需要说
的是
由于求取边缘结果可能会有负数, 不在原始图像的
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
滤波器.
![](https://i-blog.csdnimg.cn/blog_migrate/b64720c8516468e88cff8bff74b4ce93.png)
![](https://i-blog.csdnimg.cn/blog_migrate/487b0bf2943d2c94c1c6db0575399a4b.png)
该函数的第四个、第五个参 数分别是提取x方向边缘和y方向边缘的标志,该函数要求这两个参数只能有一个参数为 1. 且不能同时为 0.否则则该函数将无法提取图像边缘,该函数默认的滤波器尺寸为 3x 3并且无法修改.
3.生成边缘检测滤波器
Scharr
算子只有
两
种,
但是
Sobel
算子却有不同尺寸、不同阶次,
在实际使用过程中,
即使了解
Sobel
算子的原理 ,
推导出边缘提取需
要的滤波器也
是十分复杂而烦琐的任务。
并且,有时我们并不希望提取图像中的边缘,而是希望得到能够提取图像边缘的滤波器,通过
对滤波器的修改提升边缘检测的效果.在
Opencv
中,提供了
ge
tDe
rivKern
els()
函数,通过该
函数可以得到不同尺寸、不同阶次的
Sobel
算子和
Scharr
算子的滤波器.
![](https://i-blog.csdnimg.cn/blog_migrate/68d1d19d3c8dcebdc1185ce07d3753d9.png)
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算子
是一种二阶
导数算子,对噪声
敏感,
因此常需要配合
高斯滤波 一
起使用。
![](https://i-blog.csdnimg.cn/blog_migrate/daea502a1b11b0793a0e46169bb9be2f.png)
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低阈值,高阈值图像
未进行高斯滤波以及进行了高斯滤波:
结果表明高斯模糊在边缘纹理较多的区域能减少边缘检测的结果
但是对纹理较少
的区域影响较小.