【MATLAB源码】机器视觉与图像识别技术(3)—数字形态学处理以及图像特征点提取

系列文章目录

第一篇文章: 【MATLAB源码】机器视觉与图像识别技术---视觉系统的构成(视频与图像格式转换代码及软件下载)

第二篇文章: 【MATLAB源码】机器视觉与图像识别技术(2)---图像分割基础

第三篇文章: 【MATLAB源码】机器视觉与图像识别技术(2)续---图像分割算法


数字形态学处理以及图像特征点提取

概述

在图像预处理之后,数字形态学处理和图像特征提取步骤随之进行。数字形态学处理主要是基于形态学理论对图像进行形态变换,以提取图像的结构特征和形状信息。常用的形态学操作包括腐蚀、膨胀、开运算和闭运算。腐蚀操作用于去除图像中的噪声和细小物体,膨胀操作则用于填补图像中的小孔和连接断裂的物体。开运算和闭运算分别是腐蚀和膨胀的组合,用于平滑图像轮廓和去除小物体及细小连接。在完成形态学处理后,图像特征提取是接下来的关键步骤。特征提取旨在从图像中识别出具有显著性和稳定性的特征信息,这些特征在后续的图像匹配、物体识别和图像拼接中起着至关重要的作用。常见的特征提取方法包括Harris角点检测、尺度不变特征变换(SIFT)和加速稳健特征(SURF)等。Harris角点检测通过计算图像的梯度信息来识别角点,SIFT和SURF则通过构建图像金字塔和计算局部特征向量来提取尺度和旋转不变的特征。

综合来说,数字形态学处理和图像特征提取的结合应用能够有效增强图像的可用性和信息量,为后续的图像分析和计算提供坚实的基础。这些操作不仅提升了图像的清晰度和连贯性,还确保了特征的准确性和稳定性,从而大大提高了图像处理和计算机视觉任务的效率和效果。下面我将介绍关于这些操作的MATLAB函数的运用。


一、基本函数认了解

声明:在MATLAB中,形态学操作的函数主要用于处理二值图像和灰度图像。

1.形态学操作函数

(1)腐蚀(imerode):用于对图像进行腐蚀操作,通过结构元素(strel)对图像中的对象进行缩小,从而去除噪声和细小的物体边界。

(2)膨胀(imdilate)用于对图像进行膨胀操作,通过结构元素对图像中的对象进行扩展,填补小孔和连接断裂的物体。

(3)开运算(imopen)先腐蚀后膨胀操作,通常用于去除小的物体和噪声,同时保留图像的大体结构。

(4)闭运算(imclose)先膨胀后腐蚀操作,常用于填补图像中的小孔和连接断开的区域,同时平滑图像边缘。( :开运算和闭运算属于对偶运算)

(5)填充孔洞(imfill,低版本的是bwfill)用于填充二值图像中的孔洞,使得对象变得更加连贯和完整。

(6)计算欧拉数(bweuler):计算二进制图像的欧拉数,图像中苏偶偶白色区域总数C与这些对象孔洞数H的运算关系为:欧拉数=C-H.

(7)提取轮廓(bwmorph)用于获取二值图像的轮廓,通过反复应用形态学操作提取图像的细化结构。这些形态学操作函数是图像处理中的基本工具,每个函数都可以根据具体应用需求调整参数,以实现最佳效果。

(8)bwperim:用于计算二值图像中对象的周边像素,返回一个与输入图像大小相同的二值图像,其中周边像素值为1,其余像素值为0。这一函数常用于提取图像中对象的轮廓周长。

(9)bwarea用于计算二值图像中所有对象的像素总数,即对象的面积。该函数返回一个标量值,表示图像中所有对象的总面积。

备注:结构元素SE=strel();其中常用三种结构:

1.圆盘结构strel('disk',n);n为结构程度

2.矩形结构strel('rectangle',[10 5]);[]表示圆滑的矩形长和宽;

3.线长形strel('line',5,0)5为长度,0为线角度

剩下的可以用help 命令来查看,就不一一展示了.

2.特征提取函数

在MATLAB中,regionprops() 函数用于测量图像区域的属性,是图像分析中的重要工具。该函数接受二值图像或标签矩阵作为输入,并返回一个结构数组,其中每个元素包含一个图像区域的特定属性信息。这些属性包括面积、周长、质心、边界框、主要和次要轴长度、方向、圆形度、凸包、凸性、偏心率、等效直径、Euler数、图像、填充图像、极值值、像素列表、像素值、亚像素边界、子图像等。regionprops() 函数常用于目标检测、图像分割后区域分析和特征提取。通过测量区域属性,可以实现对图像中不同物体的形态学分析和分类。此函数在计算机视觉和图像处理应用中具有广泛用途,包括物体识别、计数、大小测量、形状分析等。它的灵活性和强大的功能使得在处理和分析复杂图像时非常有效。

