zoukankan      html  css  js  c++  java
  • 边缘检测 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滤波器

  • 相关阅读:
    【BZOJ】【1833】【ZJOI2010】count 数字计数
    bzoj2588: Spoj 10628. Count on a tree(树上第k大)(主席树)
    NOIP2017金秋冲刺训练营杯联赛模拟大奖赛第一轮Day2题解
    NOIP2017金秋冲刺训练营杯联赛模拟大奖赛第二轮Day2题解
    51nod 1962 区间计数(单调栈+二分)
    51nod 1486 大大走格子(DP+组合数学)
    bzoj2276: [Poi2011]Temperature(单调队列/堆)
    5028: 小Z的加油店(线段树)
    bzoj2216: [Poi2011]Lightning Conductor(分治决策单调性优化)
    bzoj1057: [ZJOI2007]棋盘制作(悬线法)
  • 原文地址:https://www.cnblogs.com/carlber/p/9683566.html
Copyright © 2011-2022 走看看