基于MATLAB的腐蚀膨胀算法实现

  本篇文章要分享的是基于MATLAB的腐蚀膨胀算法实现,腐蚀膨胀是形态学图像处理的基础,腐蚀在二值图像的基础上做“收缩”或“细化”操作,膨胀在二值图像的基础上做“加长”或“变粗”的操作。

  什么是二值图像呢?把一幅图片看做成一个二维的数组,那么二值图像是一个只有0和1的逻辑数组,我们前面Sobel边缘检测后的图像输出边缘效果,设置个阈值,大于阈值输出为1,小于阈值输出为0,最后输出就是一幅二维图像了。

腐蚀

  腐蚀是一种消除边界点,使边界向内部收缩的过程。可以用来消除小且无意义的物体。用3X3的结构元素,扫描图像的每一个像素,用结构元素与其覆盖的二值图像做“与”操作,如果都为1,结果图像的该像素为1。否则为0。结果会使二值图像小一圈。

  有一个形象的比喻来可以说明该运算,用0表示蛀虫,1表示大米。蛀虫腐蚀大米的过程便是腐蚀运算,

腐蚀

  如图所示,对于一个像素矩阵而言,只要有蛀虫(0)的存在,大米(1)就会被腐蚀掉了,即使只存在一个蛀虫(0),但是还是会被蛀虫腐蚀完毕,最后一幅图上面由于没有蛀虫(0)所以大米完好无损。

关于算法的实现,可以用下式子来表示,即3x3像素的运算:

P = P11 & P12 & P13 & P21 & P22 & P23 & P31 & P32 & P33

在FPGA中,为了通过面积去换速度,我们将上式改变如下:                       

P1 = P11 & P12 & P13

P2 = P21 & P22 & P23

P3 = P31 & P32 & P33

P = P1 & P2 & P3

MATLAB中可以直接写一个按位或运算。

膨胀

  膨胀是将与物体接触的所有背景点合并到该物体中,使边界向外部扩张的过程。可以用来填补物体中的空洞。用3X3的结构元素,扫描图像的每一个像素,用结构元素与其覆盖的二值图像做“与”操作,如果都为0,结果图像的该像素为0,。否则为1。结果使二值图像扩大一圈。

  先腐蚀后膨胀的过程称为开运算。用来消除小物体、在纤细点处分离物体、平滑较大物体的边界的同时并不明显的改变其面积。先膨胀后腐蚀的过程称为比运算,用来填充物体内细小空间、连接邻近物体、平滑其边界的同时并不明显改变其面积。

  膨胀算法用最简单的比喻来描述:0表示害虫,1表示青蛙,青蛙吃了害虫表示膨胀运算,我们用3*3像素阵列来解释:

膨胀

  如图所示,图左只有害虫(0),所以害虫都活着,中间那个图,虽然只有一个害虫,但是还是会被青蛙全部吃掉,最右边的那幅图,都是青蛙,所以青蛙始终是青蛙。

关于算法的实现,可以用下式子来表示,即3x3像素的运算:

P = P11 | P12 | P13 | P21 | P22 | P23 | P31 | P32 | P33

在HDL中,为了通过面积去换速度,我们将上式改变如下:                             

P1 = P11 | P12 | P13

P2 = P21 | P22 | P23

P3 = P31 | P32 | P33

P = P1 | P2 | P3

MATLAB中可以直接写一个按位与运算。

开运算闭运算

  先腐蚀后膨胀叫开运算,开运算的作用是清除图像边缘周围非边缘的细小的点。先膨胀后腐蚀为闭运算,闭运算的作用是清除图像内部的空洞,

  如果我们的目标物体外面有很多无关的小区域,就用开运算去除掉;如果物体内部有很多小黑洞,就用闭运算填充掉。

MATLAB逻辑运算函数

bitand(), 对十进制数进行逐位逻辑与运算:先将十进制数转换成二进制数,然后逐位与运算,其运算结果转换为十进制。

bitor(), 对十进制数进行逐位逻辑或运算:先将十进制数转换成二进制数,然后逐位与运算,其运算结果转换为十进制。

