Opencv--Canny边缘检测器

目标

  • 使用OpenCV函数cv :: Canny来实现Canny Edge Detector。

理论

该Canny边缘检测是由约翰·F·坎尼在1986年也知道很多的开发最佳的检测,坎尼算法旨在满足三个主要标准:

  • 低错误率:意味着只有现有边缘的良好检测。
  • 良好的定位:检测到的边缘像素与实际边缘像素之间的距离必须最小化。
  • 最小响应:每个边缘只有一个检测器响应。

步骤

  • 滤除任何噪音。高斯滤波器用于此目的。可能使用的的高斯内核的示例如下所示:size=5

Canny边缘检测器

  • 找到图像的强度梯度。为此,我们遵循类似于Sobel的程序:

应用一对卷积面罩 (在 x 和 y directions:

Canny边缘检测器

查找梯度强度和方向:

Canny边缘检测器

方向四舍五入为四个可能的角度之一(即0,45,90或135)

  • 应用非最大抑制。这将删除不被认为是边缘的一部分的像素。因此,只有细线(候选边)将保留。
  • 滞后:最后一步。Canny确实使用两个阈值(上限和下限):
  1. 如果像素梯度高于上限阈值,则像素被接受为边缘
  2. 如果像素梯度值低于较低阈值,则会被拒绝。
  3. 如果像素梯度在两个阈值之间,那么只有当它连接到高于上限阈值的像素时才被接受。

Canny推荐上限:2:1和3:1之间的较低比例。

  • 有关更多详细信息,您可以随时咨询您最喜爱的Computer Vision书籍。

Code

  • 这个程序是做什么的?
  1. 要求用户输入数值以设置我们的Canny Edge Detector的下限(通过Trackbar)。
  2. 应用Canny Detector并生成一个蒙版(亮线表示黑色背景上的边缘)。
  3. 应用在原始图像上获得的蒙版,并将其显示在窗口中。
  • 代码如下:
#include <opencv2/opencv.hpp>
#include <iostream>
#include <math.h>

using namespace cv;
Mat src, gray_src, dst;
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) {
	src = imread("C:/usr/opencv-test/Testpictures/sight.jpg");
	if (!src.data) {
		printf("could not load image...\n");
		return -1;
	}

	char INPUT_TITLE[] = "input image";
	namedWindow(INPUT_TITLE, CV_WINDOW_AUTOSIZE);
	namedWindow(OUTPUT_TITLE, CV_WINDOW_AUTOSIZE);
	imshow(INPUT_TITLE, src);

	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 * 3, 3, false);//false表用L1,即G(s) = |G(x)|+|G(y)|

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

说明

请注意以下事项:

  1. 我们建立一个较低的上限阈值3:1(与可变比率)的比率。
  2. 我们设置内核大小为(Sobel操作由Canny函数内部执行)。3
  3. 我们为的下限阈值设置最大值。100
  • 加载源图像:
  • 创建一个相同类型和大小的src(为dst)的矩阵:
  cvtColor(src,src_gray,COLOR_BGR2GRAY);
  • 创建一个窗口来显示结果:
  • 创建一个跟踪栏,供用户输入Canny检测器的下限:
createTrackbar("Threshold Value:", OUTPUT_TITLE, &t1_value, max_value, Canny_Demo);

观察以下内容:

  1. Trackbar要控制的变量是lowThreshold,最大值为max_lowThreshold(我们先前设置为100)
  2. 每次Trackbar注册一个动作时,将调用回调函数CannyThreshold。
  • 让我们检查CannyThreshold函数,一步一步:
  1. 首先,我们用内核大小为3的过滤器模糊图像:    
  1. blur(gray_src, gray_src, Size(3, 3), Point(-1, -1), BORDER_DEFAULT);
  2. 然后,我们应用OpenCV函数cv :: Canny
    Canny(gray_src, edge_output, t1_value, t1_value * 3, 3, false);

其中的解释:

    • detected_edges:源图像,灰度
    • detected_edges:检测器的输出(可以与输入相同)
    • lowThreshold:用户移动轨迹栏输入的值
    • highThreshold:在程序中设置为下限阈值的三倍(在Canny的建议之后)
    • kernel_size:我们将它定义为3(要在内部使用的Sobel内核的大小)

结果

  • 在编译上面的代码之后,我们可以运行它作为参数作为图像的路径。例如,使用以下图像作为输入:

Canny边缘检测器

 

  • 移动滑块,尝试不同的阈值,我们得到以下结果:

 

Canny边缘检测器

  • 注意图像如何与边缘区域上的黑色背景叠加。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值