邊緣檢測方面現狀:
邊緣檢測是數字圖像處理識別物體重要的預處理方法,Sobel,Robert,Prewitt,Log等等算子實現方便,處理很快,但是很容易被噪聲影響。現實場景的應用噪聲都是很多的,canny算子加入了平滑濾波器對這方面問題非常有效,平滑濾波器將會直接影響 Canny 算法的結果。較小的濾波器產生的模糊效果也較少,這樣就可以檢測較小、變化明顯的細線。較大的濾波器產生的模糊效果也較多,將較大的一塊圖像區域塗成一個特定點的顏色值。Canny細節保留非常完整,但這個優點有時候卻成為識別的瓶頸,使識別目標不夠突出。
應對這些問題,我看了些相關文獻,實現了形態學的邊緣檢測方法。
常用的邊緣檢測算子:
⒈Sobel算子
2.Robert算子
3.Prewit算子
4.Laplace算子
5.Canny算子
形態學邊緣檢測方法:
實現代碼:
1 private void morphological(Image<Gray, Byte> src, float theta) 2 { 3 int[,] mask1 = {{1,2,1},{2,8,2},{1,2,1}}; 4 int[,] mask2 = {{0,1,0},{1,1,1},{0,1,0}}; 5 int[,] mask3 = {{1,0,1},{0,1,0},{1,0,1}}; 6 7 StructuringElementEx ele1 = new StructuringElementEx(mask1, 1, 1); 8 StructuringElementEx ele2 = new StructuringElementEx(mask2, 1, 1); 9 StructuringElementEx ele3 = new StructuringElementEx(mask3, 1, 1); 10 11 Image<Gray, Byte> dst1 = new Image<Gray, Byte>(src.Size); //先腐蝕再膨脹 12 Image<Gray, Byte> dst2 = new Image<Gray, Byte>(src.Size); //先膨脹再腐蝕 13 CvInvoke.cvErode(src, dst1, ele1, 1); 14 CvInvoke.cvDilate(dst1, dst1, ele2, 1); 15 CvInvoke.cvDilate(src, dst2, ele1, 1); 16 CvInvoke.cvErode(dst2, dst2, ele2, 1); 17 18 Image<Gray, Byte> G12 = new Image<Gray, byte>(src.Size); 19 Image<Gray, Byte> G22 = new Image<Gray, byte>(src.Size); 20 Image<Gray, Byte> G32 = new Image<Gray, byte>(src.Size); 21 Image<Gray, Byte> G1 = new Image<Gray, byte>(src.Size); 22 Image<Gray, Byte> G2 = new Image<Gray, byte>(src.Size); 23 Image<Gray, Byte> G3 = new Image<Gray, byte>(src.Size); 24 25 //G1 = imdilate(imdilate(imerode(f, b1), b2),b3) - imclose(imdilate(imerode(f, b1), b2), b3); 26 CvInvoke.cvDilate(dst1, G1, ele3, 1); 27 CvInvoke.cvMorphologyEx(dst1, G12,new IntPtr(), ele3, Emgu.CV.CvEnum.CV_MORPH_OP.CV_MOP_CLOSE, 1); 28 G1 = G1 - G12; 29 30 //G2 = imopen(imerode(imdilate(f, b1), b2),b3) - imerode(imerode(imdilate(f, b1), b2),b3); 31 CvInvoke.cvMorphologyEx(dst2, G2, new IntPtr(), ele3, Emgu.CV.CvEnum.CV_MORPH_OP.CV_MOP_OPEN, 1); 32 CvInvoke.cvErode(dst2, G22, ele3, 1); 33 G2 = G2 - G22; 34 35 //G3 = imdilate(imdilate(imerode(f, b1), b2),b3) - imerode(imerode(imdilate(f, b1), b2),b3); 36 CvInvoke.cvDilate(dst1, G3, ele3, 1); 37 CvInvoke.cvErode(dst2, G32, ele3, 1); 38 G3 = G3 - G32; 39 //matsub(G3, G32, G3); 40 41 // Gmin = min(G1, G2); 42 // Gmax = max(G1, G2); 43 Image<Gray, Byte> Gmin = new Image<Gray, byte>(src.Size); 44 Image<Gray, Byte> Gmax = new Image<Gray, byte>(src.Size); 45 Gmin = G1.Min(G2); 46 Gmax = G1.Max(G2); 47 /* 48 int row = 0,col = 0; 49 for (; row < Gmin.Rows; row++) 50 { 51 for (; col < Gmin.Cols; col++) 52 { 53 Gmin.Data[row, col, 0] = Math.Min(G1.Data[row, col, 0], G2.Data[row, col, 0]); 54 Gmax.Data[row, col, 0] = Math.Max(G1.Data[row, col, 0], G2.Data[row, col, 0]); 55 } 56 }*/ 57 58 Gmax = Gmax - Gmin; 59 //matsub(Gmax, Gmin, Gmax); 60 // G = G3 + theta*deltaG; 61 src = G3 + theta * Gmax; 62 /* 63 for (row = 0; row < src.Rows; row++) 64 { 65 for (col = 0; col < src.Cols; col++) 66 { 67 src.Data[row, col, 0] = (byte)(G3.Data[row, col, 0] + theta * Gmax.Data[row, col, 0]); 68 } 69 } 70 imageBox1.Image = src;*/ 71 72 }
實現效果:
形態學邊緣檢測
附上參考的論文:http://pan.baidu.com/s/1sjQnGaL