今天看Harris的源码时,发现Sobel函数的参数scale=1的默认值被改了,主要目的是为了通过减小尺度,来提高平滑处理的速度。下文调用了sobel函数,来看看究竟scale这个参数对输出有什么影响。
首先,简单介绍下sobel函数,如下:
void Sobel(inputArray,outputArray,int ddepth,int dx,int dy,int ksize=3,double scale=1,double delta=0,int borderType=BORDER_DEFAULT)
*第一个参数,输入图像。
*第二个参数,输出图像。
*第三个参数,输出图像深度。
*第四个参数,x方向上的差分阶数。
*第五个参数,y方向上的差分阶数。
*第六个参数,Sobel核的大小,默认值为3,必须为1、3、5、7。当为1时,往往使用3x1、1x3的内核,这种情况下,没有进行高斯平滑操作。
*第七个参数,计算导数值时可选的缩放因子,默认值1,表示默认情况下没用应用缩放。
*第八个参数,表示在结果存入输出图像之前可选的delta值,默认值0。
*第九个参数,边界模式。
补充说明:
(1)当内核大小为3时,Sobel内核可能产生比较明显的误差,为了解决这一问题,Opencv提供了Scharr函数,但该函数仅作用于大小为3的内核,该函数的运算与Sobel函数一样快,但结果却更加精确。
(2)因为Sobel算子结合了高斯平滑和分化,因此结果会具有更多的抗噪性。
#include
#include
#include
#include
//-----------------------------------【命名空间声明部分】---------------------------------------
// 描述:包含程序所使用的命名空间
//-----------------------------------------------------------------------------------------------
using namespace cv;
using namespace std;
//-----------------------------------【main( )函数】--------------------------------------------
// 描述:控制台应用程序的入口函数,我们的程序从这里开始
//-----------------------------------------------------------------------------------------------
int main()
{
//【0】创建 grad_x 和 grad_y 矩阵
Mat grad_x, grad_x2, grad_x3;
Mat abs_grad_x, abs_grad_x2, abs_grad_x3;
//【1】载入原始图
Mat src = imread("1.jpg"); //工程目录下应该有一张名为1.jpg的素材图
//【2】显示原始图
imshow("【原始图】sobel边缘检测", src);
double t = (double)getTickCount();//开始时间
//【3】求 X方向梯度
Sobel(src, grad_x, CV_16S, 1, 0, 3, 1, 1, BORDER_DEFAULT);
t = (double)getTickCount() - t; //代码运行时间=结束时间-开始时间
convertScaleAbs(grad_x, abs_grad_x);
imshow("【效果图】 X方向Sobel", abs_grad_x);
double t2 = (double)getTickCount();//开始时间
//【3】求 X2方向梯度
Sobel(src, grad_x2, CV_16S, 1, 0, 3, 0.5, 1, BORDER_DEFAULT);
t2 = (double)getTickCount() - t2; //代码运行时间=结束时间-开始时间
convertScaleAbs(grad_x2, abs_grad_x2);
imshow("【效果图】 X2方向Sobel", abs_grad_x2);
double t3 = (double)getTickCount();//开始时间
//【4】求x3方向梯度
Sobel(src, grad_x3, CV_16S, 1, 0 3, 0.2, 1, BORDER_DEFAULT);
t3 = (double)getTickCount() - t3; //代码运行时间=结束时间-开始时间
convertScaleAbs(grad_x3, abs_grad_x3);
imshow("【效果图】x3方向Sobel", abs_grad_x3);
cout<< "scale=1时的用时为:" << t*1000. / getTickFrequency() << "毫秒" << endl;
cout << "scale=0.5时的用时为:" << t2*1000. / getTickFrequency() << "毫秒" << endl;
cout << "scale=0.2时的用时为:" << t3*1000. / getTickFrequency() << "毫秒" << endl;
waitKey(0);
return 0;
}
输出如下:
原图
scale=1时:
scale=0.5时:
scale=0.2时:
可见,随着scale越来越小,输出图像越来越暗,但是用时没有随着尺度的减小而减小,不知道是为什么。知道的同行还望留言讲解一下。