8基于opencv的边缘检测_Canny算子_Sobel算子_Laplace算子_Scharr滤波器

来源:互联网 发布:最好的音频编辑软件 编辑:程序博客网 时间:2024/06/05 04:44

边缘检测Canny算子、Sobel算子、Laplace算子、Scharr滤波器

一、 Canny算子

1.1 Canny()函数各参数详解

void Canny(InputArray image,OutputArray edges,double threshold1,doublethreshold2,int apertureSize = 3,boolL2gradient =false)

Ø  第一个参数,InputArray类型的image,输入图像,即源图像,填Mat类的对象即可,且需为单通道8位图像。

Ø  第二个参数,OutputArray类型的edges,输出的边缘图,需要和源图片有一样的尺寸和类型。

Ø  第三个参数,double类型的threshold1,第一个滞后性阈值。

Ø  第四个参数,double类型的threshold2,第二个滞后性阈值。

Ø  第五个参数,int类型的apertureSize,表示应用Sobel算子的孔径大小,其有默认值3。

Ø  第六个参数,bool类型的L2gradient,一个计算图像梯度幅值的标识,有默认值false。

需要注意的是,这个函数阈值1和阈值2两者的小者用于边缘连接,而大者用来控制强边缘的初始段,推荐的高低阈值比在2:1到3:1之间。

1.2调用示例 

Mat ScrImgae, OutImage1;

ScrImage = imread("E:\\1TJQ\\Opencv\\Images\\image1.jpg");

Canny(ScrImgae,OutImage1, 150, 50, 3); //Canny边缘检测算法

imshow("Canny边缘检测算法", OutImage1);

 

二、 Sobel算子

2.1 Sobel ()函数各参数详解

 

void Sobel(InputArray src,OutputArray dst,int ddepth,int dx,int dy, int ksize = 3,double scale =1,double delta = 0,int borderType =BORDER_DEFAULT)

Ø  第一个参数,InputArray 类型的src,为输入图像,填Mat类型即可。

Ø  第二个参数,OutputArray类型的dst,即目标图像,函数的输出参数,需要和源图片有一样的尺寸和类型。

Ø  第三个参数,int类型的ddepth,输出图像的深度,支持如下src.depth()和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,表示默认情况下是没有应用缩放的。我们可以在文档中查阅getDerivKernels的相关介绍,来得到这个参数的更多信息。

Ø  第八个参数,double类型的delta,表示在结果存入目标图(第二个参数dst)之前可选的delta值,有默认值0。

Ø  第九个参数, int类型的borderType,我们的老朋友了(万年是最后一个参数),边界模式,默认值为BORDER_DEFAULT。这个参数可以在官方文档中borderInterpolate处得到更详细的信息。

 

一般情况下,都是用ksize xksize内核来计算导数的。然而,有一种特殊情况——当ksize为1时,往往会使用3 x 1或者1 x 3的内核。且这种情况下,并没有进行高斯平滑操作。

1.2调用示例 

Mat ScrImgae, OutImage3, OutImage4, OutImage5, OutImage6;

ScrImage = imread("E:\\1TJQ\\Opencv\\Images\\image1.jpg");

Sobel(ScrImgae, OutImage3, CV_16S, 1, 0,3);//Sobel边缘检测算法X方向

   convertScaleAbs(OutImage3,OutImage4); //计算绝对值,并将结果转换成8

   Sobel(ScrImgae,OutImage3, CV_16S, 0, 1, 3);//Sobel边缘检测算法Y方向

   convertScaleAbs(OutImage3,OutImage5);

   addWeighted(OutImage4,0.5, OutImage5, 0.5, 0, OutImage6);//Sobel边缘检测算法X方向和Y方向加起来注意:要分别对X方向和Y方向进行操作,效果才好。不能一起操作

   imshow("Sobel边缘检测算法X",OutImage4);

   imshow("Sobel边缘检测算法Y",OutImage5);

imshow("Sobel边缘检测算法X+Y", OutImage6);

 

 

