2020.11.07 使用OpenCV进行图像边缘提取(Sobel算子)【OpenCV C++ Sobel】

图像边缘提取,采用的算子为Sobel

使用API:Sobel()以及增强了权重的Scharr()

处理流程:

1.进行高斯滤波

2.转化为灰度图像

3.进行X,Y轴的Sobel处理

4.对X,Y处理后的数据进行线性叠加(简化实际的Sobel运算)

源代码:

// testOpencv16.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;

const char* inWin = "input window";
const char* outWin = "output window";


int main()
{
   // std::cout << "Hello World!\n";

    Mat src, graySrc,dst;
    src = imread("E:/imageSources/7.jpg");
    if (!src.data) {
        printf("cannot load image,Please check you code");
        return -1;
    }

    namedWindow(inWin, WINDOW_AUTOSIZE);
    imshow(inWin,src);

    //进行高斯滤波
    GaussianBlur(src,dst,Size(3,3),0,0.0);
    cvtColor(dst,graySrc,COLOR_BGR2GRAY);
    imshow("gray image",graySrc);

    Mat sobelX, sobelY, sobelOutImage;
    //采用Sobel API进行图像边缘提取
    //Sobel(graySrc, sobelX, -1, 1, 0);
    //Sobel(graySrc, sobelY, -1, 0, 1);

    //Sobel(graySrc,sobelX,CV_16S,1,0);
    //Sobel(graySrc, sobelY, CV_16S, 0, 1);

    //采用Scharr:加权之后的Sobel算法
    Scharr(graySrc, sobelX, CV_16S, 1, 0);
    Scharr(graySrc, sobelY, CV_16S, 0, 1);


    //保证值都为正的相加
    //取绝对值操作
    convertScaleAbs(sobelX,sobelX);
    convertScaleAbs(sobelY,sobelY);

    Mat xyGrad = Mat::zeros(sobelX.size(),sobelX.type());
    int heigh = xyGrad.rows;
    int width = xyGrad.cols;
    //采用像素点遍历的方式进行X,Y线性叠加
    for (int row = 0; row < heigh; row++) {
        for (int col = 0; col < width; col++) {
            int x = sobelX.at<uchar>(row, col);
            int y = sobelY.at<uchar>(row, col);
            int xy = x + y;
            //限制xy像素值在一定范围内(防止因为相加造成超出像素范围值)
            xyGrad.at<uchar>(row, col) = saturate_cast<uchar>(xy);
            //xyGrad.at<uchar>(row, col) = xy;

        }
    }
    namedWindow(outWin, WINDOW_AUTOSIZE);
    imshow(outWin, xyGrad);


    //采用线性叠加,权重的方式
    double alpha = 0.5;
    addWeighted(sobelX, alpha ,sobelY,(1- alpha),0.0,sobelOutImage);
    namedWindow(outWin, WINDOW_AUTOSIZE);
    imshow("addWeight method", sobelOutImage);

    waitKey(0);
    return 0;
}


图像处理效果:

使用sobel()(像素点遍历相加 + addWeight的方法进行线性叠加)

2020.11.07 使用OpenCV进行图像边缘提取(Sobel算子)【OpenCV C++ Sobel】

 

使用Scharr()(像素遍历线性相加+addWeight的方法进行线性叠加)

2020.11.07 使用OpenCV进行图像边缘提取(Sobel算子)【OpenCV C++ Sobel】

可以看到使用Scharr()更加能抓住图像细节边缘