zoukankan      html  css  js  c++  java
  • C# 使用OpenCV在一张图片里寻找人脸

    先上个效果图

    相关库的下载

    例程中用到一个库叫做emgucv,是opencv的net封装
    编译打包好的稳定版,在这:https://sourceforge.net/projects/emgucv/files/emgucv/
    如果要最新代码,在这里获取:https://github.com/emgucv/emgucv

    建立工程

    首先建立一个C#控制台工程.添加引用:Emgu.CV.World.dll
    然后添加这2个文件到工程(在emgucv的压缩包里有的,搜索下文件吧~):
    注意:其中的dll文件需要根据要编译的程序是32位还是64位选不同文件

    记得把"复制到输出目录"设为"较新则复制"
    另外准备一张要识别的图片,放到编译输出目录.
    接下来就是编辑代码了,后面所有代码都在main里

    配置OpenCV使用显卡运算(如果支持的话)

    使用显卡处理图像数据效率会很多,如果你的设备支持,最好打开,使用CvInvoke.HaveOpenCLCompatibleGpuDevice能返回是否支持.
    配置CvInvoke.UseOpenCL能让OpenCV 启用或者停用 GPU运算

    CvInvoke.UseOpenCL = CvInvoke.HaveOpenCLCompatibleGpuDevice;
    

    构建级联分类器对象

    emgu包里已经有训练好的数据了,文件名叫做"haarcascade_frontalface_alt.xml",就是上面添加的文件之一

    var face = new CascadeClassifier("haarcascade_frontalface_alt.xml");
    

    加载图像并作简单处理

    在OpenCV中,大部分函数是处理灰度图的,包括这个识别物体,所以需要转成灰度图,然后再调整下亮度

    //加载要识别的图片
    var img = new Image<Bgr, byte>("0.png");
    var img2 = new Image<Gray, byte>(img.ToBitmap());
    //把图片从彩色转灰度
    CvInvoke.CvtColor(img, img2, Emgu.CV.CvEnum.ColorConversion.Bgr2Gray);
    //亮度增强
    CvInvoke.EqualizeHist(img2, img2);
    

    检测人脸

    其实这一步反而最简单,返回的是rectangle[]格式,因为图中可能有多个人脸,所以返回的是数组.

    //在这一步就已经识别出来了,返回的是人脸所在的位置和大小
    var facesDetected = face.DetectMultiScale(img2, 1.1, 10, new Size(50, 50));
    

    剪切并保存

    因为是多个人脸所以需要循环剪切并保存,(→_→)这一块的代码量竟然反而比上面那堆多

    //循环把人脸部分切出来并保存
    int count = 0;
    var b = img.ToBitmap();
    foreach (var item in facesDetected)
    {
    	count++;
    	var bmpOut = new Bitmap(item.Width, item.Height, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
    	var g = Graphics.FromImage(bmpOut);
    	g.DrawImage(b, new Rectangle(0, 0, item.Width, item.Height), new Rectangle(item.X, item.Y, item.Width, item.Height), GraphicsUnit.Pixel);
    	g.Dispose();
    	bmpOut.Save($"{count}.png", System.Drawing.Imaging.ImageFormat.Png);
    	bmpOut.Dispose();
    }
    

    释放资源退出

    //释放资源退出
    b.Dispose();
    img.Dispose();
    img2.Dispose();
    face.Dispose();
    

    全代码和测试图片:

    static void Main(string[] args)
    {
    	//如果支持用显卡,则用显卡运算
    	CvInvoke.UseOpenCL = CvInvoke.HaveOpenCLCompatibleGpuDevice;
    
    	//构建级联分类器,利用已经训练好的数据,识别人脸
    	var face = new CascadeClassifier("haarcascade_frontalface_alt.xml");
    
    	//加载要识别的图片
    	var img = new Image<Bgr, byte>("0.png");
    	var img2 = new Image<Gray, byte>(img.ToBitmap());
    
    	//把图片从彩色转灰度
    	CvInvoke.CvtColor(img, img2, Emgu.CV.CvEnum.ColorConversion.Bgr2Gray);
    
    	//亮度增强
    	CvInvoke.EqualizeHist(img2, img2);
    
    	//在这一步就已经识别出来了,返回的是人脸所在的位置和大小
    	var facesDetected = face.DetectMultiScale(img2, 1.1, 10, new Size(50, 50));
    
    	//循环把人脸部分切出来并保存
    	int count = 0;
    	var b = img.ToBitmap();
    	foreach (var item in facesDetected)
    	{
    		count++;
    		var bmpOut = new Bitmap(item.Width, item.Height, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
    		var g = Graphics.FromImage(bmpOut);
    		g.DrawImage(b, new Rectangle(0, 0, item.Width, item.Height), new Rectangle(item.X, item.Y, item.Width, item.Height), GraphicsUnit.Pixel);
    		g.Dispose();
    		bmpOut.Save($"{count}.png", System.Drawing.Imaging.ImageFormat.Png);
    		bmpOut.Dispose();
    	}
    
    	//释放资源退出
    	b.Dispose();
    	img.Dispose();
    	img2.Dispose();
    	face.Dispose();
    
    	return;
    
    }
    

    运行效果

    编译后运行可以看到目录多了两个图片文件:

    打开看看:

  • 相关阅读:
    ADO.NET 根据实体类自动生成添加修改语句仅限Oracle使用
    C# 实体对象作为参数统一去除空格
    jQuery 前端复选框 全选 反选 下拉菜单联动
    C# 后台服务器端 Get 请求函数封装
    服务器404错误页面
    vue 封装公用函数
    Vue 生命周期
    Oracle 查看表结构
    ubuntu源配置
    外观(Facade)模式
  • 原文地址:https://www.cnblogs.com/DragonStart/p/7751993.html
Copyright © 2011-2022 走看看