Sobel算子主要用來做圖像邊緣檢測。在OpenCV中有現成的接口可以調用,即:cvSobel。
今天遇到一個問題是需要一個類似Sobel算子的功能,因為Sobel算子沒有考慮到像素點周圍的相似性,現在需要考慮這個問題。所以需要的算子的元素與Sobel算子不同。于是自己動手寫了sobel算子的實現,這樣對于不同的參數修改算子的元素值即可。代碼如下:
1 void MySobel(IplImage* gray, IplImage* gradient)
2 {
3 /* Sobel template
4 a00 a01 a02
5 a10 a11 a12
6 a20 a21 a22
7 */
8
9 unsigned char a00, a01, a02, a20, a21, a22;
10 unsigned char a10, a11, a12;
11
12 for (int i=1; i<gray->height-1; ++i)
13 {
14 for (int j=1; j<gray->width-1; ++j)
15 {
16 CvScalar color = cvGet2D(gray, i, j);
17
18 a00 = cvGet2D(gray, i-1, j-1).val[0];
19 a01 = cvGet2D(gray, i-1, j).val[0];
20 a02 = cvGet2D(gray, i-1, j+1).val[0];
21
22 a10 = cvGet2D(gray, i, j-1).val[0];
23 a11 = cvGet2D(gray, i, j).val[0];
24 a12 = cvGet2D(gray, i, j+1).val[0];
25
26 a20 = cvGet2D(gray, i+1, j-1).val[0];
27 a21 = cvGet2D(gray, i+1, j).val[0];
28 a22 = cvGet2D(gray, i+1, j+1).val[0];
29
30 // x方向上的近似導數
31 double ux = a20 * (1) + a21 * (2) + a22 * (1)
32 + (a00 * (-1) + a01 * (-2) + a02 * (-1));
33
34 // y方向上的近似導數
35 double uy = a02 * (1) + a12 * (2) + a22 * (1)
36 + a00 * (-1) + a10 * (-2) + a20 * (-1);
37
38 color.val[0] = ux;
39
40 cvSet2D(gradient, i, j, color);
41 }
42 }
43 }
上面代碼中訪問圖像的像素使用了OpenCV的接口,這個不如直接使用指針的效率高,可以修改。