打印
[STM32F4]

【STM32F469I试用】sobel滤波

[复制链接]
1474|11
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
关于emwin的显示,lcd的使用什么的,我就不废话了,st的板子都一样,另外论坛也有了大量的写的很优秀的入门**

Sobel算子是一种一阶微分算子,主要用于获得数字图像的一阶梯度,常见的应用和物理意义是边缘检测。它是一种计算机视觉领域的重要方法。
如下图所示,对lena提取的边缘图像


对于应用如此广泛的sobel,奇怪的是,竟然没有一篇正是的论文发表,而且各个来源出去也不一样。
原来,这个著名的Sobel边缘算子,当年作者并没有公开发表过论文,仅仅是在一次博士生课题讨论会(1968)上提出("A 3x3 Isotropic Gradient Operator for Image Processing"),后在1973年出版的一本专著("Pattern Classification and Scene Analysis")的脚注里作为注释出现和公开的【1】
【1】An Isotropic 3 3 Image Gradient Operator .Research gate.2010-04-9[引用日期2014-08-10]


在讨论边缘算子之前,首先给出一些术语的定义:

l (1)边缘:灰度或结构等信息的突变处,边缘是一个区域的结束,也是另一个区域的开始,利用该特征可以分割图像。

l (2)边缘点:图像中具有坐标[x,y],且处在强度显著变化的位置上的点。

l (3)边缘段:对应于边缘点坐标[x,y]及其方位 ,边缘的方位可能是梯度角。


梯度算子为什么能够检测边缘

在网络上暂时没找到更详细的阐述,我写一下我自己的理解

函数的极值求解微分为0,那么在极值点前后必然经历一次灰度的跃变,比如由白色突然转向黑色,而这也就是我们所要找的边缘。

梯度方向是变化最快的方向

梯度大小,是xy两个方向的2范数。



那么sobel利用加权差分的做法来实现微分运行,图像的不连续性



于是可以得到卷积模板


一个x方向,一个y方向。

在简述一下过程


用模板卷积的方式来实现对x方向和y方向的差分求解。

然后求得梯度大小和方向。


当梯度大小>一个阈值,那么判定为边缘,否则不是边缘



在上篇**的基础上。读取bmp图片,然后转换成灰度图像,计算sobel算子边缘结果,显示出来,代码


如果不想显示灰度的sobel,想试试彩色图片的sobel呢,当然可以,用r、g、b分量分别计算。然后显示,那么就是彩色的了。代码


如果对仅仅x,y方向两个方向不满足,想要更多方向的微分计算,当然也可以,将模板旋转一下就可以,代码没有

沙发
hwl1023| | 2016-1-8 09:48 | 只看该作者
感谢楼主分享!

使用特权

评论回复
板凳
wejoncy|  楼主 | 2016-1-8 10:19 | 只看该作者
hwl1023 发表于 2016-1-8 09:48
感谢楼主分享!

多谢支持

使用特权

评论回复
地板
mmuuss586| | 2016-1-8 13:47 | 只看该作者

牛人;

使用特权

评论回复
5
Varus| | 2016-1-8 17:18 | 只看该作者
C代码

/* Sobel template
a00 a01 a02
a10 a11 a12
a20 a21 a22
*/
unsigned char a00, a01, a02;
unsigned char a10, a11, a12;
unsigned char a20, a21, a22;
void MySobel(IplImage* gray, IplImage* gradient)
{
CvScalar color ;
for (int i=1; i<gray->height-1; ++i)
{
for (int j=1; j<gray->width-1; ++j)
{
a00 = cvGet2D(gray, i-1, j-1).val[0];
a01 = cvGet2D(gray, i-1, j).val[0];
a02 = cvGet2D(gray, i-1, j+1).val[0];
a10 = cvGet2D(gray, i, j-1).val[0];
a11 = cvGet2D(gray, i, j).val[0];
a12 = cvGet2D(gray, i, j+1).val[0];
a20 = cvGet2D(gray, i+1, j-1).val[0];
a21 = cvGet2D(gray, i+1, j).val[0];
a22 = cvGet2D(gray, i+1, j+1).val[0];
// x方向上的近似导数
double ux = a20 * (1) + a21 * (2) + a22 * (1)
+ (a00 * (-1) + a01 * (-2) + a02 * (-1));
// y方向上的近似导数
double uy = a02 * (1) + a12 * (2) + a22 * (1)
+ a00 * (-1) + a10 * (-2) + a20 * (-1);
color.val[0] = sqrt(ux*ux + uy*uy);
cvSet2D(gradient, i, j, color);
}
}
}
//注释:该程序需要在安装Opencv软件下运行。
Matlab
ps=imread('D:\14.jpg'); %读取图像
subplot(1,3,1)
imshow(ps);
title('原图像');
ps=rgb2gray(ps);
[m,n]=size(ps); %用Sobel微分算子进行边缘检测
pa = edge(ps,'sobel');
subplot(1,3,2);
imshow(pa);
title('Sobel边缘检测得到的图像');

使用特权

评论回复
6
colin2135| | 2016-1-24 15:08 | 只看该作者
本帖最后由 colin2135 于 2016-1-25 09:48 编辑

:):):):):):):):):)算了不讨论,新年快乐

使用特权

评论回复
7
colin2135| | 2016-1-24 15:09 | 只看该作者
本帖最后由 colin2135 于 2016-1-25 09:48 编辑

undefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefined算了不讨论,新年快乐

使用特权

评论回复
8
wejoncy|  楼主 | 2016-1-25 08:53 | 只看该作者
colin2135 发表于 2016-1-24 15:08
你这帖子跟F469并有什么关系,你有移植上去吗? C代码用的也是OPENCV的库,STM32并不能支持OPNECV的库。

...

多谢你的评论,但是,也先请你看清楚,我哪里说到了opencv

我只是先把滤波原理说清楚,然后自己用c代码在469上实现

使用特权

评论回复
9
colin2135| | 2016-1-25 09:34 | 只看该作者
本帖最后由 colin2135 于 2016-1-25 09:46 编辑

:):):):):):):):):)算了不讨论,新年快乐。

使用特权

评论回复
10
wejoncy|  楼主 | 2016-1-25 09:43 | 只看该作者
colin2135 发表于 2016-1-25 09:34
你的C代码:CvScalar color ;
for (int i=1; iheight-1; ++i)
{

额,我不知道你从哪里看到这是我的代码。但这确实不是我写的,我写的在文中有超链接的蓝体字给出

使用特权

评论回复
11
wahahaheihei| | 2016-1-25 13:21 | 只看该作者
)边缘:灰度或结构等信息的突变处,边缘是一个区域的结束,也是另一个区域的开始,利用该特征可以分割图像。

使用特权

评论回复
12
auv555| | 2016-1-25 14:15 | 只看该作者
不错 谢谢分享

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

15

主题

168

帖子

3

粉丝