例程中用到一個庫叫作emgucv,是opencv\的net封裝
編譯打包好的穩定版,在這:https://sourceforge.net/projects/emgucv/files/emgucv/
若是要最新代碼,在這裏獲取:https://github.com/emgucv/emgucvgit
首先創建一個C#控制檯工程.添加引用:Emgu.CV.World.dll
而後添加這2個文件到工程(在emgucv的壓縮包裏有的,搜索下文件吧~):
注意:其中的dll文件須要根據要編譯的程序是32位仍是64位選不一樣文件
記得把"複製到輸出目錄"設爲"較新則複製"
另外準備一張要識別的圖片,放到編譯輸出目錄.
接下來就是編輯代碼了,後面全部代碼都在main裏github
使用顯卡處理圖像數據效率會不少,若是你的設備支持,最好打開,使用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[]格式,由於圖中可能有多我的臉,因此返回的是數組..net
//在這一步就已經識別出來了,返回的是人臉所在的位置和大小 var facesDetected = face.DetectMultiScale(img2, 1.1, 10, new Size(50, 50));
由於是多我的臉因此須要循環剪切並保存,(→_→)這一塊的代碼量居然反而比上面那堆多3d
//循環把人臉部分切出來並保存 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; }
編譯後運行能夠看到目錄多了兩個圖片文件:
打開看看:
code