c# OpenCvSharp Dlib人脸检测

c# OpenCvSharp Dlib人脸检测

由于高版本19.21的DlibDotNet也存在BitmapExtensions,与DlibDotNet.Extensions.BitmapExtensions存在冲突。因此本案例采用 19.18的DlibDotNet、DlibDotNet.Extensions。

 

需要将shape_predictor_5_face_landmarks.dat或者shape_predictor_68_face_landmarks.dat放在程序face_data目录下。

using OpenCvSharp;
using OpenCvSharp.Extensions;
using DlibDotNet;
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;

namespace app
{
    public partial class FrmMain : Form
    {
        public FrmMain()
        {
            InitializeComponent();
        }


        /// <summary>
        /// 进行人脸识别
        /// </summary>
        /// <param name="image">图像</param>
        /// <param name="numOfFaceDetected"> 识别到的人脸数目</param>
        /// <returns></returns>
        public Bitmap FaceDetectionFromImage(Bitmap image, out int numOfFaceDetected)
        {
            // 人脸数据文件路径名称属性
            // 默认文件路径
            string faceDataPath = @"face_data\shape_predictor_68_face_landmarks.dat";

            numOfFaceDetected = 0;
            if (image != null)
            {
                // 图像转换到Dlib的图像类中
                Array2D<RgbPixel> img = DlibDotNet.Extensions.BitmapExtensions.ToArray2D<RgbPixel>(image);

                using (var faceDetector = Dlib.GetFrontalFaceDetector())
                using (var shapePredictor = ShapePredictor.Deserialize(faceDataPath))
                {

                    // 检测人脸
                    var faces = faceDetector.Operator(img);

                    // 遍历检测到的人脸区域
                    foreach (var rect in faces)
                    {
                        // 绘制脸部区域
                        Dlib.DrawRectangle(img, rect, new RgbPixel { Red = 255 }, 3);

                        /*
                        // 人脸区域中识别脸部特征
                        var shape = shapePredictor.Detect(img, rect);
                        // 简单绘制识别到的特征(用线连起来)
                        for (uint i = 1; i < shape.Parts; i++)
                        {
                            Dlib.DrawLine(img, shape.GetPart(i), shape.GetPart(i - 1), new RgbPixel { Red = 255 });
                        }
                        */
                    }
                    numOfFaceDetected = faces.Length;
                }
                return DlibDotNet.Extensions.BitmapExtensions.ToBitmap<RgbPixel>(img);
            }
            return image;
        }

        /// <summary>
        /// 打开摄像头
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnOpenVideo_Click(object sender, EventArgs e)
        {
            // 定义图像捕捉方式 从摄像头 , 注意 Windows下需要选择 VideoCaptureAPIs.DSHOW
            var capture = new VideoCapture(0, VideoCaptureAPIs.DSHOW);

            if (!capture.IsOpened())
                return;

            capture.XI_OffsetX = 0; // 以左上角为起点 坐标X
            capture.XI_OffsetY = 0; // 以左上角为起点 坐标Y
            capture.FrameWidth = 640; // 宽
            capture.FrameHeight = 480; // 高
            capture.AutoFocus = true;

            const int sleepTime = 10;

            //var window = new Window("cv");

            // Mat作为图像的存储容器
            var image = new Mat();

            while (true)
            {
                capture.Read(image);

                if (image.Empty())
                    break;

                // 显示
                //window.ShowImage(image);

                // Windows窗体PictureBox加载
                //picboxDest.Image = image.ToBitmap();

                int numFaces = 0;
                //Bitmap img = image.ToBitmap();
                picboxDest.Image = FaceDetectionFromImage(image.ToBitmap(), out numFaces);

                /*
                int flag = Cv2.WaitKey(sleepTime);

                if (flag >= 0)
                {
                    break;
                }
                */

                // 可以防止界面停止响应
                Application.DoEvents();
            }
        }

    }
}

 

 

6条评论

  1. 你好,最近一直在看您写的博客,受益匪浅。现在我有个需求,是在图片中识别印章,印章可能是圆形、正方形、长方形、三角形,我的思路是识别红色区域,再识别红色区域内的字,请问您有什么好的建议吗

    孙福玉
  2. 第一种思路:
    1、先分离红色区域。
    2、分割处理红色区域里面的文字。
    3、文字匹配、识别。
    如果从零开始写,识别的准确率还是偏低的。可以找一些成熟的ocr识别库,减少调试的工作量。

    第二种思路:
    1、如果印章是固定内容的。可以用模板匹配的思路。

    第三种思路:
    1、训练模型。通过模型来识别印章。

    蒋智昊

发表回复

您的电子邮箱地址不会被公开。