二、使用介绍

1.形态学操作示例

以列车在轨道的操作给大家做一个示例说明,让大家看清楚这些函数的效果怎么样,下图是我选取的一张列车在轨道上的行驶图,对目标对象列车进行形态学操作.

经过一系列形态学操作的效果图如下,由于环境噪音非常大,影响了图片的质量,所以必要进行滤波处理。由图可以看出,腐蚀和膨胀操作的运算效果验证了,腐蚀可以消除边界点,是边界收缩,消除了一些没有意义的点,但是使得对象减小了一圈边缘,把白色区域变细了。而膨胀操作就是相反的操作,将物体接触的所有背景点合并入物体中,使得边界外阔,填补孔洞,增加一圈边缘。对偶运算中的开运算(imopen)和闭运算(imclose)效果就很明显了:

开操作作用如图所示,先腐蚀后膨胀,消除细小对象和连粘,平滑目标的边缘。而闭运算就是先膨胀后腐蚀,填充物体内细小的空洞,连接邻近的缝隙。

通过这些形态学操作,火车的轮廓在二值图像中变得更加明显和清晰。最终结果展示了这些形态学操作在图像处理中的有效性,使目标物体(火车)的特征更加突出,背景噪声显著减少,合理的就是开操作运算,效果较为理想。

代码如下(示例):

clc
clear all
close all
% 读取图像
a = imread('d:\z\252.jpg');
% 转换为灰度图像
b = rgb2gray(a);
% 应用中值滤波,使用 5x5 的滤波器
m = medfilt2(b, [5 5]);
% 将灰度图像转换为二值图像,阈值为 210/255
c = im2bw(m, 210/255);
% 填充二值图像中的孔洞
h = bwfill(c, 'holes');
% 定义半径为8的圆盘形结构元素
SE = strel('disk', 8);
% 腐蚀操作
L = imerode(h, SE);
% 膨胀操作
K = imdilate(h, SE);
% 闭运算(先膨胀后腐蚀)
G = imclose(h, SE);
% 开运算(先腐蚀后膨胀)
k = imopen(h, SE);
% 在一个窗口中显示所有结果
figure;
subplot(321)
imshow(a);
title("原始图像")
subplot(322)
imshow(b)
title("灰度图")
subplot(323)
imshow(L)
title("腐蚀后的二值图")
subplot(324)
imshow(K)
title("膨胀后的二值图")
subplot(325)
imshow(G)
title("进行闭操作的二值图")
subplot(326)
imshow(k)
title("进行开运算的二值图")

2.特征点提取示例

1.计算欧拉数函数bweuler(bw,n),其中n为连通域4或8。

2.计算周长函数bwperim(bw,n),同理就是n也是连通域,默认是4。

3.计算二值图面积bwarea(bw);

4.特征点的提取,语法:regionprops(bw,properties),其中properties表示特征量,输入的标注矩阵bw可以具有任意数值类型,一般常用二值数值矩阵,用help命令可以查到其量描述:如下图

其中我将通过help的命令找出来,翻译和把我的理解跟大家描述一下:
(1)'Area ':这是一个标量,表示图像中各个区域内像素的总数,有点跟计算面积相似。但是计算得到的该数值可能与函数 bwarea 计算的值略有不同,在模式识别中,一般用此计算当作某物体的特征点进行区分不同类。

(2)'BoundingBox ':这返回的是一个1*2列的向量,表示包含相应区域的最小矩形框。BoundingBox 的格式为 [ul_corner width],其中 ul_corner 以 [x y z ...] 的坐标形式给出边界框的左上角,boxwidth 以 [x_宽 y_width ...] 的形式表示边界框矩形的宽度及高度。

(3)'Centroid ':这返回的是一个1列的向量,表示每个区域的质心或者说(重心)的位置坐标。Centroid 的第一个元素表示质心的水平坐标(x坐标),第二个元素表示质心的垂直坐标(y坐标),其余元素按维度顺序排列。

(4) 'MajorAxisLength' :返回的是一个标量值,表示与区域具有相同标准二阶中心矩的椭圆的长轴长度(单位:像素),这是用于描述区域主要方向的一个特征。

