【OpenCV】边缘检测

来源:互联网 发布:部落冲突七本满防数据 编辑:程序博客网 时间:2024/05/17 19:21

Sobel一阶导数

  Sobel操作符是一个离散的微分算子。它计算了图像强度函数的梯度,结合了高斯平滑和微分。

  函数Sobel() 检测水平变化、检测垂直变化


  函数Scharr() 比传统Sobel函数运算快而且更为准确。


代码示例

#include "opencv2/imgproc.hpp"#include "opencv2/imgcodecs.hpp"#include "opencv2/highgui.hpp"#include <iostream>using namespace cv;using namespace std;int main(int argc, char** argv){    CommandLineParser parser(argc, argv,            // 命令行解析类,减少命令行使用过程中的工作量        "{@input  | ../data/lena.jpg|input image}"        "{ksize k | 1 |hit 'K' to increase value}"        "{scale s | 1 |hit 'S' to increase value}"        "{delta d | 0 |hit 'D' to increase value}"        "{help  h | false |show help message}");    cout << "The sample uses Sobel or Scharr OpenCV functions for edge detection\n\n";    parser.printMessage();    cout << "\nPress 'ESC' to exit program.\n"        "Press 'R' to reset values ( ksize will be -1 equal to Scharr function )";    Mat image, src, src_gray, grad;    String window_name = "Sobel Demo";    int ksize = parser.get<int>("ksize");    int scale = parser.get<int>("scale");    int delta = parser.get<int>("delta");    int ddepth = CV_16S;    String imageName = parser.get<String>("@input");    // 获取图像路径和图像名               image = imread(imageName, IMREAD_COLOR);    if (image.empty()) { return -1; }    while (1)    {        GaussianBlur(image, src, Size(3, 3), 0, 0, BORDER_DEFAULT);     // 高斯模糊        cvtColor(src, src_gray, COLOR_BGR2GRAY);                        // 转换灰度图像        Mat grad_x, grad_y, abs_grad_x, abs_grad_y;        Sobel(src_gray, grad_x, ddepth, 1, 0, ksize, scale, delta, BORDER_DEFAULT);        Sobel(src_gray, grad_y, ddepth, 0, 1, ksize, scale, delta, BORDER_DEFAULT);        convertScaleAbs(grad_x, abs_grad_x);            // 缩放,计算绝对值,并将结果转换为8位        convertScaleAbs(grad_y, abs_grad_y);        addWeighted(abs_grad_x, 0.5, abs_grad_y, 0.5, 0, grad);        imshow(window_name, grad);        char key = (char)waitKey(0);        if (key == 27)        {            return 0;        }        if (key == 'k' || key == 'K')        {            ksize = ksize < 30 ? ksize + 2 : -1;        }        if (key == 's' || key == 'S')        {            scale++;        }        if (key == 'd' || key == 'D')        {            delta++;        }        if (key == 'r' || key == 'R')        {            scale = 1;            ksize = -1;            delta = 0;        }    }    return 0;}


运行结果


拉普拉斯二阶导数


代码示例

#include "opencv2/imgproc.hpp"#include "opencv2/imgcodecs.hpp"#include "opencv2/highgui.hpp"using namespace cv;int main(int argc, char** argv){    Mat src, src_gray, dst;    int kernel_size = 3;    int scale = 1;    int delta = 0;    int ddepth = CV_16S;    char* window_name = "Laplace Demo";    char* imageName = "../data/lena.jpg";    src = imread(imageName, IMREAD_COLOR);    if (src.empty()) { return -1; }    GaussianBlur(src, src, Size(3, 3), 0, 0, BORDER_DEFAULT);       // 高斯模糊    cvtColor(src, src_gray, COLOR_BGR2GRAY);                        // 转换灰度图像    Mat abs_dst;                                                    // 拉普拉斯二阶导数    Laplacian(src_gray, dst, ddepth, kernel_size, scale, delta, BORDER_DEFAULT);    convertScaleAbs(dst, abs_dst);                                  // 绝对值8位    imshow(window_name, abs_dst);    waitKey(0);    return 0;}


运行结果


Canny

优点:

  Low error rate: Meaning a good detection of only existent edges.

  Good localization: The distance between edge pixels detected and real edge pixels have to be minimized.

  Minimal response: Only one detector response per edge.


代码示例

#include "opencv2/imgproc.hpp"#include "opencv2/imgcodecs.hpp"#include "opencv2/highgui.hpp"using namespace cv;Mat src, src_gray, dst, detected_edges;int lowThreshold = 1;int max_lowThreshold = 100;int ratio = 3;int kernel_size = 3;char* window_name = "Canny Demo";void CannyThreshold(int, void*){    blur(src_gray, detected_edges, Size(3, 3));     // 平均滤波平滑    Canny(detected_edges, detected_edges, lowThreshold, lowThreshold*ratio, kernel_size);    dst = Scalar::all(0);    src.copyTo(dst, detected_edges);    imshow(window_name, dst);}int main(int, char** argv){    char* filename = "../data/lena.jpg";    src = imread(filename, IMREAD_COLOR);    if (src.empty()) { return -1;}    dst.create(src.size(), src.type());    cvtColor(src, src_gray, COLOR_BGR2GRAY);    namedWindow(window_name, WINDOW_AUTOSIZE);    createTrackbar("Min Threshold", window_name, &lowThreshold, max_lowThreshold, CannyThreshold);    CannyThreshold(0, 0);    waitKey(0);    return 0;}


运行结果


原创粉丝点击