MATLAB代码实现

  1 %RGB_YCbCr
  2 clc;
  3 clear all;
  4 close all;
  5
  6 RGB_data = imread(‘lena.jpg‘);
  7
  8 R_data =    RGB_data(:,:,1);
  9 G_data =    RGB_data(:,:,2);
 10 B_data =    RGB_data(:,:,3);
 11
 12 %imshow(RGB_data);
 13
 14 [ROW,COL, DIM] = size(RGB_data);
 15
 16 Y_data = zeros(ROW,COL);
 17 Cb_data = zeros(ROW,COL);
 18 Cr_data = zeros(ROW,COL);
 19 Gray_data = RGB_data;
 20
 21 for r = 1:ROW
 22     for c = 1:COL
 23         Y_data(r, c) = 0.299*R_data(r, c) + 0.587*G_data(r, c) + 0.114*B_data(r, c);
 24         Cb_data(r, c) = -0.172*R_data(r, c) - 0.339*G_data(r, c) + 0.511*B_data(r, c) + 128;
 25         Cr_data(r, c) = 0.511*R_data(r, c) - 0.428*G_data(r, c) - 0.083*B_data(r, c) + 128;
 26     end
 27 end
 28
 29 Gray_data(:,:,1)=Y_data;
 30 Gray_data(:,:,2)=Y_data;
 31 Gray_data(:,:,3)=Y_data;
 32
 33 figure;
 34 imshow(Gray_data);
 35
 36 %Median Filter
 37 imgn = imnoise(Gray_data,‘salt & pepper‘,0.02);
 38
 39 figure;
 40 imshow(imgn);
 41
 42 Median_Img = Gray_data;
 43 for r = 2:ROW-1
 44     for c = 2:COL-1
 45         median3x3 =[imgn(r-1,c-1)    imgn(r-1,c) imgn(r-1,c+1)
 46                     imgn(r,c-1)      imgn(r,c)      imgn(r,c+1)
 47                     imgn(r+1,c-1)      imgn(r+1,c) imgn(r+1,c+1)];
 48         sort1 = sort(median3x3, 2, ‘descend‘);
 49         sort2 = sort([sort1(1), sort1(4), sort1(7)], ‘descend‘);
 50         sort3 = sort([sort1(2), sort1(5), sort1(8)], ‘descend‘);
 51         sort4 = sort([sort1(3), sort1(6), sort1(9)], ‘descend‘);
 52         mid_num = sort([sort2(3), sort3(2), sort4(1)], ‘descend‘);
 53         Median_Img(r,c) = mid_num(2);
 54     end
 55 end
 56
 57 figure;
 58 imshow(Median_Img);
 59
 60 %Sobel_Edge_Detect
 61
 62 Median_Img = double(Median_Img);
 63 Sobel_Threshold = 150;
 64 Sobel_Img = zeros(ROW,COL);
 65
 66 for r = 2:ROW-1
 67     for c = 2:COL-1
 68         Sobel_x = Median_Img(r-1,c+1) + 2*Median_Img(r,c+1) + Median_Img(r+1,c+1) - Median_Img(r-1,c-1) - 2*Median_Img(r,c-1) - Median_Img(r+1,c-1);
 69         Sobel_y = Median_Img(r-1,c-1) + 2*Median_Img(r-1,c) + Median_Img(r-1,c+1) - Median_Img(r+1,c-1) - 2*Median_Img(r+1,c) - Median_Img(r+1,c+1);
 70         Sobel_Num = abs(Sobel_x) + abs(Sobel_y);
 71         %Sobel_Num = sqrt(Sobel_x^2 + Sobel_y^2);
 72         if(Sobel_Num > Sobel_Threshold)
 73             Sobel_Img(r,c)=255;
 74         else
 75             Sobel_Img(r,c)=0;
 76         end
 77     end
 78 end
 79
 80 figure;
 81 imshow(Sobel_Img);
 82
 83 %imopen Erosion_Dilation
 84 %Erosion
 85 % Erosion_img = zeros(ROW,COL);
 86 % for r = 2:ROW-1
 87     % for c = 2:COL-1
 88         % and1 = bitand(Sobel_Img(r-1, c-1), bitand(Sobel_Img(r-1, c), Sobel_Img(r-1, c+1)));
 89         % and2 = bitand(Sobel_Img(r, c-1), bitand(Sobel_Img(r, c), Sobel_Img(r, c+1)));
 90         % and3 = bitand(Sobel_Img(r+1, c-1), bitand(Sobel_Img(r+1, c), Sobel_Img(r+1, c+1)));
 91         % Erosion_img(r, c) = bitand(and1, bitand(and2, and3));
 92     % end
 93 % end
 94
 95 % figure;
 96 % imshow(Erosion_img);
 97
 98 % %Dilation
 99 % Dilation_img = zeros(ROW,COL);
