本次实验使用了两种方法进行了边缘检测,分别使用到了opencv中的两个API函数为Canny()和Sobel()函数。实验后加了Scharr滤波器,它其实是基于Sobel()函数的。
这三个API中的参数可进行调整,实验中也可动态调整参数值来达到不同的检测效果。
#include#include using namespace cv;//全局变量的定义Mat src, gray, dst;//Canny边缘检测相关变量Mat canny;int CannyLowThreshold = 1; //滑动条位置参数//Sobel边缘检测相关变量Mat SobelGradient_X, SobelGradient_Y;Mat SobelAbsGradient_X, SobelAbsGradient_Y;int SobelKernelSize = 1; //滑动条位置参数//Scharr滤波器相关变量Mat ScharrGradient_X, ScharrGradient_Y;Mat ScharrAbsGradient_X, ScharrAbsGradient_Y;//全局函数的声明static void on_canny(int,void*); //canny边缘检测窗口滑动条回调函数static void on_sobel(int,void*);//sobel边缘检测窗口滑动条回调函数void Scharr();int main(int argc,char **argv){ system("color 2F"); src = imread("D:/meinv.jpg"); //载入原图 namedWindow("原图", CV_WINDOW_AUTOSIZE); imshow("原图", src); dst.create(src.size(), src.type()); //创建与src同类型和大小的矩阵 cvtColor(src, gray, COLOR_BGR2GRAY);//转化为灰度图像 namedWindow("Canny边缘检测", CV_WINDOW_AUTOSIZE); namedWindow("Sobel边缘检测", CV_WINDOW_AUTOSIZE); //创建滑动条 createTrackbar("参数值: ", "Canny边缘检测", &CannyLowThreshold, 120, on_canny); createTrackbar("参数值: ", "Sobel边缘检测", &SobelKernelSize, 3, on_sobel); //调用滑动条函数 on_canny(0, 0); on_sobel(0, 0); //调用封装了Scharr边缘检测代码函数 Scharr(); while ((char(waitKey(1))!= 'q')) { } return 0;}void on_canny(int, void*){ blur(gray,canny,Size(3, 3)); //先使用3*3内核来降噪 Canny(canny, canny, CannyLowThreshold, CannyLowThreshold * 3, 3); //Canny算子 dst = Scalar::all(0); //将dst内的所有元素设置为0 src.copyTo(dst,canny); //使用canny算子输出的边缘图作为掩码,来将原图拷贝到目标图中 imshow("Canny边缘检测", dst); imwrite("D:/learn-opencv/canny.jpg", dst);}void on_sobel(int, void*){ //求X方向的梯度 Sobel(src, SobelGradient_X, CV_16S, 1, 0, (2 * SobelKernelSize + 1), 1, 1, BORDER_DEFAULT); convertScaleAbs(SobelGradient_X, SobelAbsGradient_X); //计算绝对值 //求Y方向的梯度 Sobel(src, SobelGradient_Y, CV_16S, 0, 1, (2 * SobelKernelSize + 1), 1, 1, BORDER_DEFAULT); convertScaleAbs(SobelGradient_Y, SobelAbsGradient_Y); //合并梯度 addWeighted(SobelAbsGradient_X, 0.5, SobelAbsGradient_Y, 0.5, 0, dst); imshow("Sobel边缘检测", dst); imwrite("D:/learn-opencv/sobel.jpg", dst); }void Scharr(){ Scharr(src, ScharrGradient_X, CV_16S, 1, 0,1,0, BORDER_DEFAULT); convertScaleAbs(ScharrGradient_X, ScharrAbsGradient_X); Scharr(src, ScharrGradient_Y, CV_16S, 0, 1, 1, 0, BORDER_DEFAULT); convertScaleAbs(ScharrGradient_Y, ScharrAbsGradient_Y); addWeighted(ScharrAbsGradient_X, 0.5, ScharrAbsGradient_Y, 0.5, 0, dst); imshow("Scharr滤波器", dst); imwrite("D:/learn-opencv/scharr.jpg", dst);}
1.Canny 效果图
2.Sobel 效果图
3.Scharr滤波器