opencv学习笔记(二十)Canny边缘检测

1.原理

个人觉得和Sobel算子差不多,不过其对高低阈值又进行了一个控制,下面介绍。

2.相关API

Canny(InputArray src,OutputArray edges,double threshold1,double threshold2,int aptertureSize,bool L2gradient )

参数1:8-bit的输入图像

参数2:输出边缘图像, 一般都是二值图像,背景是黑色

参数3:低阈值

参数4:高阈值(为低阈值2到3倍)

参数5:Soble算子的size,通常3x3,取值3

参数6:归一化方法,一般用L1取绝对值

参数3和4的解释:T1T2为高低阈值,凡是高于T2的都保留,凡是小于T1都丢弃,从高于T2像素出发,凡是大于T1而且相互连接的,都保留。最终得到一个输出二值图像。

3.代码实现

#include "stdafx.h"
#include <opencv2/opencv.hpp>
#include <iostream>
#include <math.h>
using namespace std;
using namespace cv;

Mat src, dst,srcGray,result;
char inputName[] = "input name";
char outputName[] = "output name";
int t1Value = 50;
int maxValue = 255;
void CannyDemo(int, void*);
int main()
{
	src = imread("D:/demo.jpg");
	if (src.empty())
	{
		cout << "找不到图像" << endl;
		return -1;
	}
	namedWindow(inputName, CV_WINDOW_AUTOSIZE);
	imshow(inputName, src);
	namedWindow(outputName, CV_WINDOW_AUTOSIZE);
	GaussianBlur(src, dst, Size(3, 3), 0, 0);
	cvtColor(dst, srcGray, CV_BGR2GRAY);
	createTrackbar("Threshold T1 Value", outputName, &t1Value, maxValue, CannyDemo);
	CannyDemo(0, 0);

	waitKey(0);
	return 0;
}

void CannyDemo(int, void*)
{
	Mat final;
	Canny(srcGray, result, t1Value, t1Value * 3, 3, false);
	final.create(src.size(), src.type());
	src.copyTo(final, result);//A.copyTo(B, mask),如果在某个像素点(i, j)其值为1(只看第一通道,所以mask单通道即可),则把A.at(i, j)处的值直接赋给B.at(i, j),如果其值为0则B.at(i, j)处保留其原始像素值。这样能够使得图标边缘的颜色和原图保持一致。
	imshow(outputName, final);
}

4.运行结果

当低阈值较低时候保留的细节越多,所以轮廓越明显。低阈值高的时候如下:

扫描二维码关注公众号,回复: 9968117 查看本文章

发布了53 篇原创文章 · 获赞 9 · 访问量 3281

猜你喜欢

转载自blog.csdn.net/weixin_41039168/article/details/96423343