標籤:
---恢複內容開始---
最近沒什麼事,公司領導希望我們瞭解影像處理,所以學習了以下!由於我不太會C++,只能試著用C#編寫代碼!但是網上關於emgu cv的資料少之又少,而且很多還是英文的,而且講的不詳細。所以慢慢琢磨。寫了個c#定位車牌的代碼,不過效果不是很理想。參考了c++高手的代碼!
思路就是1.灰階化,豎向邊緣檢測
2.自適應二值化處理
3.形態學處理(膨脹和腐蝕)
4.輪廓尋找與篩選
代碼如下:
Image<Bgr, Byte> simage = img; //new Image<Bgr, byte>("license-plate.jpg"); //Image<Bgr, Byte> simage = sizeimage.Resize(400, 300, Emgu.CV.CvEnum.INTER.CV_INTER_NN); Image<Gray, Byte> GrayImg = new Image<Gray, Byte>(simage.Width, simage.Height); IntPtr GrayImg1 = CvInvoke.cvCreateImage(simage.Size, Emgu.CV.CvEnum.IPL_DEPTH.IPL_DEPTH_8U, 1); //灰階化 CvInvoke.cvCvtColor(simage.Ptr, GrayImg1, Emgu.CV.CvEnum.COLOR_CONVERSION.BGR2GRAY); //首先建立一張16深度有符號的映像地區 IntPtr Sobel = CvInvoke.cvCreateImage(simage.Size, Emgu.CV.CvEnum.IPL_DEPTH.IPL_DEPTH_16S, 1); //X方向的Sobel運算元檢測 CvInvoke.cvSobel(GrayImg1, Sobel, 2, 0, 3); IntPtr temp = CvInvoke.cvCreateImage(simage.Size, Emgu.CV.CvEnum.IPL_DEPTH.IPL_DEPTH_8U, 1); CvInvoke.cvConvertScale(Sobel, temp, 0.00390625, 0); ////int it = ComputeThresholdValue(GrayImg.ToBitmap()); ////二值化處理 ////Image<Gray, Byte> dest = GrayImg.ThresholdBinary(new Gray(it), new Gray(255)); Image<Gray, Byte> dest = new Image<Gray, Byte>(simage.Width, simage.Height); //二值化處理 CvInvoke.cvThreshold(temp, dest, 0, 255, Emgu.CV.CvEnum.THRESH.CV_THRESH_OTSU); IntPtr temp1 = CvInvoke.cvCreateImage(simage.Size, Emgu.CV.CvEnum.IPL_DEPTH.IPL_DEPTH_8U, 1); Image<Gray, Byte> dest1 = new Image<Gray, Byte>(simage.Width, simage.Height); CvInvoke.cvCreateStructuringElementEx(3, 1, 1, 0, Emgu.CV.CvEnum.CV_ELEMENT_SHAPE.CV_SHAPE_RECT, temp1); CvInvoke.cvDilate(dest, dest1, temp1, 6); CvInvoke.cvErode(dest1, dest1, temp1, 7); CvInvoke.cvDilate(dest1, dest1, temp1, 1); CvInvoke.cvCreateStructuringElementEx(1, 3, 0, 1, Emgu.CV.CvEnum.CV_ELEMENT_SHAPE.CV_SHAPE_RECT, temp1); CvInvoke.cvErode(dest1, dest1, temp1, 2); CvInvoke.cvDilate(dest1, dest1, temp1, 2); IntPtr dst = CvInvoke.cvCreateImage(simage.Size, Emgu.CV.CvEnum.IPL_DEPTH.IPL_DEPTH_8U, 3); CvInvoke.cvZero(dst); //dest.Dilate(10); //dest.Erode(5); using (MemStorage stor = new MemStorage()) { Contour<Point> contours = dest1.FindContours( Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE, Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_CCOMP, stor); for (; contours != null; contours = contours.HNext) { Rectangle box = contours.BoundingRectangle; Image<Bgr, Byte> test = simage.CopyBlank(); test.SetValue(255.0); double whRatio = (double)box.Width / box.Height; int area = (int)box.Width * box.Height; if (area > 1000 && area<10000) { if ((3.0 < whRatio && whRatio < 6.0)) { test.Draw(box, new Bgr(Color.Red), 2); simage.Draw(box, new Bgr(Color.Red), 2); CvInvoke.cvRectangle(simage, new Point(box.X, box.Y), new Point(box.X + box.Width, box.Y + box.Height), new MCvScalar(255, 0, 0), 1, Emgu.CV.CvEnum.LINE_TYPE.EIGHT_CONNECTED, 0); //CvInvoke.cvNamedWindow("dst"); //CvInvoke.cvShowImage("dst", dst); imageBox1.Image = simage; } } } }
還是有一些細節沒處理好啊
C# open cv即emgu cv 定位車牌思路及代碼