MATLAB基于形态学的目标检测(一)简单图形统计

(目标检测)MATLAB基于形态学的目标检测(一)简单图形统计


by HPC_ZY


本文主要介绍二值形态学在目标检测上的用法, 就不讲形态学原理了。
不熟悉的选手可以参考以下文章,
二值形态学原理:https://blog.csdn.net/zxli3011/article/details/50522939
二值形态学效果MATLAB演示:https://blog.csdn.net/abigbiggirl/article/details/49888733


一、生成测试图像

  1. 目标图形生成
%% 矩形
% bg:背景图 x,y:矩形中心坐标 rh,rw:矩形高宽半径
function bg = CreateRectangle(bg, x, y, rh, rw)

bg(x-rh:x+rh, y-rw:y+rw) = 1;

end

%% 圆形
% bg:背景图 x,y:圆心坐标 r:半径
function bg = CreateCircle(bg, x, y, r)

for i = x-r:x+r
	for j = y-r:y+r
		if(i-x)^2+(j-y)^2 < (r+1)^2
			bg(i,j) = 1;
		end
	end
end

end
  1. 测试与效果
%% 测试图生成
bg1 = zeros(500);
bg2 = zeros(500);
N = 8; % 图形数量
for n = 1:N
	% 随机生成整数坐标(以下写法是为确保图形在图像内部)
	x = round(rows*(rand()*0.8+0.1);
	y = round(cols*(rand()*0.8+0.1);
	bg1 = CreateRectangle(bg1, x, y, 30, 30);
	bg2 = CreateCircle(bg2, x, y, 40);
end

在这里插入图片描述


二、连通区域目标统计

利用二值连通区域标记算法统计目标的数量。

  1. 二值连通区域标记算法
    算法原理不做介绍,感兴趣可以查看:
    二值图连通区域标记-https://blog.csdn.net/ch190029975/article/details/82734619

  2. MATLAB实现与结果
    这里以圆形目标为例,可自行测试其他图形。

%% 测试图生成与显示
%...

%% 连通区域标记
[label,num] = bwlabel(bg);

%% 结果显示
status = regionprops(label,'BoundingBox'); % 获取标记框
centroid = regionprops(label,'Centroid'); % 获取标记中心

subplot(122), imshow(bg), title('连通分量标记');
hold on
for n = 1:num
	rectangle('position',status(n).BoundingBox,'edgecolor','r'); % 画框
    text(centroid(n,1).Centroid(1,1)-1,centroid(n,1).Centroid(1,2)-1, num2str(n),'Color', 'r')  % 标号
end

从结果可以看出,当目标图形无重叠时,连通分量标记可以很好的统计目标数量;但图像有相连或重叠时,则无法正确统计。
无重叠情况
有重叠情况


三、结合形态学

充分利用腐蚀算法的原理,实现目标检测。

  1. 目标结构元的生成
    自己设定的模板形状,调用strel()函数即可生成
%% 矩形
% rh,rw:矩形高宽半径
function se = RectangleStrel(rh, rw)

mask = ones(rh*2+1,rw*2+1);
se = strel(mask);

end

%% 圆形
% r:半径
function se = CircleStrel(r)

[x,y] = meshgrid(-r:r);
mask = x.^2+y.^2<(r+1)^2;
se = strel(mask);

end
  1. 基于形态学腐蚀的目标检测
    代码以圆形目标为例,其他图形可自行修改。
%% 测试图生成
bg = zeros(500);
N = 8; % 图形数量
R = 40; % 圆形半径
for n = 1:N
	% 随机生成整数坐标(以下写法是为确保图形在图像内部)
	x = round(rows*(rand()*0.8+0.1);
	y = round(cols*(rand()*0.8+0.1);
	bg = CreateCircle(bg2, x, y, R);
end

%% 形态学腐蚀
se = CircleStrel(R*0.9); % 使用等于或略小于目标的结构元
ob = imerode(bg,se);

%% 连通区域标记
[label,num] = bwlabel(ob); % 对腐蚀结果进行连通区域标记

%% 结果显示
subplot(131), imshow(bg), title('原图')
subplot(132), imshow(ob), title('腐蚀结果')
subplot(133)imshow(bg), title('标记结果')
hold on;
for n = 1:num
    rectangle('position',status(n).BoundingBox+[-R,-R,2*R,2*R],'edgecolor','r');
    text(centroid(n,1).Centroid(1,1)-1,centroid(i,1).Centroid(1,2)-1, num2str(n),'Color', 'r') 
end

结果图如下, 可以看到效果比较好。如果代码里使用与目标等半径的结构元,腐蚀结果则可以定位到图形中心。
在这里插入图片描述

在这里插入图片描述


总结

对于形状和尺寸都统一的图形,利用该方法可以精确获取目标图形的位置与数量。
但对于图形尺寸不一、形状多样的背景里,还能适用吗?
这个问题将在下一篇为大家分享。

有任何问题欢迎讨论,最后还是把测试代码上传
https://download.csdn.net/download/xsz591541060/11246225
由于核心代码在文中已讲,不推荐下载,除非你买了年VIP。

猜你喜欢

转载自blog.csdn.net/xsz591541060/article/details/91984878
今日推荐