C# 使用OpenCV在一张图片里寻找人脸
2017-10-29 23:48
183 查看
先上个效果图
相关库的下载
例程中用到一个库叫做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;
}
运行效果
编译后运行可以看到目录多了两个图片文件:打开看看:
相关文章推荐
- [人脸识别]使用VGG Face Model对一张图片进行测试
- python使用opencv将灰度图人脸图片转化为RGB
- [置顶] 使用opencv人脸识别对比两张人脸图片
- opencv学习笔记--使用opencv打开一张图片
- java使用Opencv小例子,从合并的两个图片中减去一张图片
- opengl离屏渲染(不需要和窗口绑定,仅当作一个可以渲染一张图片的API使用)+ opencv显示
- 使用opencv创建一张纯黑色的图片与其他图片进行合成
- opengl离屏渲染(不需要和窗口绑定,仅当作一个可以渲染一张图片的API使用)+ opencv显示
- Java使用OpenCV实现人脸识别/人眼检测/图片截取/合成/添加水印
- java使用Opencv小例子,从合并的两个图片中减去一张图片
- 使用一张或两张图片创建大背景网站
- 使用.net(C#)处理图片之:旋转图片任意角度
- C#中使用OpenCV等库进行图像处理
- (转) 在C#中使用WIA获取扫描仪数据(三、利用Filter处理图片)
- windows mobile平台中使用C#将byte数组转换为Format24bppRgb格式的图片
- 使用OpenCV实现WebCam摄像头保存JPEG图片
- windows mobile中使用DirectShow开发视频流之从摄像头流中捕捉一张图片
- 使用 Visual Studio 2008 和 OpenCV 在窗口显示图片或视频
- C# 绘图中的图片闪烁问题解决方法的使用结果
- 使用C#创建SQLServer的存储过程 附带图片