PPC的C/C++和人工智能学习笔记
每一篇学习笔记,都只是为了更好地掌握和理解

数字图像处理与opencv(17)-Canny边缘检测

本次学习:openCV的Canny边缘检测的原理与相关的API应用。

 

Canny边缘检测算法:

是在1986年提出的一个很好的边缘检测器,是一种很常用也很实用的图像处理方法。

 

Canny的算法步骤:

1、高斯模糊;2、灰度转换;3、计算梯度(Sobel/Scharr);4、非最大信号抑制;5、高低阈值输出二值图像。输出的是背景为黑色的二值图像。输入图像也可以是彩色图,但是深度必须是8的。

非最大信号抑制:

首先计算出x方向和y方向的Sobel梯度,那么通过计算Gy/Gx的arctan,我们可以求出一个角度“西塔”,假如x方向变化剧烈,也就是Gx的值远大于Gy的值的时候,我们是判断该点的左右值,假如该点的值比它左边或者右边值小的话,则置0,是最大值的话保留,同样道理,按照“西塔”的角度做y方向,或者斜向的比较,保留最大的值。

非最大信号抑制:我们通过Sobel算子求出的边缘,可能是一条比较宽的线,而非最大信号抑制就是想找出这根比较宽的线中最合适的那根细线作为边缘。

 

高低阈值输出二值图像:

给出两个阈值T1,T2,一般情况下T2=2×T1或者3×T1;这里T1称为低阈值,T2称为高阈值,小于T1的全部置为0,大于T2的全部保留,而在T1和T2之间的点,只要是和T2直接或者间接连接的就保留(从高于T2的像素点出发,凡是大于T1而且相互连接的保留),反之舍弃。

 

openCV的Canny函数:

void Canny( InputArray image, OutputArray edges,

double threshold1, double threshold2,

int apertureSize = 3, bool L2gradient = false );

参数:threshold就是低阈值,threshold2就是高阈值;

最后1个参数,默认是flase,就是用L1来计算x和y方向的梯度和。

L1:Sobel算子计算得到的 x方向梯度的绝对值 + y方向梯度的绝对值

L2:两个方向的平方和然后再开根号。SQRT(x*x+y*y),精度高些,但是效率低

//Canny边缘检测.cpp
#include <opencv2/opencv.hpp>
using namespace cv;

int t1 = 60;
int max_t1 = 255;
const char* outWindow = "edge";
void Canny_demo(int, void*);
Mat src, gray_src, edge;

int main() {
 src = imread("1.jpg");
 if (src.empty()) return -1;
 imshow("src", src);
 namedWindow(outWindow, CV_WINDOW_AUTOSIZE);
 cvtColor(src, gray_src, CV_BGR2GRAY); //转灰度
 createTrackbar("bar", outWindow, &t1, max_t1, Canny_demo);
 Canny_demo(0, 0);
 waitKey(0);
 return 0;
}

void Canny_demo(int, void*) {
 Canny(gray_src, edge, t1, t1 * 2, 3, false);
 imshow(outWindow, ~edge);
 Mat dst;
 src.copyTo(dst, edge);
 imshow("color edge", dst);
}

(2017-03-27 www.vsppc.com)

学习笔记未经允许不得转载:PPC的C/C++和人工智能学习笔记 » 数字图像处理与opencv(17)-Canny边缘检测

分享到:更多 ()

评论 抢沙发

评论前必须登录!