100 % for r = 2:ROW-1
101     % for c = 2:COL-1
102         % or1 = bitor(Erosion_img(r-1, c-1), bitor(Erosion_img(r-1, c), Erosion_img(r-1, c+1)));
103         % or2 = bitor(Erosion_img(r, c-1), bitor(Erosion_img(r, c), Erosion_img(r, c+1)));
104         % or3 = bitor(Erosion_img(r+1, c-1), bitor(Erosion_img(r+1, c), Erosion_img(r+1, c+1)));
105         % Dilation_img(r, c) = bitor(or1, bitor(or2, or3));
106     % end
107 % end
108
109 % figure;
110 % imshow(Dilation_img);
111
112 %imclose Erosion_Dilation
113 %Dilation
114 Dilation_img = zeros(ROW,COL);
115 for r = 2:ROW-1
116     for c = 2:COL-1
117         or1 = bitor(Sobel_Img(r-1, c-1), bitor(Sobel_Img(r-1, c), Sobel_Img(r-1, c+1)));
118         or2 = bitor(Sobel_Img(r, c-1), bitor(Sobel_Img(r, c), Sobel_Img(r, c+1)));
119         or3 = bitor(Sobel_Img(r+1, c-1), bitor(Sobel_Img(r+1, c), Sobel_Img(r+1, c+1)));
120         Dilation_img(r, c) = bitor(or1, bitor(or2, or3));
121     end
122 end
123
124 figure;
125 imshow(Dilation_img);
126
127 %Erosion
128 Erosion_img = zeros(ROW,COL);
129 for r = 2:ROW-1
130     for c = 2:COL-1
131         and1 = bitand(Dilation_img(r-1, c-1), bitand(Dilation_img(r-1, c), Dilation_img(r-1, c+1)));
132         and2 = bitand(Dilation_img(r, c-1), bitand(Dilation_img(r, c), Dilation_img(r, c+1)));
133         and3 = bitand(Dilation_img(r+1, c-1), bitand(Dilation_img(r+1, c), Dilation_img(r+1, c+1)));
134         Erosion_img(r, c) = bitand(and1, bitand(and2, and3));
135     end
136 end
137
138 figure;
139 imshow(Erosion_img);

处理后结果对比

为了可以清晰的看到图像边缘的变化,我们把黑色作为背景,白色作为边缘。

Sobel边缘检测后的lena

腐蚀后的lena

膨胀后的lena

先腐蚀后膨胀开运算lena

先膨胀后腐蚀闭运算lena

  从上面两幅图可以看出,腐蚀后的图像边缘明显变细,消除了更多假边缘,在腐蚀基础上使用膨胀算法的lena将腐蚀后的边缘扩大、加粗,这样看起来更清楚。

转载请注明出处:NingHeChuan(宁河川)

个人微信订阅号:开源FPGA

如果你想及时收到个人撰写的博文推送,可以扫描左边二维码(或者长按识别二维码)关注个人微信订阅号

知乎ID:NingHeChuan

微博ID:NingHeChuan

原文地址:https://www.cnblogs.com/ninghechuan/p/9527915.html

原文地址:https://www.cnblogs.com/ninghechuan/p/9530964.html

时间: 2024-10-24 16:22:30

基于MATLAB的腐蚀膨胀算法实现的相关文章

基于FPGA的腐蚀膨胀算法实现

本篇文章我要写的是基于的腐蚀膨胀算法实现,腐蚀膨胀是形态学图像处理的基础,,腐蚀在二值图像的基础上做"收缩"或"细化"操作,膨胀在二值图像的基础上做"加长"或"变粗"的操作.那么什么是二值图像呢?把一幅图片看做成一个二维的数组,那么二值图像是一个只有0和1的逻辑数组,我们前面Sobel边缘检测后的图像输出边缘效果,设置个阈值,大于阈值输出为1,小于阈值输出为0,最后输出就是一幅二维图像了. 上一篇我是直接用MATLAB处理后的

数学软件 之 基于MATLAB的DFP算法

DFP算法是本科数学系中最优化方法的知识,也是无约束最优化方法中非常重要的两个拟Newton算法之一,上一周写了一周的数学软件课程论文,姑且将DFP算法的实现细节贴出来分享给学弟学妹参考吧,由于博客不支持数学公式,所以就不累述算法原理及推倒公式了. DFP算法流程图 先给出DFP算法迭代流程图,总体上是拟Newton方法的通用迭代步骤,唯独在校正公式的地方有所区别. MATLAB实现DFP 基于此图便可以设计DFP算法的MATLAB程序: 对分法及加步探索法的实现 首先由于DFP算法中需要利用一

