例程中用到一个库叫做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里
使用显卡处理图像数据效率会很多,如果你的设备支持,最好打开,使用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;
- }
编译后运行可以看到目录多了两个图片文件:
打开看看:
来源: http://www.cnblogs.com/DragonStart/p/7751993.html