圖像處理中的卷積運算一般都用來平滑圖像、尖銳圖像求邊緣等等。主要看你選擇什么樣的核函數了。現在核函數很多,比如高斯平滑核函數,sobel核函數,canny核函數等等。這里舉一個sobel核函數的例子來求圖像的梯度。
Sobel自動求邊緣圖(梯度圖)在opencv里有特定的函數,具體參照opencv文檔(需要自己設定閾值)。這里主要講怎么用已知的sobel算子(核函數)去平滑當前圖像。
C++:void filter2D(InputArraysrc, OutputArray dst, int ddepth, InputArray kernel, Point anchor=Point(-1,-1), doubledelta=0,intborderType=BORDER_DEFAULT)
這里要注意的是kerne,寫的是單通道浮點型矩陣。
Sobel核函數:
 
按圖一為例,kernel內核為:
Mat kernelY=Mat::zeros(3,3,CV_32FC1);
kernelY.at<float>(0,0)=1;
kernelY.at<float>(0,1)=2;
kernelY.at<float>(0,2)=1;
kernelY.at<float>(1,0)=0;
kernelY.at<float>(1,1)=0;
kernelY.at<float>(1,2)=0;
kernelY.at<float>(2,0)=-1;
kernelY.at<float>(2,1)=-2;
kernelY.at<float>(2,2)=-1;
注意類型。我一開始寫成CV_8U和uchar類型,filter2D卷積后就全是白色的。。
然后就直接調用函數:
filter2D(src,sobelY,-1,kernelY,Point(-1,-1),0.0,BORDER_DEFAULT);
sobel函數是x,y方向的卷積的疊加,即:
 
Sx和sy是兩種內核卷積后的圖像矩陣。M是最后的sobel梯度圖。
如果要直接用sobel函數,可以寫成:
Sobel(src,edge1,-1,1,0,3,1.0,0.0,4);//兩個方向
Sobel(src,edge2,-1,0,1,3,1.0,0.0,4);
edge=abs(edge1)+abs(edge2); //也可以采用標准的平方根形式疊加
兩種方式最后得出的邊緣圖比較類似,個人感覺filter直接平滑的噪聲更少。當然也可以認為檢測出的'邊緣點'(噪聲點)個更少
 
(sobel) (filter)