基于matlab mex的平面点集按重心逆时针排序算法

基于matlab mex的平面点集按重心逆时针排序算法,可用于求凸集,代码如下: #include <mex.h> #include <mat.h> #include <stdlib.h> #include <vector> #include <algorithm> using namespace std; typedef struct PointF { int id; double x, y; PointF() { id = -1; } Poi

图像处理——灰度化、二值化、膨胀算法、腐蚀算法以及开运算和闭运算

一.RGB RGB色彩模式使用RGB模型为图像中每个像素的RGB分量分配一个0~255范围内的强度值.RGB图像仅仅使用三种颜色,R(red).G(green).B(blue),就能够使它们依照不同的比例混合,在屏幕上呈现16777216(256 * 256 * 256)种颜色. 在电脑中,RGB的所谓"多少"就是指亮度,并使用整数来表示.通常情况下,RGB各有256级亮度,用数字表示为从0.1.2...直到255. 二.ARGB 一种色彩模式,也就是RGB色彩模式附加上Alpha(透

基于MeanShift的目标跟踪算法及实现

一.简介 首先扯扯无参密度估计理论,无参密度估计也叫做非参数估计,属于数理统计的一个分支,和参数密度估计共同构成了概率密度估计方法.参数密度估计方法要求特征空间服从一个已知的概率密度函数,在实际的应用中这个条件很难达到.而无参数密度估计方法对先验知识要求最少,完全依靠训练数据进行估计,并且可以用于任意形状的密度估计.所以依靠无参密度估计方法,即不事先规定概率密度函数的结构形式,在某一连续点处的密度函数值可由该点邻域中的若干样本点估计得出.常用的无参密度估计方法有:直方图法.最近邻域法和核密度估计

基于大数据技术推荐系统算法案例实战视频教程(项目实战)

38套大数据,云计算,架构,数据分析师,Hadoop,Spark,Storm,Kafka,人工智能,机器学习,深度学习,项目实战视频教程 视频课程包含: 38套大数据和人工智能精品高级课包含:大数据,云计算,架构,数据挖掘实战,实时推荐系统实战,电视收视率项目实战,实时流统计项目实战,离线电商分析项目实战,Spark大型项目实战用户分析,智能客户系统项目实战,Linux基础,Hadoop,Spark,Storm,Docker,Mapreduce,Kafka,Flume,OpenStack,Hiv

基于傅里叶变换的音频重采样算法 (附完整c代码)

前面有提到音频采样算法: WebRTC 音频采样算法 附完整C++示例代码 简洁明了的插值音频重采样算法例子 (附完整C代码) 近段时间有不少朋友给我写过邮件,说了一些他们使用的情况和问题. 坦白讲,我精力有限,但一般都会抽空回复一下. 大多数情况,阅读一下代码就能解决的问题, 也是要尝试一下的. 没准,你就解决了呢? WebRtc的采样算法本身就考虑到它的自身应用场景, 所以它会有一些局限性,例如不支持任意采样率等等. 而简洁插值的这个算法, 我个人也一直在使用,因为简洁明了,简单粗暴. 我自

基于位置信息的聚类算法介绍及模型选择

百度百科 聚类:将物理或抽象对象的集合分成由类似的对象组成的多个类的过程被称为聚类.由聚类所生成的簇是一组数据对象的集合,这些对象与同一个簇中的对象彼此相似,与其他簇中的对象相异."物以类聚,人以群分",在自然科学和社会科学中,存在着大量的分类问题.聚类分析又称群分析,它是研究(样品或指标)分类问题的一种统计分析方法.聚类分析起源于分类学,但是聚类不等于分类.聚类与分类的不同在于,聚类所要求划分的类是未知的. 分类和聚类算法一直以来都是数据挖掘,机器学习领域的热门课题,因此产生了众多的

基于matlab的音频波形实时采集显示 v0.1

robj = audiorecorder(44100,16,1); %设置采样频率.采样位数.通道数 recordblocking(robj,1); %采集初步数据(1s长度) rdata = getaudiodata(robj); %获取音频数据 plot(rdata); %绘制波形 axis([1,44100,-0.1,0.1]); %设置固定坐标轴 drawnow %刷新显示 n = 100; %设定后续的采样更新次数,n与m可联合计算后续更新时间长度 m = 0.1; %设定更新间隔,m