三、 Laplacian算子

2.1 Laplacian ()函数各参数详解

   voidLaplacian(InputArray src,OutputArray dst,int ddepth,int ksize = 1,double scale =1,double delta = 0, intborderType =BORDER_DEFAULT)

Ø  第一个参数,InputArray类型的image,输入图像,即源图像,填Mat类的对象即可,且需为单通道8位图像。

Ø  第二个参数,OutputArray类型的edges,输出的边缘图,需要和源图片有一样的尺寸和通道数。

Ø  第三个参数,int类型的ddept,目标图像的深度。

Ø  第四个参数,int类型的ksize,用于计算二阶导数的滤波器的孔径尺寸,大小必须为正奇数,且有默认值1。

Ø  第五个参数,double类型的scale,计算拉普拉斯值的时候可选的比例因子,有默认值1。

Ø  第六个参数,double类型的delta,表示在结果存入目标图(第二个参数dst)之前可选的delta值,有默认值0。

Ø  第七个参数, int类型的borderType,边界模式,默认值为BORDER_DEFAULT。这个参数可以在官方文档中borderInterpolate()处得到更详细的信息。

Laplacian( )函数其实主要是利用sobel算子的运算。它通过加上sobel算子运算出的图像x方向和y方向上的导数,来得到我们载入图像的拉普拉斯变换结果。

 

1.2调用示例 

Mat ScrImgae, OutImage7;

ScrImage = imread("E:\\1TJQ\\Opencv\\Images\\image1.jpg");

Laplacian(ScrImgae, OutImage7, CV_16S, 3);     //Lapacian边缘检测算法,基于Sobel边缘检测算法为基础

   convertScaleAbs(OutImage7,OutImage7);  //计算绝对值,并将结果转换成8

imshow("Laplacian边缘检测算法", OutImage7);

 

 

四、 Scharr滤波器

2.1 Scharr ()函数各参数详解

