二、高通滤波:边缘检测
高通滤波器最好的一个应用就是边缘检测,由文章开头分析可知高频是图像中变化剧烈的地方,所以图像的边缘区域恰好符合这一特性,我们可以利用高通滤波让图像的边缘显露出来,进一步计算图像的一些特征。
边缘检测本来打算作为一个单独的主题来写一篇文章,但是由于Canny边缘检测算法比较复杂,篇幅也较大,所以先把Sobel边缘检测在高通滤波这里作为一个实例,以后Canny边缘检测作为单独的一篇文章来写。
实际上OpenCV有提供了Sobel边缘检测的函数,但是一方面阈值好像取的不太好,另一方面没有对最后边缘作细化处理,所以效果并不太让人满意,本文是模仿Matlab中算法来写的。
下面是Sobel实现的:
bool Sobel(const Mat& image,Mat& result,int TYPE) { if(image.channels()!=1) return false; // 系数设置 int kx(0); int ky(0); if( TYPE==SOBEL_HORZ ){ kx=0;ky=1; } else if( TYPE==SOBEL_VERT ){ kx=1;ky=0; } else if( TYPE==SOBEL_BOTH ){ kx=1;ky=1; } else return false; // 设置mask float mask[3][3]={{1,2,1},{0,0,0},{-1,-2,-1}}; Mat y_mask=Mat(3,3,CV_32F,mask)/8; Mat x_mask=y_mask.t(); // 转置 // 计算x方向和y方向上的滤波 Mat sobelX,sobelY; filter2D(image,sobelX,CV_32F,x_mask); filter2D(image,sobelY,CV_32F,y_mask); sobelX=abs(sobelX); sobelY=abs(sobelY); // 梯度图 Mat gradient=kx*sobelX.mul(sobelX)+ky*sobelY.mul(sobelY); // 计算阈值 int scale=4; double cutoff=scale*mean(gradient)[0]; result.create(image.size(),image.type()); result.setTo(0); for(int i=1;i<image.rows-1;i++) { float* sbxPtr=sobelX.ptr<float>(i); float* sbyPtr=sobelY.ptr<float>(i); float* prePtr=gradient.ptr<float>(i-1