边缘检测 opencv

 本次实验使用了两种方法进行了边缘检测,分别使用到了opencv中的两个API函数为Canny()和Sobel()函数。实验后加了Scharr滤波器,它其实是基于Sobel()函数的。

这三个API中的参数可进行调整,实验中也可动态调整参数值来达到不同的检测效果。

#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>

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滤波器

posted @ 2018-09-20 21:54  RamboBai  阅读(733)  评论(0编辑  收藏  举报