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的接口,这个不如直接使用指针的效率高,可以修改。