c# 联合opencv进行人脸检测

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里面自带的。

链接:

Releases - 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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值