day17:图像的边缘检测

需要说 的是 由于求取边缘结果可能会有负数, 不在原始图像的 8U 的数据类型内,因此滤波后的图像数据类型为 CV 1 6S

 代码:

void visionagin::Myedge(Mat& img)
{
	Mat kernelx = (Mat_<float>(1, 3) << 1, 0, -1);//x方向的边缘检测滤波器
	Mat kernely = (Mat_<float>(3, 1) << 1, 0, -1);// y 方向的边缘检测滤波器
	Mat kernelleftup=(Mat_<float>(2, 2) << 1, 0, 0, -1);//左上到右下
	Mat kernelrightup = (Mat_<float>(2, 2) << 0,-1,1,0);//右上到左下
	Mat resx, resy, reslu, resru,res;//求取边缘检测后的数据有负数,用cv_16s接收
	filter2D(img, resx, CV_16S, kernelx, Point(-1, -1));
	filter2D(img, resy, CV_16S, kernely, Point(-1, -1));
	filter2D(img, reslu, CV_16S, kernelleftup, Point(-1, -1));
	filter2D(img, resru, CV_16S, kernelrightup, Point(-1, -1));
	convertScaleAbs(resx, resx);
	convertScaleAbs(resy, resy);
	convertScaleAbs(reslu, reslu);
	convertScaleAbs(resru, resru);//将结果图像像素值绝对值化
	res = resx + resy;
	imshow("res", res);//x,y方向的边缘检测方向结果相加即为整个图像的边缘检测结果
	imshow("resx", resx);
	imshow("resy", resy);
	imshow("reslu", reslu);
	imshow("resru", resru);
}

 

 1:Sobel算子

任意-个方向的差分阶数都需要小子算子的尺寸,特殊情况是,当 ksize=1 时,任意一个方向阶数需要小于 3. 在一般情况下,当差分阶数的最大值为1时,算子尺寸选3 ,当差分阶数的最大值为 2时,算子尺寸选5 ,当差分阶数最大值为3, 算子尺寸选 7. 当算子尺寸 ksize=,1,程序中使用的算子尺寸不再是正方形而是 3x 1 或者 1x 3.

 

代码:

void visionagin:: SobelOperate(Mat& img)
{
	Mat resx, resy, res;
	Sobel(img, resx, CV_16S, 2, 0, 5);//x方向二阶边缘
	Sobel(img, resy, CV_16S, 0, 1, 3);//y方向一阶边缘
	convertScaleAbs(resx, resx);
	convertScaleAbs(resy, resy);
	res = resx + resy;
	imshow("res", res);
	imshow("resx", resx);
	imshow("resy", resy);
}

 

2.Scharr算子:

虽然 S obel 算子 可以有效地提取图像 边缘,但 是对图像中较弱的边缘提取效果较差.因此 为 了能够有效地提取出较弱的边缘, 要将像 素值间的 差距增大, 于是引 入 Scharr 算子. Scharr 算子
是对 Sobel 差异性的增强,因此两者在 检测图 像边缘的 原理和使 用方式上相 同. Scharr 算子的
边缘检测滤波的尺寸为3  x3,  因此也称其 Scharr 滤波器.

 该函数的第四个、第五个参 数分别是提取x方向边缘和y方向边缘的标志,该函数要求这两个参数只能有一个参数为 1. 且不能同时为 0.否则则该函数将无法提取图像边缘,该函数默认的滤波器尺寸为 3x 3并且无法修改.

 3.生成边缘检测滤波器

Scharr   算子只有 种, 但是 Sobel  算子却有不同尺寸、不同阶次,  在实际使用过程中, 即使了解 Sobel  算子的原理 , 推导出边缘提取需 要的滤波器也 是十分复杂而烦琐的任务。
并且,有时我们并不希望提取图像中的边缘,而是希望得到能够提取图像边缘的滤波器,通过
对滤波器的修改提升边缘检测的效果.在 Opencv  中,提供了 ge tDe rivKern els() 函数,通过该
函数可以得到不同尺寸、不同阶次的 Sobel 算子和 Scharr  算子的滤波器.
void visionagin:: GetkerenelOperate(Mat& img)
{
	Mat sobelx1, sobelx2, sobelx3,sobely1,sobely2,sobely3, scharrx1,scharry1;
	Mat sobel1, sobel2, sobel3, scharr1;
	//x方向一阶sobel算子
	getDerivKernels(sobelx1, sobely1, 1, 0, 3);//结果Ksize*1的矩阵
	sobelx1 = sobelx1.reshape(CV_8U, 1);
	sobel1 = sobely1 * sobelx1;//相乘的矩阵列行相等
	//x方向二阶sobel算子
	getDerivKernels(sobelx2, sobely2, 2, 0, 5);
	sobelx2 = sobelx2.reshape(CV_8U, 1);
	sobel2 = sobely2 * sobelx2;
	//y方向三阶sobel算子
	getDerivKernels(sobelx3, sobely3, 0, 3, 7);
	sobelx3 = sobely3.reshape(CV_8U, 1);
	sobel3 = sobely3 * sobelx3;
	//x方向一阶Scharr算子
	getDerivKernels(scharrx1, scharry1, 1, 0, FILTER_SCHARR);//生成Scharr算子标志,FILTER_SCHARR
	scharrx1 = scharrx1.reshape(CV_8U, 1);
	scharr1 = scharry1 * scharrx1;
	cout << sobel1 << endl;
	cout << sobel2 << endl;
	cout << sobel3 << endl;
	cout << scharr1 << endl;
}

 4.Laplacian算子

上述的边缘检测算子都具有方向, 因此需要分别求x 方向的边缘,y方 向的边 缘,将两个方向的边缘综合得到图像的整 体边缘,Laplacian算子 具有各 方向同 性的特性,能 够对任意方向的边缘进行提取,具有 无方 向性 的优点 , 使用Laplacian算子 提取边缘不需要 检测 x方向 的边缘和y方向的边缘 ,只需要一 次边缘检 测. Laplacian算子 是一种二阶 导数算子,对噪声 敏感, 因此常需要配合 高斯滤波 一 起使用。

void visionagin::LaplassianOperate(Mat& img)
{
	Mat lapsres, lapsres2;
	Laplacian(img, lapsres, CV_16S, 1);
	convertScaleAbs(lapsres, lapsres);//绝对值化
	imshow("未去除噪声", lapsres);//未进行高斯滤波进行的laps边缘检测

	GaussianBlur(img, img, Size(3, 3), 1);//先进行高斯滤波
	Laplacian(img, lapsres2, CV_16S, 3);
	convertScaleAbs(lapsres2, lapsres2);
	imshow("去除噪声后", lapsres2);
}

结果:

 

 5.Canny算法

 

void visionagin:: Mycanny(Mat& img)
{
	Mat res1, res2, res3, res4;
	Canny(img, res1, 20, 40);
	imshow("res1低阈值", res1);//低阈值

	Canny(img, res2, 100, 200);
	imshow("res2高阈值", res2);//高阈值

	GaussianBlur(img, img, Size(3, 3), 5);
	Canny(img, res3, 20, 40);//进行了高斯滤波
	imshow("res3低阈值", res3);

	Canny(img, res4, 100, 200);
	imshow("res4高阈值", res4);
}

结果:分别为未进行高斯滤波,Canny低阈值,高阈值图像,以及进行高斯滤波Canny低阈值,高阈值图像

 未进行高斯滤波以及进行了高斯滤波:

结果表明高斯模糊在边缘纹理较多的区域能减少边缘检测的结果 但是对纹理较少 的区域影响较小.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值