博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
opencv(10)图像变换之边缘检测
阅读量:6821 次
发布时间:2019-06-26

本文共 2436 字,大约阅读时间需要 8 分钟。

1.

 

sobel算子利用多项式计算导数的近似值,其计算公式和3*3模版如下,sobel算子结合了一些滤波的效果,对噪声有一定的鲁棒性。

opencv提供了进行sobel算子的函数,函数如下:

void cvSobel( const CvArr* src, CvArr* dst, int xorder, int yorder, int aperture_size=3 );

src :输入图像. 单通道,8位或者浮点

dst: 输出图像. 单通道,如果是8位图像,为了防止溢出,输出必须是IPL_DEPTH_16S类型

xorder:  x 方向上的差分阶数

yorder : y 方向上的差分阶数  可以是0 1 2
aperture_size  :扩展 Sobel 核的大小,必须是 1, 3, 5 或 7。 除了尺寸为 1, 其它情况下, aperture_size ×aperture_size 可分离内核将用来计算差分。对 aperture_size=1的情况, 使用 3x1 或 1x3 内核 (不进行高斯平滑操作)。这里有一个特殊变量 CV_SCHARR (=-1),对应 3x3 Scharr 滤波器,可以给出比 3x3 Sobel 滤波更精确的结果。

 

sobel算子使用大核计算到导数更加的逼近,小核对噪声更加敏感,当计算X,Y方向的梯度的时候,精确度还可以,但是使用Y/X计算图像梯度方向的时候,精度就很差,尤其是小核的时候。所以opencv提供了scharr滤波器来解决这个问题,计算梯度的准确率会比sobel 3*3的效果好。

 

2.

拉普拉斯算子的是对拉普拉斯函数的离散模拟,函数形式如下,opencv中利用二次sobel算子来实现,先利用sobel算子计算X Y方向的差分,然后再求和。

 

opencv中的实现函数:

void cvLaplace( const CvArr* src, CvArr* dst, int aperture_size=3 );参数和cvsobel函数类似。注意的拉普莱斯中对过零问题做了处理,将二阶差分为0 ,一阶差分算子响应低的边缘点滤除掉。3.void cvCanny( const CvArr* image, CvArr* edges, double threshold1,double threshold2, int aperture_size=3 );canny的步骤如下step1:用高斯滤波器平滑图象;step2:用一阶偏导的有限差分来计算梯度的幅值和方向;step3:对梯度幅值进行非极大值抑制;

step4:用双阈值算法检测和连接边缘。image:canny只接受单通道图像double threshold1,double threshold2为canny算子中采用的两个最大阈值和最小阈值,一个像素的梯度大于最大阈值被认定为边缘,如果小于最小阈值则被抛弃,如果介于二者之间,主要当期与高于上限阈值的连接时才会被认定为接受。也可以采用自适应的阈值算法,可以参考:aperture:计算一阶偏导的时候opencv采用sobel算子,这个参数为sobel的内核大小。默认为3*3

 
 

测试代码:

1: IplImage *Image1;
2: Image1 = cvLoadImage("7.jpg");
3: IplImage *ImageGray = cvCreateImage(cvGetSize(Image1),IPL_DEPTH_8U,1);
4: IplImage *SobelDstImg= cvCreateImage(cvGetSize(Image1),IPL_DEPTH_16S,1);
5: IplImage *ImageGray2 = cvCreateImage(cvGetSize(Image1),IPL_DEPTH_8U,1);
6: cvCvtColor(Image1,ImageGray,CV_BGR2GRAY);
7: 
8: cvNamedWindow("src");
9: cvShowImage("src",ImageGray);
10: 
11: cvSobel(ImageGray,SobelDstImg,1,1,3 );
12: cvConvertScaleAbs(SobelDstImg,ImageGray2);
13: 
14: cvNamedWindow("sobel");
15: cvShowImage("sobel",ImageGray2);
16: 
17: cvLaplace(ImageGray,SobelDstImg,3);
18: cvConvertScaleAbs(SobelDstImg,ImageGray2);
19: 
20: cvNamedWindow("Laplace");
21: cvShowImage("Laplace",ImageGray2);
22: 
23: cvCanny(ImageGray,ImageGray2,50,100,3);
24: 
25: cvNamedWindow("Canny");
26: cvShowImage("Canny",ImageGray2);
27: 
28: cvCanny(ImageGray,ImageGray2,100,150,3);
29: 
30: cvNamedWindow("Canny2");
31: cvShowImage("Canny2",ImageGray2);
32: 
33: cvWaitKey();

测试图像:

 

 

sobel检测效果没有canny好,拉普拉斯产生了双边缘,canny不同的阈值得到的结果也有很大的差别。

转载于:https://www.cnblogs.com/zsb517/archive/2012/06/19/2554212.html

你可能感兴趣的文章
一张图说明Linux启动过程
查看>>
Provider处理请求逻辑梳理
查看>>
我的友情链接
查看>>
查看当前服务链接数
查看>>
Open-Falcon 互联网企业级监控系统解决方案(2)
查看>>
抄录一份linux哲学思想
查看>>
DBLIKE创建命令
查看>>
cesiumjs开发实践(五) 坐标变换
查看>>
明明白白学C#第0章准备工作
查看>>
Xamarin.Forms单元控件Cell
查看>>
Linux下MySQL备份以及crontab定时备份
查看>>
Exchange 2016和 O365 混合部署系列三之混合配置
查看>>
shell脚本生成服务演示服务启动、停止过程。
查看>>
CentOS 7.4 Tengine安装配置详解(二)
查看>>
C#日期格式化
查看>>
H3C FlexStorage P5730服务器数据恢复初检报告
查看>>
Linux内核源码各目录功能说明
查看>>
redhat 6.5 kvm 虚拟化(好久没更新了...)
查看>>
联想E430C笔记本Ubuntu系统换Win7系统
查看>>
实验15:静态路由的设置及相关命令
查看>>