Image Edge Extraction

Generally the boundary information of an image reflected by mutation gradation value, the image edge extraction is generally achieved by a method of capturing gray-scale mutations, mutations capture gradation can be realized by differentiating

Derivative greater the greater the change, the stronger the edge signal

 

1.Sobel operator

Also known as discrete differential operator, first-order differential operator, the derivative operator, do first Gaussian smoothing doing Differential guide

Find the gradient image can be in various directions

The horizontal direction Gx = [- 1,0,1, -2,0,2, -1,0,1], the vertical direction Gy = [- 1, -2, -1,0,0,0,1, 2,1]

The final G = sqrt (Gx ^ 2 + Gy ^ 2), or G = | Gx | + | Gy |

The second operation faster than the first, the second method is generally

Sobel operator improved version called Scharr operator [-3,0,3, -10,0,10, -3,0,3]

#include<iostream>
#include<opencv2/opencv.hpp>

using namespace std;
using namespace cv;

int main(int argc, char **argv)
{
    Mat src, dst;
    src = imread("b.png");
    if (src.empty())
    {
        cout << "load img failed" << endl;
        return -1;
    }
    imshow("input img", src);

    Mat gaussian,gray_src;
    GaussianBlur(src, gaussian, Size(3, 3), 0, 0);
    cvtColor(gaussian, gray_src, CV_BGR2GRAY);
    imshow("blur gray", gray_src);

    Mat xgrad, ygrad;
    Sobel(gray_src, xgrad, CV_16S, 1, 0, 3);
    Sobel(gray_src, ygrad, CV_16S, 0, 1, 3);
    convertScaleAbs(xgrad, xgrad);
    convertScaleAbs(ygrad, ygrad);
    imshow("x grade", xgrad);
    imshow("y grade", ygrad);
    
    addWeighted(xgrad, 0.5, ygrad, 0.5, 0, dst);
    imshow("output img", dst);
    /*
    dst = Mat(xgrad.size(), xgrad.type());
    int width = dst.cols;
    int height = dst.rows;
    for(int i=0;i<height;++i)
        for (int j = 0; j < width; ++j)
        {
            int xg = xgrad.at<char>(i, j);
            int yg = ygrad.at<char>(i, j);
            int xy = xg + yg;
            dst.at<char>(i, j) = saturate_cast<uchar>(xy);
        }
    imshow("output img", dst);*/
    waitKey(0);
    return 0;
}

 

 

 

 2.Laplance operator

The second derivative, the second derivative in time, the maximum change value of 0, i.e., the edge of the second derivative is zero

Process:

Gaussian blur de-noising GaussianBlur ()

Switch gradation value cvtColor ()

Laplance second derivative calculated Laplancian ()

Absolute value convertScaleAbs ()

Show results

#include<iostream>
#include<opencv2/opencv.hpp>

using namespace std;
using namespace cv;

int main(int argc, char **argv)
{
    Mat src, dst;
    src = imread("b.png");
    if (src.empty())
    {
        cout << "load img failed" << endl;
        return -1;
    }
    imshow("input img", src);

    Mat gaussian,gray_src;
    GaussianBlur(src, gaussian, Size(3, 3), 0, 0);
    cvtColor(gaussian, gray_src, CV_BGR2GRAY);
    imshow("blur gray", gray_src);

    Laplacian(gray_src, dst, CV_16S,3);
    convertScaleAbs(dst, dst);
    imshow("Laplacian", dst);
    threshold(dst, dst, 0, 255, THRESH_OTSU | THRESH_BINARY);
    imshow("output img", dst);
    /*
    dst = Mat(xgrad.size(), xgrad.type());
    int width = dst.cols;
    int height = dst.rows;
    for(int i=0;i<height;++i)
        for (int j = 0; j < width; ++j)
        {
            int xg = xgrad.at<char>(i, j);
            int yg = ygrad.at<char>(i, j);
            int xy = xg + yg;
            dst.at<char>(i, j) = saturate_cast<uchar>(xy);
        }
    imshow("output img", dst);*/
    waitKey(0);
    return 0;
}

 

 

3.Canny边缘检测

步骤:

高斯模糊 GaussianBlur

灰度转换cvtColor

计算梯度Sobel/Scharr

非最大信号抑制

高低阈值输出二值图像

 

非最大信号抑制需要计算梯度方向

 

 T1为低阈值,T2为高阈值,凡是高于T2的都保留,凡是低于T1的都丢弃,从高于T2的像素出发,凡是大于T1且相互连接的都保留,最终得到一个输出二值图像

推荐的高低阈值比为3:1或2:1

Canny(src,dst,threshold_low,threshold_high,Sobel_size,Lwgradient)

最后一个如果是true就用L2归一化(开根),如果不是就L1归一化(绝对值),一般用L1

#include<iostream>
#include<opencv2/opencv.hpp>

using namespace std;
using namespace cv;

Mat src, dst, gray_src, gaussian;
int t1_value = 50;
int max_value = 255;
const char* OUTPUT_TITLE = "Canny Result";
void Canny_Demo(int,void*);

int main(int argc, char **argv)
{
    //Mat src, dst;
    src = imread("b.png");
    if (src.empty())
    {
        cout << "load img failed" << endl;
        return -1;
    }
    imshow("input img", src);

    //Mat gaussian,gray_src;
    //GaussianBlur(src, gaussian, Size(3, 3), 0, 0);
    namedWindow(OUTPUT_TITLE, CV_WINDOW_AUTOSIZE);
    cvtColor(src, gray_src, CV_BGR2GRAY);
    createTrackbar("Threshold Value :", OUTPUT_TITLE, &t1_value, max_value, Canny_Demo);
    Canny_Demo(0, 0);
    waitKey(0);
    return 0;
}

void Canny_Demo(int, void*)
{
    Mat edge_output;
    blur(gray_src, gray_src, Size(3, 3), Point(-1, -1), BORDER_DEFAULT);
    Canny(gray_src, edge_output, t1_value, t1_value * 2, 3, false);

    //dst.create(src.size(), src.type());
    //src.copyTo(dst, edge_output);
    imshow(OUTPUT_TITLE, ~edge_output);
}

去掉注释会变成彩色图,注意修改imshow中的输出变量

 

Guess you like

Origin www.cnblogs.com/wangtianning1223/p/12101203.html