1)尺寸检测
在提供的实验素材中,“coins.jpg”和“sample_25.75mm.jpg”两幅图像是在同一视角,同一设备参数(相机,焦距,视野,工作距离均相同)下拍摄,已知“sample_25.75mm.jpg”图中硬币直径为25.75mm(毫米),请标出“coins.jpg”中每个硬币的实际直径为多少毫米。
建议解题思路(仅供参考,可自行设计):预处理(调整到合适对比度,模糊度,目的使二值化不至于出现很多碎块),二值化,形态学,检测连通域,确定最大外接矩形尺寸;二幅图进行以上处理,并根据线像素比例,确定每个硬币的直径。
1.sample_25.75mm.jpg
2.coins.jpg
clc;clear;close all;
sample = imread('sample_25.75mm.jpg');
subplot(1,2,1);imshow(sample);title('initial image of coin');
sample = imbinarize(rgb2gray(sample));
g_coin = bwmorph(~sample,'close',Inf);
subplot(1,2,2);imshow(g_coin);title('marked image');
[L,num] = bwlabel(g_coin,4);
rad = regionprops(L,'BoundingBox');
%对连通域长度进行从大到小冒泡排序
for i = 1 : num-1
for j = 1:num-i
if rad(j).BoundingBox(3) < rad(j+1).BoundingBox(3)
t1 = rad(j);
rad(j) = rad(j+1);
rad(j+1) = t1;
end
end
end
%标注长度最大的连通区域
boundingbox = rad(1).BoundingBox;
x = boundingbox(1);
y = boundingbox(2);
width_x = boundingbox(3);
width_y = boundingbox(4);
rectangle('Position',[x y width_x width_y],'EdgeColor','r');
diameter = 25.75; %直径25.75mm
k = diameter / ((width_x+width_y)/2); %线像素数
%处理硬币
c = imread('coins.jpg');
c = imbinarize(rgb2gray(c));%二值化
g1 = bwmorph(c,'close',Inf);
figure,imshow(g1);title('标注结果');
hold on;
[L,num] = bwlabel(g1,4);
stats = regionprops(L,'basic');
%对连通域面积进行从大到小冒泡排序
for i = 1 : num-1
for j = 1:num-i
if stats(j).Area < stats(j+1).Area
tmp = stats(j);
stats(j) = stats(j+1);
stats(j+1) = tmp;
end
end
end
stats = stats(1:22); %取22个标记硬币的区域
N = size(stats,1);
for i = 1:N
boundingbox = stats(i).BoundingBox;
dia = (boundingbox(3)+boundingbox(4))/2; %直径
d = dia *k; %直径像素
x = stats(i).Centroid(1);
y = stats(i).Centroid(2);
p1 = [y, x - dia/2];
p2 = [y, x + dia/2];
plot( [p1(2),p2(2)],[p1(1),p2(1)], 'Color','r','LineWidth',2);
text(x-80,y-40,strcat(num2str(d),'mm'),'color','r','FontSize',13);
end
2)形状检测
在提供的实验素材中,“shape1.png”为已经经过预处理得到的二值图像,请先检测到每个图形的位置(中心点),并根据每个图形的特征(外接矩形边长比例,质心,欧拉数,像素比例…等特征)在每个图形上方或下放标注形状类型(打印出红色文字)。
建议解题思路(仅供参考,可自行设计):二值化,检测连通域(调用regionprops()函数,自行查阅用法),根据返回的特征(可能需要多个特征共同判断),用switch语句或者选择结构判断形状,并在图形上打印判断结果。
1.shape1.png
clc;clear;close all;
img = imread('shape1.png');
img1 = ~imbinarize(rgb2gray(img));
imshow(img1);
[L,num] = bwlabel(img1,8);
stats = regionprops(L,'all');
%BoundingBox : [x,y,w_x,w_y]x,y为矩形左上角坐标
%Centroid: 区域质心[x,y]
%Circularity : 计算圆度值,理想圆为1
%Orientation : x轴与椭圆主轴的角度,(-90,90)
%Eccentricity : 椭圆离心率(焦点距离与长轴长度之比),0为圆,1为线段
%Extent :外接矩形占空比
%MajorAxisLength : 椭圆长轴长度
%MinorAxisLength : 椭圆短轴长度
for i = 1:num
%质心
x = stats(i).Centroid(1);
y = stats(i).Centroid(2);
%长、宽
width_diff = stats(i).BoundingBox(3)-stats(i).BoundingBox(4);
%椭圆长轴/短轴
c = stats(i).MajorAxisLength/stats(i).MinorAxisLength;
%椭圆离心率
ecc = stats(i).Eccentricity;
%外接椭圆与x轴的角度
angle = stats(i).Orientation;
%占空比
ext = stats(i).Extent;
%圆度值
cir = stats(i).Circularity;
if ext > 0.75 %圆、椭圆、正、长
if ext == 1
if width_diff==0
text(x,y,'正方形','color','r','Fontsize',13);
else
text(x,y,'长方形','color','r','Fontsize',13);
end
elseif width_diff==0
text(x,y,'圆形','color','r','Fontsize',13);
else
text(x,y,'椭圆','color','r','Fontsize',13);
end
elseif ext>0.7 && ext<0.75
if width_diff>0
text(x,y,'平行四边形','color','r','Fontsize',13);
else
text(x,y,'五边形','color','r','Fontsize',13);
end
elseif ext>0.5 && ext<0.6
if width_diff<0
if angle>0
text(x,y,'竖着的菱形','color','r','Fontsize',13);
else
text(x,y,'直角三角形','color','r','Fontsize',13);
end
else
if cir >0.7
text(x,y,'横着的菱形','color','r','Fontsize',13);
else
text(x,y,'等腰三角形','color','r','Fontsize',13);
end
end
elseif ext<0.5
if c>3
text(x,y,'钝角三角形','color','r','Fontsize',13);
else
text(x,y,'五角星','color','r','Fontsize',13);
end
end
end