在图像识别中我们经常需要对各种形状进行提取,比如之前介绍的矩方法可以用于识别图像中的不同形状,如下链接所示:
(1条消息) 图形学中的不变矩方法及其matlab实现_warnerchang的博客-CSDN博客https://blog.csdn.net/weixin_43568289/article/details/123924817?spm=1001.2014.3001.5502今天我们将讲解如何使用reginprops函数对图像中的不同形状进行提取,并基于特定的特征对其进行提取。以识别圆形为例:
具体步骤如下:
1、将图像首先转化为灰度图像(这一步可以设定一个阈值区间,降低背景噪声的干扰),并将其二值化
2、如果形状的颜色为黑色,则需要对其进行反色处理
3、使用bwboundaries找到所有的闭合边界,主要是为了后续图像显示,与最后提取特定形状无关
4、使用regionprops函数获得不同形状的统计值
5、根据获得统计值进行筛选
代码如下:
% Matlab
% 读取图片
Im = imread('R_C.jpg');
% 转化为灰度图
Im_gray = rgb2gray(Im);
% 二值化
bw = imbinarize(Im_gray);
% 反色处理(形状填充颜色为白色)
bw = ~bw;
% 边界寻找
[B,L] = bwboundaries(bw,'noholes');
subplot(1,3,1)
imshow(L)
hold on
% 初始化矩阵
roundness = zeros(size(B,1), 3); % 用于存储满足要求圆形的统计值
metric_List = zeros(length(B),1); % 用于存储满足阈值圆度的逻辑值
% 圆度的统计值,将图形中每个分离的连通区域的周长、面积和圆度值记录下来
stats = regionprops(L,'Area','Centroid');
threshold = 0.87; % 设定圆度的阈值
% 循环处理每个边界
for k = 1:length(B) % 获取边界坐标
boundary = B{k}; % 计算周长
delta_sq = diff(boundary).^2;
perimeter = sum(sqrt(sum(delta_sq,2))); % 对标记为K的对象获取面积
area = stats(k).Area; % 圆度计算公式4*PI*A/P^2
metric = 4*pi*area/perimeter^2; % 结果显示
roundness(k,:) = [perimeter, area, metric ];
% 标记圆度大于threshold = 0.87 的对象
if metric >threshold
metric_string = sprintf('%2.2f',metric);
centroid = stats(k).Centroid; % centroid是目标k的质心
metric_List(k) = 1;
plot(centroid(1), centroid(2),'k.');
text(centroid(1), centroid(2),metric_string,'Color','r',...
'FontSize',14,'FontWeight','bold');
else
metric_List(k) = 0;
end
end
title('圆度识别结果,越圆越接近1');
hold off
% 找到面积大于500的形状,并将其显示出来
mask_area= ismember(L, find([stats.Area]>=500));
Im_select_area = immultiply(bw,mask_area);
subplot(1,3,2)
imshow(Im_select_area)
title('Area>500')
% 将圆度大于阈值的形状挑选出来
%*************************************************************************%
% 这两行代码是错误代码,不需要这么麻烦,不要想着去修改stats结构体
% stats.metric = metric_List';
% mask_metric= ismember(L, find([stats.metric]==1));
%*************************************************************************%
mask_metric= ismember(L, find(metric_List==1));
Im_select_metric = immultiply(bw,mask_metric);
subplot(1,3,3)
imshow(Im_select_metric)
title('metric>threshold')
所使用的图片如下所示:
最后的效果图: