OpenCV学习笔记(十二):边缘检测:Canny(),Sobel(),Laplace(),Scharr滤波器

OpenCV学习笔记(十二):边缘检测:Canny(),Sobel(),Laplace(),Scharr滤波器

1)滤波:边缘检测的算法主要是基于图像强度的一阶和二阶导数,但导数通常对噪声很敏感,因此必须采用滤波器来改善与噪声有关的边缘检测器的性能。常见的滤波方法主要有高斯滤波,即采用离散化的高斯函数产生一组归一化的高斯核,然后基于高斯核函数对图像灰度矩阵的每一点进行加权求和。
2)增强:增强边缘的基础是确定图像各点邻域强度的变化值。增强算法可以将图像灰度点邻域强度值有显著变化的点凸显出来。在具体编程实现时,可通过计算梯度幅值来确定。
3)检测:经过增强的图像,往往邻域中有很多点的梯度值比较大,而在特定的应用中,这些点并不是我们要找的边缘点,所以应该采用某种方法来对这些点进行取舍。实际工程中,常用的方法是通过阈值化方法来检测。

1、Canny()算子:

Canny边缘检测算子是一个多级边缘检测算法

C++: void Canny(InputArray image,	//输入图像,即源图像
OutputArray edges, 					// 输出的边缘图
double threshold1, 					// 第一个滞后性阈值
double threshold2, 					// 第二个滞后性阈值// 这个函数阈值1和阈值2两者的小者用于边缘连接,而大者用来控制强边缘的初始段,推荐的高低阈值比在2:1到3:1之间。
int apertureSize=3,					// 表示应用Sobel算子的孔径大小
bool L2gradient=false 				// 一个计算图像梯度幅值的标识
)

2、Sobel()算子:

Sobel 算子是一个主要用作边缘检测的离散微分算子 (discrete differentiation operator)。它Sobel算子结合了高斯平滑和微分求导,用来计算图像灰度函数的近似梯度。在图像的任何一点使用此算子,将会产生对应的梯度矢量或是其法矢量。

void Sobel (
InputArray src,				// 输入图
OutputArray dst,			// 输出图
int ddepth,					// 输出图像的深度// 若src.depth() = CV_8U, 取ddepth =-1/CV_16S/CV_32F/CV_64F// 若src.depth() = CV_16U/CV_16S, 取ddepth =-1/CV_32F/CV_64F// 若src.depth() = CV_32F, 取ddepth =-1/CV_32F/CV_64F// 若src.depth() = CV_64F, 取ddepth = -1/CV_64F
int dx,						// x 方向上的差分阶数
int dy,						// y 方向上的差分阶数	
int ksize=3,				// 表示Sobel核的大小;必须取1,3,5或7
double scale=1,				// 计算导数值时可选的缩放因子 
double delta=0,				// 表示在结果存入目标图之前可选的delta值
int borderType=BORDER_DEFAULT 	// 边界模式
);

3、Laplace()算子:

Laplacian 算子是n维欧几里德空间中的一个二阶微分算子,定义为梯度grad()的散度div()。Laplacian( )函数其实主要是利用sobel算子的运算。它通过加上sobel算子运算出的图像x方向和y方向上的导数,来得到我们载入图像的拉普拉斯变换结果。

void Laplacian(InputArray src,		// 源图像
OutputArray dst, 					// 输出的边缘图
int ddepth, 						// 输出图像的深度
int ksize=1, 						// 用于计算二阶导数的滤波器的孔径尺寸
double scale=1, 					// 计算拉普拉斯值的时候可选的比例因子
double delta=0, 					// 表示在结果存入目标图之前可选的delta值 
intborderType=BORDER_DEFAULT 		// 边界模式
);

4、scharr滤波器:

scharr一般我就直接称它为滤波器,而不是算子,主要是配合Sobel算子的运算而存在的。
scharr算子与Sobel的不同点是在平滑部分,这里所用的平滑算子是1/16∗[3,10,3],相比于1/4∗[1,2,1],中心元素占的权重更重,这可能是相对于图像这种随机性较强的信号,邻域相关性不大,所以邻域平滑应该使用相对较小的标准差的高斯函数,也就是更瘦高的模板。

void Scharr(
InputArray src, 			// 源图OutputArray dst, 			// 目标图int ddepth,				// 图像深度int dx,					// x方向上的差分阶数int dy,					//y方向上的差分阶数double scale=1,			//缩放因子double delta=0,			// delta值intborderType=BORDER_DEFAULT 	// 边界模式)		

4、代码示例:

#include <opencv2/opencv.hpp>using namespace cv;
using namespace std;//原图,原图的灰度版,目标图
Mat g_srcImage, g_srcGrayImage,g_dstImage;//Canny边缘检测相关变量
Mat g_cannyDetectedEdges;
int g_cannyLowThreshold=1;//TrackBar位置参数  //Sobel边缘检测相关变量
Mat g_sobelGradient_X, g_sobelGradient_Y;
Mat g_sobelAbsGradient_X, g_sobelAbsGradient_Y;
int g_sobelKernelSize=1;//TrackBar位置参数  //Scharr滤波器相关变量
Mat g_scharrGradient_X, g_scharrGradient_Y;
Mat g_scharrAbsGradient_X, g_scharrAbsGradient_Y;int main()
{//载入原图g_srcImage = imread("F:/C++/2. OPENCV 3.1.0/7.1 edge detection 边缘检测/5.jpg");if( !g_srcImage.data ) { printf("Oh,no,读取srcImage错误~! \n"); return false; }//显示原始图namedWindow("【原始图】");imshow("【原始图】", g_srcImage);// 1、创建与src同类型和大小的矩阵(dst)g_dstImage.create( g_srcImage.size(), g_srcImage.type() );// 2、将原图像转换为灰度图像cvtColor( g_srcImage, g_srcGrayImage, COLOR_BGR2GRAY );// 3、创建trackbarnamedWindow( "【效果图】Canny边缘检测", WINDOW_AUTOSIZE );namedWindow( "【效果图】Sobel边缘检测", WINDOW_AUTOSIZE );createTrackbar( "参数值:", "【效果图】Canny边缘检测", &g_cannyLowThreshold, 120, on_Canny);createTrackbar( "参数值:", "【效果图】Sobel边缘检测", &g_sobelKernelSize, 3, on_Sobel);// 4、调用回调函数on_Canny(0, 0);on_Sobel(0, 0);// 5、调用封装了Scharr边缘检测代码的函数Scharr( );//轮询获取按键信息,若按下Q,程序退出while((char(waitKey(1)) != 'q')) {}
}

1)Canny边缘检测窗口滚动条的回调函数

void on_Canny(int, void*)
{// 先使用 3x3内核来降噪blur( g_srcGrayImage, g_cannyDetectedEdges, Size(3,3) );// 运行我们的Canny算子// threshold1:滞后性阈值1(较小值用于边缘连接,较大值控制强边缘的初始段)// threshold2:滞后性阈值2// apertureSize sobel算子的孔径大小Canny( g_cannyDetectedEdges, g_cannyDetectedEdges, g_cannyLowThreshold, g_cannyLowThreshold*3, 3 );//先将g_dstImage内的所有元素设置为0g_dstImage = Scalar::all(0);//使用Canny算子输出的边缘图g_cannyDetectedEdges作为掩码,来将原图g_srcImage拷到目标图g_dstImage中g_srcImage.copyTo( g_dstImage, g_cannyDetectedEdges);//显示效果图imshow( "【效果图】Canny边缘检测", g_dstImage );
}

2)Sobel边缘检测窗口滚动条的回调函数

void on_Sobel(int, void*)
{//Sobel算子是一阶导数的边缘检测算子,在算法实现过程中,通过3×3模板作为核与图像中的每个像素点做卷积和运算,然后选取合适的阈值以提取边缘。//Sobel算子算法的优点是计算简单,速度快。但是由于只采用了2个方向的模板,只能检测水平和垂直方向的边缘,//因此这种算法对于纹理较为复杂的图像,其边缘检测效果就不是很理想。该算法认为://凡灰度新值大于或等于阈值的像素点时都是边缘点。//这种判断欠合理,会造成边缘点的误判,因为许多噪声点的灰度值也很大。// ddepth:输出图像的深度// dx,dy: x y方向上的差分阶数// scale :计算导数时的缩放因子// 求 X方向梯度Sobel( g_srcImage, g_sobelGradient_X, CV_16S, 1, 0, (2*g_sobelKernelSize+1), 1, 1, BORDER_DEFAULT );// 对于输入数组的每个元素,convertScaleAbs函数依次执行三个操作:缩放、取绝对值、转换为无符号8位类型 :// dst(I)=saturate\_cast<uchar>(|src(I)∗alpha+beta|)convertScaleAbs( g_sobelGradient_X, g_sobelAbsGradient_X );
//    Mat grad_xROI(grad_x,Rect(0,0,20,20));
//    cout<<"M="<<endl<<grad_xROI<<endl;
//    imshow("【效果图】 X方向Sobel1", grad_x);// 求Y方向梯度Sobel( g_srcImage, g_sobelGradient_Y, CV_16S, 0, 1, (2*g_sobelKernelSize+1), 1, 1, BORDER_DEFAULT );convertScaleAbs( g_sobelGradient_Y, g_sobelAbsGradient_Y );// 合并梯度addWeighted( g_sobelAbsGradient_X, 0.5, g_sobelAbsGradient_Y, 0.5, 0, g_dstImage );//显示效果图imshow("【效果图】Sobel边缘检测", g_dstImage);}

3)Scharr边缘检测相关代码的函数

void Scharr( )
{// scharr算子与Sobel的不同点是在平滑部分,这里所用的平滑算子是1/16∗[3,10,3],// 相比于1/4∗[1,2,1],中心元素占的权重更重,这可能是相对于图像这种随机性较强的信号,// 邻域相关性不大,所以邻域平滑应该使用相对较小的标准差的高斯函数,也就是更瘦高的模板。// 求 X方向梯度Scharr( g_srcImage, g_scharrGradient_X, CV_16S, 1, 0, 1, 0, BORDER_DEFAULT );convertScaleAbs( g_scharrGradient_X, g_scharrAbsGradient_X );//计算绝对值,并将结果转换成8位// 求Y方向梯度Scharr( g_srcImage, g_scharrGradient_Y, CV_16S, 0, 1, 1, 0, BORDER_DEFAULT );convertScaleAbs( g_scharrGradient_Y, g_scharrAbsGradient_Y );//计算绝对值,并将结果转换成8位// 合并梯度addWeighted( g_scharrAbsGradient_X, 0.5, g_scharrAbsGradient_Y, 0.5, 0, g_dstImage );//显示效果图imshow("【效果图】Scharr滤波器", g_dstImage);
}

结果:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/491146.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

微软转型里程碑:云计算收入首次超过Windows业务

来源&#xff1a;腾讯科技导语 微软云计算业务第二季度收入为114亿美元&#xff0c;实现了64%的营收增长&#xff0c;上年同期和上一季度的增幅分别为89%和73%。腾讯科技讯 据国外媒体报道&#xff0c;微软公司今日公布了二季度财报&#xff08;自然季度&#xff0c;下同&#…

OpenCV学习笔记(十三):霍夫变换:HoughLines(),HoughLinesP(),HoughCircles( )

OpenCV学习笔记&#xff08;十三&#xff09;&#xff1a;霍夫变换&#xff1a;HoughLines(),HoughLinesP(),HoughCircles( ) 1、霍夫线变换HoughLines() OpenCV支持三种不同的霍夫线变换&#xff0c;它们分别是&#xff1a; 1&#xff09;标准霍夫变换(Standard Hough Trans…

“如果没有IBM和其所提供的系统,我们就无法登上月球。”

来源&#xff1a;IBM中国“如果没有IBM和其所提供的系统&#xff0c;我们就无法登上月球。”——NASA飞行指挥官 Gena Kra1969年7月20日&#xff0c;就在距离阿姆斯特朗迈出“人类一大步”约122米的月球上空&#xff0c;登月舱里突然响起了刺耳的警报声。警报向NASA显示机载电脑…

C++有符号和无符号数的转换

本文转自&#xff1a;http://www.94cto.com/index/Article/content/id/59973.html 1.引例&#xff1a; 今天在做了一道关于有符号数和无符号数相互转换及其左移/右移的问题&#xff0c;被它们之间的转换原理和位移原理搞得头大了。真的很后悔本科的时候没有认真学习《计算机组成…

OpenCV学习笔记(十四):重映射:remap( )

OpenCV学习笔记&#xff08;十四&#xff09;&#xff1a;重映射&#xff1a;remap( ) 图像的坐标映射是通过原图像与目标图像之间建立一种映射关系&#xff0c;这种映射关系有两种&#xff0c;一种是计算原图像任意像素在映射后图像的坐标位置&#xff0c;另一种是计算变换后…

C++中setw()的用法

setw&#xff08;&#xff09; 用于控制输出之间的间隔 #include <iomanip> using std::setw;cout<<s<<setw(8)<<a<<endl; s和a之间有7个空格&#xff0c;cout<<s<<setw(8)<<a<<endl;的意思是s后面输出8个字符&#xf…

自动驾驶产业链全景图

来源&#xff1a;乐晴智库精选自动驾驶产业链构成:感知-决策-执行 三个层面从感知层面看&#xff0c;感知环境的激光雷达、毫米波雷达、摄像头、红外夜视和组合导航设备&#xff0c;感知车辆自身的包括压力传感器、流量传感器、陀螺仪及加速度传感器等传感器都属于感知层面的零…

OpenCV学习笔记(十五):图像仿射变换:warpAffine(),getRotationMatrix2D()

OpenCV学习笔记&#xff08;十五&#xff09;&#xff1a;图像仿射变换&#xff1a;warpAffine(),getRotationMatrix2D() 一个任意的仿射变换都能表示为乘以一个矩阵(线性变换)接着再加上一个向量(平移)的形式。 仿射变换&#xff08;Affine Transformation或 Affine Map&…

『科技』2019全球最有前景AI公司TOP100

来源&#xff1a;eet-china I 整理&#xff1a;弗锐达引言&#xff1a;硅谷最强智库之一的CB Insights发布AI 100 2019报告&#xff0c;在全球范围内评选出了100家“最有前景”的AI创业公司&#xff0c;其中中国公司有6家&#xff0c;分别是……日前&#xff0c;硅谷最强智库之…

《环球》杂志 :《人工智能的“大脑”》

《环球》杂志 &#xff08;2019年6月26日出版的第13期&#xff09;文章来源&#xff1a;《环球》杂志 &#xff08;2019年6月26日出版的第13期&#xff09;&#xff0c;原题《人工智能的“大脑”》作者&#xff1a;徐贵宝 中国信息通信研究院图片来源&#xff1a;网络编辑&…

人类首次登月50年后,这60家公司决心重返月球

来源&#xff1a; 资本实验室1969年7月20日&#xff0c;美国宇航员尼尔阿姆斯特朗在踏上月球的那一刻&#xff0c;发出了“这是个人的一小步&#xff0c;却是人类的一大步”的经典感慨。这句话既是对地球之外更广袤空间的由衷赞叹&#xff0c;也是对人类勇气与探索精神的坚定表…

OpenCV学习笔记(十六):直方图均衡化:equalizeHist()

OpenCV学习笔记&#xff08;十六&#xff09;&#xff1a;直方图均匀化&#xff1a;equalizeHist() 参考博客&#xff1a; 直方图均衡化的数学原理 直方图匹配的数学原理 直方图均衡化广泛应用于图像增强中&#xff1a; 直方图均衡化处理的“中心思想”是把原始图像的灰度直方…

PHP自学3——在html的table标签中显示用户提交表单

为了更好地显示用户提交表单&#xff0c;本节将在上一节的基础上将读取的用户表单显示在html的<table>标签中&#xff0c;这一节将用到和数组有关的知识。 本节代码将从外部文件&#xff08;.txt文件&#xff09;中读取信息于指定数组中&#xff0c;然后对逐条订单进行处…

《科学》封面特别报道:人类登月50年

来源&#xff1a;学术经纬50年前的今天&#xff0c;1969年7月20日&#xff0c;人类首次踏足地球以外的世界&#xff1a;阿波罗11号登月舱着陆月球表面。▲阿波罗11号的三位宇航员&#xff1a;踏足月球的尼尔阿姆斯特朗&#xff08;Neil Armstrong&#xff0c;左&#xff09;、巴…

图解JVM的Class文件格式(详细版)

了解JAVA的Class文件结构有助于掌握JAVA语言的底层运行机制&#xff0c;我在学习的过程中会不断的与ELF文件格式作对比&#xff08;当然他们的复杂程度、格式相去甚远&#xff0c;比如可执行ELF的符号表解析在静态链接阶段已经完成(除了动态链接库是在动态链接阶段完成)&#x…

OpenCV学习笔记(十七):查找并绘制轮廓:findContours(),drawContours(),approxPolyDP()

OpenCV学习笔记&#xff08;十七&#xff09;&#xff1a;查找并绘制轮廓&#xff1a;findContours() 1、findContours() 函数 该函数使用Suzuki85算法从二值图像中检索轮廓。轮廓线是一种用于形状分析、目标检测和识别的有效工具。 opencv轮廓检测之FindContours函数算法解释…

69张图看懂Elon Musk的脑机接口芯片项目

来源&#xff1a;内容由半导体行业观察整理因为制造特斯拉等各种先进科技产品&#xff0c;Elon Musk被誉为地球上最有创新力的人之一。近来&#xff0c;他更是在脑机接口上有了新的突破。据英国《金融时报》18日报道&#xff0c;他旗下的脑机接口初创公司Neuralink&#xff0c;…

C++可重载运算符和不可重载运算符

可重载运算符&#xff1a; 不可重载运算符&#xff1a;

OpenCV学习笔记(十八):凸包,最小包围区域算子:convexHull(),minAreaRect(),minEnclosingTriangle(),minEnclosingCircle()

OpenCV学习笔记&#xff08;十八&#xff09;&#xff1a;凸包&#xff0c;最小包围区域算子&#xff1a;convexHull(),minAreaRect(),minEnclosingTriangle(),minEnclosingCircle() 1、convexHull()函数 计算出图像点集的凸包&#xff0c;根据图像的轮廓点&#xff0c;通过函…