边缘检测Canny算子
该算法不容易受到噪声的影响,能够识别图像中的弱边缘和强边缘,并结合强弱边缘的位置关系,综和给出图像整体的边缘信息。Canny边缘检测算法是目前最优越的边缘检测算法之一,该方法的检测过程分为以下5个步骤:
Step1:使用高斯滤波平滑图像,减少图像中噪声。一般情况下使用式所示的5×5的高斯滤波器。
Step2:计算图像中每个像素的梯度方向和幅值。首先通过Sobel算子分别检测图像X方向的边缘和Y方向的边缘,之后利用式(5.24)计算梯度的方向和幅值。
为了简便,梯度方向常取值0°、45°、90°和135°这个四个角度之一。
void Canny( InputArray image, OutputArray edges,
double threshold1, double threshold2,
int apertureSize = 3, bool L2gradient = false );
该函数利用Canny算法提取图像中的边缘信息。第一个参数是需要提取边缘的输入图像,目前只支持数据类型为CV_8U的图像,输入图像可以是灰度图像或者彩色图像。第二个参数是边缘检测结果的输出图像,图像是数据类型为为CV_8U的单通道灰度图像。函数第三个和第四个参数是Canny算法中用于区分强边缘和弱边缘的两个阈值,两个参数不区分较大阈值和较小阈值,函数会自动比较区分两个阈值的大小,不过一般情况下,较大阈值与较小阈值的比值在2:1到3:1之间。函数最后一个参数是计算梯度幅值方法的选择标志,无特殊需求的情况下,使用默认值即可。
简单示例
//
// Created by smallflyfly on 2021/6/15.
//
#include "opencv2/opencv.hpp"
#include "opencv2/highgui.hpp"
#include "utils.hpp"
#include
using namespace std;
using namespace cv;
int main() {
Mat im = imread("test.jpg", IMREAD_GRAYSCALE);
if (im.empty()) {
cerr << "image file read error" << endl;
return -1;
}
resize(im, im, Size(0, 0), 0.5, 0.5);
Mat result11, result12, result21, result22, result31, result32, result41, result42;
Canny(im, result11, 100, 200);
Canny(im, result12, 100, 200, 3, true);
Canny(im, result21, 20, 50);
Canny(im, result22, 20, 50, 3, true);
// gauss blur
Mat imGauss;
GaussianBlur(im, imGauss, Size(5, 5), 5);
Canny(imGauss, result31, 20, 50);
Canny(imGauss, result32, 20, 50, 3, true);
Canny(imGauss, result41, 100, 200);
Canny(imGauss, result42, 100, 200, 3, true);
showImage("result11", result11);
showImage("result12", result12);
showImage("result21", result21);
showImage("result22", result22);
showImage("result31", result31);
showImage("result32", result32);
showImage("result41", result41);
showImage("result42", result42);
waitKey(0);
destroyAllWindows();
return 0;
}