1.环境配置
创建 c# winform 新项目cv_face
打开NUGET
搜索OpenCvSharp
安装 这三个:
调用
using OpenCvSharp;
using OpenCvSharp.Extensions;
就可以使用啦
2、OpenCvSharp
2.1 读取图片 ,显示图片
c#界面上添加一个pictureBox1和button_start
opencv 的图片格式为 Mat img = new Mat();
读取图片
Mat img = Cv2.ImRead(...)
在picturebox中显示:
pictureBox1.Image = BitmapConverter.ToBitmap(img);
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using OpenCvSharp;
using OpenCvSharp.Extensions;
namespace cv_face
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button_start_Click(object sender, EventArgs e)
{
Mat img = Cv2.ImRead("C:\\Users\\86957\\Desktop\\test_vm2_1.bmp");
OpenCvSharp.Size resizeSize = new OpenCvSharp.Size(pictureBox1.Width, pictureBox1.Height);//获取picturebox的尺寸
Cv2.Resize(img, img, resizeSize);
pictureBox1.Image = BitmapConverter.ToBitmap(img);
}
}
}
2.2打开摄像头
private VideoCapture camera;
camera = new VideoCapture(0);
打开并显示:
private void start_camera()
{
camera = new VideoCapture(0); // 打开默认摄像头
Mat frame = new Mat();
while (true) {
camera.Read(frame);
Bitmap bitmap = BitmapConverter.ToBitmap(frame);
pictureBox1.Image = bitmap;
}
}
运行后卡死, 因为操作pictureBox1需要回到ui线程。
所以需要用Task.Run(() =>打开线程
使用
this.BeginInvoke(new Action(() => {
pictureBox1.Image = bitmap;
}));
回线程。
或者pictureBox1.Invoke((MethodInvoker)delegate回线程
(MethodInvoker)delegate
是一个匿名方法,表示要在 UI 线程上执行的代码。
通过 Invoke
,这段代码会被排队到 UI 线程的消息循环中执行。
(c# 线程的基础教学(winform 电梯模拟)-CSDN博客)
代码:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using OpenCvSharp;
using OpenCvSharp.Extensions;
namespace cv_face
{
public partial class Form1 : Form
{
private VideoCapture camera;
public Form1()
{
InitializeComponent();
}
private void button_start_Click(object sender, EventArgs e)
{
start_camera();
}
private void start_camera()
{
camera = new VideoCapture(0); // 打开默认摄像头
Task.Run(() =>
{
Mat frame = new Mat();
while (true)
{
camera.Read(frame);
Bitmap bitmap = BitmapConverter.ToBitmap(frame);
//法二
pictureBox1.Invoke((MethodInvoker)delegate
{
pictureBox1.Image = bitmap;
});
//法一
/*
this.BeginInvoke(new Action(() => {
pictureBox1.Image = bitmap;
}));*/
}
});
}
}
}
运行后:
3.人脸检测
opencv 内置了人脸检测功能,使用起来非常简单。
使用opencvsharp.CascadeClassifier
代码如下:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using OpenCvSharp;
using OpenCvSharp.Extensions;
namespace cv_face
{
public partial class Form1 : Form
{
private VideoCapture camera;
public Form1()
{
InitializeComponent();
}
private void button_start_Click(object sender, EventArgs e)
{
start_camera();
}
private void start_camera()
{
camera = new VideoCapture(0); // 打开默认摄像头
Task.Run(() =>
{
Mat frame = new Mat();
Mat grayFrame = new Mat();
Rect[] faces;
// 加载预训练的人脸检测模型(Haar 级联分类器)
string faceCascadePath = "D:\\opencv\\opencv\\build\\etc\\haarcascades\\haarcascade_frontalface_alt.xml"; // 确保文件存在
var faceCascade = new CascadeClassifier(faceCascadePath);
while (true)
{
camera.Read(frame);
// 转换为灰度图
Cv2.CvtColor(frame, grayFrame, ColorConversionCodes.BGR2GRAY);
// 检测人脸
faces = faceCascade.DetectMultiScale(
grayFrame,
scaleFactor: 1.1, // 图像缩放比例
minNeighbors: 5, // 检测结果的邻域数量(减少误检)
minSize: new OpenCvSharp.Size(30, 30) // 最小人脸尺寸
);
// 在检测到的人脸周围画矩形
foreach (var face in faces)
{
Cv2.Rectangle(frame, face, Scalar.Red, 2);
}
// 显示结果
Bitmap bitmap = BitmapConverter.ToBitmap(frame);
//法二
pictureBox1.Invoke((MethodInvoker)delegate
{
pictureBox1.Image = bitmap;
});
//法一
/*
this.BeginInvoke(new Action(() => {
pictureBox1.Image = bitmap;
}));*/
}
});
}
}
}
其中,
"D:\\opencv\\opencv\\build\\etc\\haarcascades\\haarcascade_frontalface_alt.xml"
官网下载的opencv里面自带的。
链接:
or
通过网盘分享的文件:haarcascade_frontalface_alt.xml
链接: https://pan.baidu.com/s/1WMGnIi1fUuQVeIA5kKjvFg
提取码: 2xt6
====================================
上面是框选人脸
如果想遮挡。
代码如下:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using OpenCvSharp;
using OpenCvSharp.Extensions;
namespace cv_face
{
public partial class Form1 : Form
{
private VideoCapture camera;
private Mat faceMask; // 存储人脸遮罩图片
public Form1()
{
InitializeComponent();
LoadFaceMask(); // 初始化时加载遮罩图片
}
private void LoadFaceMask()
{
string maskPath = "mask.png"; // 替换为您的图片路径
if (System.IO.File.Exists(maskPath))
{
faceMask = Cv2.ImRead(maskPath, ImreadModes.Color);
if (faceMask.Empty())
{
MessageBox.Show("遮罩图片加载失败!");
}
}
else
{
MessageBox.Show("遮罩图片不存在!");
}
}
private void button_start_Click(object sender, EventArgs e)
{
start_camera();
}
private void start_camera()
{
/*
camera = new VideoCapture(0); // 打开默认摄像头
Task.Run(() =>
{
Mat frame = new Mat();
Mat grayFrame = new Mat();
Rect[] faces;
// 加载预训练的人脸检测模型(Haar 级联分类器)
string faceCascadePath = "D:\\opencv\\opencv\\build\\etc\\haarcascades\\haarcascade_frontalface_alt.xml"; // 确保文件存在
var faceCascade = new CascadeClassifier(faceCascadePath);
while (true)
{
camera.Read(frame);
// 转换为灰度图
Cv2.CvtColor(frame, grayFrame, ColorConversionCodes.BGR2GRAY);
// 检测人脸
faces = faceCascade.DetectMultiScale(
grayFrame,
scaleFactor: 1.1, // 图像缩放比例
minNeighbors: 5, // 检测结果的邻域数量(减少误检)
minSize: new OpenCvSharp.Size(30, 30) // 最小人脸尺寸
);
// 在检测到的人脸周围画矩形
foreach (var face in faces)
{
Cv2.Rectangle(frame, face, Scalar.Red, 2);
}
// 显示结果
Bitmap bitmap = BitmapConverter.ToBitmap(frame);
pictureBox1.Invoke((MethodInvoker)delegate
{
pictureBox1.Image = bitmap;
});
}
});
*/
camera = new VideoCapture(0);
Task.Run(() =>
{
Mat frame = new Mat();
Mat grayFrame = new Mat();
Rect[] faces;
// 加载人脸检测模型
string faceCascadePath = "D:\\opencv\\opencv\\build\\etc\\haarcascades\\haarcascade_frontalface_alt.xml";
var faceCascade = new CascadeClassifier(faceCascadePath);
while (true)
{
if (camera.Read(frame))
{
// 转换为灰度图
Cv2.CvtColor(frame, grayFrame, ColorConversionCodes.BGR2GRAY);
// 检测人脸
faces = faceCascade.DetectMultiScale(
grayFrame,
scaleFactor: 1.1,
minNeighbors: 5,
minSize: new OpenCvSharp.Size(30, 30)
);
// 用本地图片遮住人脸
if (faceMask !=null)
{
foreach (var face in faces)
{
// 调整遮罩图片大小以匹配人脸区域
Mat resizedMask = new Mat();
Cv2.Resize(faceMask, resizedMask, new OpenCvSharp.Size(face.Width, face.Height));
// 将遮罩图片覆盖到人脸区域
Mat roi = new Mat(frame, face); // 人脸区域的ROI
resizedMask.CopyTo(roi); // 覆盖
}
}
// 显示结果
Bitmap bitmap = BitmapConverter.ToBitmap(frame);
this.BeginInvoke(new Action(() =>
{
pictureBox1.Image?.Dispose(); // 释放旧图像
pictureBox1.Image = bitmap; // 显示新图像
}));
}
}
});
}
}
}
4. 项目源码
通过网盘分享的文件:cv_face
链接: https://pan.baidu.com/s/1tD_YPr4p9L6bOYL7F8DxOQ
提取码: 5gbw