void Scharr(InputArray src,OutputArray dst,int ddepth,int dx,int dy, double scale = 1,double delta =0, intborderType =BORDER_DEFAULT

Ø  第一个参数,InputArray 类型的src,为输入图像,填Mat类型即可。

Ø  第二个参数,OutputArray类型的dst,即目标图像,函数的输出参数,需要和源图片有一样的尺寸和类型。

Ø  第三个参数,int类型的ddepth,输出图像的深度,支持如下src.depth()和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方向上的差分阶数。

Ø  第六个参数,double类型的scale,计算导数值时可选的缩放因子,默认值是1,表示默认情况下是没有应用缩放的。我们可以在文档中查阅getDerivKernels的相关介绍,来得到这个参数的更多信息。

Ø  第七个参数,double类型的delta,表示在结果存入目标图(第二个参数dst)之前可选的delta值,有默认值0。

Ø  第八个参数, int类型的borderType,我们的老朋友了(万年是最后一个参数),边界模式,默认值为BORDER_DEFAULT。这个参数可以在官方文档中borderInterpolate处得到更详细的信息。

如下两者等价:

Scharr(src, dst, ddepth, dx, dy, scale, delta,borderType);

Sobel(src, dst, ddepth, dx, dy, CV_SCHARR, scale,delta, borderType);

 

1.2调用示例 

Mat ScrImgae, OutImage1, OutImage2, OutImage;

ScrImage = imread("E:\\1TJQ\\Opencv\\Images\\image1.jpg");

Scharr(ScrImgae, OutImage1, CV_16S, 1, 0);//Scharr边缘检测算法X方向,Sobel功能一样

   Scharr(ScrImgaeCopy1,OutImage2, CV_16S, 0, 1);//Scharr边缘检测算法Y方向,Sobel功能一样

   addWeighted(OutImage1,0.5, OutImage2, 0.5, 0, OutImage);//Sobel边缘检测算法X方向和Y方向加起来

   convertScaleAbs(OutImage,OutImage);//计算绝对值,并将结果转换成8

   imshow("Scharr边缘检测算法X+Y", OutImage);

 

三、完整程序示例

#include <opencv2/core/core.hpp>

#include <opencv2/imgproc/imgproc.hpp>

#include <opencv2/opencv.hpp>

 

#include <vector>

#include <cstdio>

 

using namespacestd;

using namespacecv;

 

int main()

{

   Mat ScrImage, ScrImgaeCopy1, OutImage, OutImage1, OutImage2,OutImage3, OutImage4, OutImage5, OutImage6, OutImage7, OutImage8, OutImage9;

   ScrImage = imread("E:\\1TJQ\\Opencv\\Images\\image1.jpg");//读入图像 \\image1.jpg brownbug.jpg

 

   imshow("【原图】", ScrImage);

 

   ScrImgaeCopy1 =ScrImage.clone();              //将源图像复制

   //cvtColor(ScrImage, ScrImgaeCopy1, CV_RGB2GRAY);    //将源图像转换为灰度图像

   //imshow("【原图灰度图】", ScrImgaeCopy1);

 

   //GaussianBlur(ScrImage, ScrImgaeCopy1, Size(3, 3),0, 0);//高斯滤波

   //bilateralFilter(ScrImage, ScrImgaeCopy1, -1, 21,21);//双边滤波

   /*blur(ScrImage, ScrImgaeCopy1, Size(3, 3));      //均值滤波

 

   Canny(ScrImgaeCopy1,OutImage1, 150, 50, 3);      //Canny边缘检测算法

   Canny(ScrImage,OutImage2, 150, 50, 3);        //Canny边缘检测算法

   OutImage =OutImage1 - OutImage2;*/

 

   //Sobel(ScrImage, OutImage3, CV_16S, 1, 1, 3);    //Sobel边缘检测算法

   //convertScaleAbs(OutImage3, OutImage7);       //将像素值转换到uchar8类型

   Sobel(ScrImgaeCopy1,OutImage3, CV_16S, 1, 0, 3);//Sobel边缘检测算法X方向

   convertScaleAbs(OutImage3,OutImage4);

   Sobel(ScrImgaeCopy1,OutImage3, CV_16S, 0, 1, 3);//Sobel边缘检测算法Y方向

   convertScaleAbs(OutImage3,OutImage5);

   addWeighted(OutImage4,0.5, OutImage5, 0.5, 0, OutImage6); //Sobel边缘检测算法X方向和Y方向加起来注意:要分别对X方向和Y方向进行操作,效果才好。不能一起操作

  

   Laplacian(ScrImgaeCopy1,OutImage7, CV_16S, 3);     //Lapacian边缘检测算法,基于Sobel边缘检测算法为基础

   convertScaleAbs(OutImage7,OutImage7);            //计算绝对值,并将结果转换成8

  

   Scharr(ScrImgaeCopy1,OutImage1, CV_16S, 1, 0);     //Scharr边缘检测算法X方向,Sobel功能一样

   Scharr(ScrImgaeCopy1,OutImage2, CV_16S, 0, 1);     //Scharr边缘检测算法Y方向,Sobel功能一样

   addWeighted(OutImage1,0.5, OutImage2, 0.5, 0, OutImage);  //Sobel边缘检测算法X方向和Y方向加起来

   convertScaleAbs(OutImage,OutImage);           //计算绝对值,并将结果转换成8

 

   /*imshow("Canny边缘检测算法+均值滤波", OutImage1);

   imshow("Canny边缘检测算法-均值滤波", OutImage2);

   imshow("不加均值滤波差异", OutImage);*/

   imshow("Sobel边缘检测算法X",OutImage4);

   imshow("Sobel边缘检测算法Y",OutImage5);

   imshow("Sobel边缘检测算法X+Y",OutImage6);

  

   imshow("Laplacian边缘检测算法", OutImage7);

  

   imshow("Scharr边缘检测算法X+Y", OutImage);

 

   waitKey(0);

   return NULL;

}


参考内容:

http://www.cnblogs.com/mq0036/p/5902104.html

阅读全文
0 0