(5)'MinorAxisLength ':同理,跟上面的相反,不过也是返回的是一个标量值,表示与区域具有相同标准二阶中心矩的椭圆的短轴长度(单位:像素),它表示区域的次要方向。

(6)'Eccentricity ':这是一个标量,表示与区域具有相同标准二阶中心矩的椭圆的离心率,这个标量反映了区域的椭圆形状,可以作为模式识别中的特征选取。

(7)'Orientation ':返回的是一个标量,表示与区域具有相同标准二阶中心矩的椭圆的长轴与x轴的夹角(以度数为单位),这个角度描述了椭圆的旋转方向。

(8)'Image ':返回一个二值图像,具有与某区域大小相同的逻辑矩阵。可以使用此属性直接提取和分析区域中的像素。

(9)'FilledImage ':与上面相似,不同之处在于这是填充后的逻辑矩阵!本例中与上面的没有区别,适用于处理区域内部有空洞的情况。

(10)'FilledArea ':返回一个标量,表示在填充区域图像中的on像素(即区域内像素)的总数。这个值显示了填充后区域的大小.

(11)'ConvexHull ':返回一个n行2列的矩阵,包含某区域的最小凸多边形。每一行存储该凸多边形的一个顶点的xy坐标。这个多边形可以用于分析区域的形状。

(12)'ConvexImage ':返回一个二值图像,用于绘制上述区域的最小凸多边形。并且凸包内的所有像素都被标记为on,图像尺寸与该区域的边界矩形相同。此属性仅支持二维标注矩阵,发现此处函数搭配 roipoly 很有效果!

(13)'ConvexArea ':返回一个标量,表示填充区域凸多边形图像中的on像素个数,相当于凸多边形的面积。

(14)'EulerNumber ':同样返回的是一个标量,几何拓扑中的一个拓扑不变量------欧拉数,等于图像中目标的数量减去这些目标中空洞的数量。此属性仅支持二维标注矩阵,返回的这个数值用于描述区域的拓扑结构。

(15)'Extrema ':返回一个8行2列的矩阵,记录区域在八个方向上的极值点。矩阵的每一行存储这些点的xy坐标,向量格式为 [top-left top-right right-top right-bottom bottom-right bottom-left left-bottom left-top]。

(16)'EquivDiameter ':返回一个标量,存储与区域具有相同面积的圆的直径。计算公式为:sqrt(4*Area/pi) 。它用于表示区域的等效直径,便于比较不同形状的区域。

(17)'Solidity ':返回一个标量,表示区域与其最小凸多边形中的像素比例。计算公式为:Area/ConvexArea,这个值反映了区域的紧实程度或固体程度

(18)'Extent':这是一个标量,表示区域与其最小边界矩形中的像素比例。计算公式为:Area 除以边界矩形面积,这是一个仿射特征,反映了区域的扩展范围。

(19)'PixelIdxList ':这是一个p元素区域像素索引的向量,每个元素表示一个像素在图像中的索引位置。

(20)'PixelList ' :返回一个矩阵,存储与 'PixelIdxList' 对应的像素坐标。每一行代表一个像素的坐标位置。

通过这些属性可以用来对图像中的区域进行详细的分析和描述,根据图像所需特征点进行选择选取。

特征提取示例说明:

对于上面介绍的前三点,我用一个图像给大家表现出来,然后与regionprops有所不同,下图就是计算面积和周长以及欧拉数的结果图:

下面我将用regionprops函数对常见的属性进行目标对象的提取,本次示例选择的实验数据为一组连续增加粒数的花生图像,如下图所示,通过提取其特征进行识别计数,可以用BP神经网络进行预测,或者作为各种聚类分析的特征数据进行分类。

对大量图片进行数据提取示例代码:

clc
clear all
close all
a='D:\视觉图片处理\花生\训练数据图片\(101).jpg';  %提取训练样本的数据路径
a0='D:\视觉图片处理\花生\训练\(101).jpg';
k=0;
kk=zeros(300,9);% 初始化一个300x9的矩阵,用于保存特征数据
for z=101:400 
    zz=num2str(z);% 将当前循环的数字转为字符串
    output_file = ['D:\\花生\\训练\\(' zz ').jpg'];%输出的路径和命名
    a(15:17)=zz(1:3);% 动态修改输入文件路径的编号部分
    a0(17:19)=zz(1:3); % 动态修改输出文件路径的编号部分
    b=imread(a);% 读取图像
    g=rgb2gray(b);%灰度化
    m=medfilt2(g);%中值滤波
    level=graythresh(m);%最佳阈值
    bw=im2bw(m,level);%二值化  
    imwrite(bw,output_file,'jpg');  % 保存二值化图像到输出文件,格式为jpg
    bw2=bwareaopen(bw,20);%删除象素小于20的连通域
     for x=1:1
        [l,n]=bwlabel(bw2,8);  % 计算8连通的连通域,返回标签矩阵和连通域数量
        display(n);                                        %连通域
        tatal=bwarea(bw2)                           %连通域总面积
        eul=bweuler(bw2)                            %连通域欧拉数
        bw3=bwperim(bw2,4);                      %图像边缘提取
        b_sum=sum(sum(bw3));     % 计算边缘像素点的数量
        L=bwlabel(bw2);                  % 对连通域进行标签
        stats=regionprops(L,'Area', 'Perimeter','Eccentricity','MajorAxisLength','MinorAxisLength'); %对各个属性进行求解
        c=sum(sum([stats.MajorAxisLength]));% 长轴长度之和
        d=sum(sum([stats.MinorAxisLength]));% 短轴长度之和
         area= [stats.Area];%计算各连通域面积
         per = [stats.Perimeter];%计算各连通域周长
        hear=mean([stats.Eccentricity]);%计算花生的离心率均值
        % 计算周长面积比
        pa = per ./area;
        k=k+1;
        kk(k, 1) = b_sum;  % 边缘像素点数量
        kk(k, 2) = c;  % 长轴长度之和
        kk(k, 3) = d;  % 短轴长度之和
        kk(k,4) = mean(pa);  %周长比上面积 
        kk(k, 5) = tatal;  % 总面积 
        kk(k, 6) = n;  % 连通域数量
        kk(k, 7) = eul;  % 欧拉数
        kk(k,8)=hear;%离心率
    end    
end
xlswrite('D:\花生\数据.xlsx',kk);%将提取得到的数据存入表格里面

结果得到的数据二值图和表格如下所示,因为截图有限,所以只截取了一部分信息进行展示:

regionprops函数提取的一系列特征主要运用于模式识别,在现实识别能更加精确快速的确定目标所在。在现代农业中,可以更好的区分作物与杂草,这样就可以实现更加精确喷洒农药或者除草工作,机器视觉的成本低,所以就有很大的发展空间。

最后以上就是对图片处理的形态学操作和特征提取,希望能给大家带来帮助。

总结

本次文章大概跟大家讲一下各函数的认识和使用的效果,形态学操作和特征提取之后就是模式识别,分类的问题,根据物体所具有的特征进行识别分类,精确提取目标对象才能更好的完成后续的分析。这次讲解就到这里(嘿嘿,不要忘了点赞,谢谢大家,望大佬能够指正),后续下一章就写一下模式识别算法(三种聚类分析以及BP神经网络预测),后面我也加以改进我的描述(哈哈哈),真的谢谢各位的点赞、收藏和关注。

相关推荐
昨日之日20061 小时前
Moonshine - 新型开源ASR(语音识别)模型,体积小,速度快,比OpenAI Whisper快五倍 本地一键整合包下载
人工智能·whisper·语音识别
浮生如梦_1 小时前
Halcon基于laws纹理特征的SVM分类
图像处理·人工智能·算法·支持向量机·计算机视觉·分类·视觉检测
深度学习lover1 小时前
<项目代码>YOLOv8 苹果腐烂识别<目标检测>
人工智能·python·yolo·目标检测·计算机视觉·苹果腐烂识别
热爱跑步的恒川2 小时前
【论文复现】基于图卷积网络的轻量化推荐模型
网络·人工智能·开源·aigc·ai编程
阡之尘埃4 小时前
Python数据分析案例61——信贷风控评分卡模型(A卡)(scorecardpy 全面解析)
人工智能·python·机器学习·数据分析·智能风控·信贷风控
孙同学要努力6 小时前
全连接神经网络案例——手写数字识别
人工智能·深度学习·神经网络
Eric.Lee20216 小时前
yolo v5 开源项目
人工智能·yolo·目标检测·计算机视觉
其实吧37 小时前
基于Matlab的图像融合研究设计
人工智能·计算机视觉·matlab
丕羽7 小时前
【Pytorch】基本语法
人工智能·pytorch·python
ctrey_7 小时前
2024-11-1 学习人工智能的Day20 openCV(2)
人工智能·opencv·学习