目的:将一副包含一个或多个矩形(圆形,三角形,正五边形,正六边形),且彼此独立不粘连的图像进行图像切割,提取出里面单独的形状,并利用占空比的方法判断图像的形状。
主程序代码:
%% 代码作用:连通域的分割,判断识别图像类型
% 输入图像中仅包含一个或多个矩形,圆形,三角形,正五边形,正六边形,彼此独立且不粘连
% 思路:
% 直接进行切割,且进行局部图像提取保存。然后利用占空比的方法判断图像的类型
% 说明:
% 暂时只能针对矩形,圆形,三角形,正五边形 ,正六边形的图形检测。如需添加
% 其他类型需要对ratio_search()函数进行扩充。
% 作者:cw 时间:2019.8.14
clc;
clear all;
t0 = clock;
%% 图像读入,灰度化,二值化,显示二值图
img=imread('TEST.jpg');
img = rgb2gray(img);
BW=~im2bw(img); % 背景用0表示,有效区域用1表示
figure;imshow(BW),title('二值显示');
%% 连通域切割,8连通域
% 图像连通域标记
[Local,image_num] = bwlabel(BW,8);
% RGB = label2rgb(Local);
% figure;imshow(RGB),title('rgb显示连通域');
% 连通域提取步骤:
% 1 先将图像分为5张,每张图只放一个标签区域;
% 2 删除个图中的无效区域;
% 3 创建元组来保存切割后的图像;
Multi_pic = Multi_Local(Local,image_num);
MultiPic_cell = cell(1,image_num);
for i=1:image_num
Local_shape = [];
Postion_range = EdgeCheck(Multi_pic,i);
Local_shape = Image_Cut(Local,Postion_range,i);
MultiPic_cell{i} = Local_shape;
end
%% 判断图像类型并显示各个图像
for i =1:image_num
% 占空比法判断图像的类型
Class_name{i} = ratio_search(MultiPic_cell{i})
figure;imshow(MultiPic_cell{i}),title(['this is ', Class_name{i}]);
end
%% 耗时计算
Time_consumed = etime(clock,t0);
函数Multi_Local.m:
function Multi_pic = Multi_Local( Labeled_Pic,Label_num)
% 将标记好的图差分成多张图,每张图仅有一个标签
% 采用list结构存储效率更高,可惜MATLAB中没有对应数据类型
[m,n] = size(Labeled_Pic);
TEMP = zeros(m,n,Label_num);
for i = 1:m
for j = 1:n
for k = 1:Label_num
if Labeled_Pic(i,j) == k
TEMP(i,j,k) = 1;
break;
end
end
end
end
Multi_pic = TEMP;
end
函数EdgeCheck.m:
function Position_range = EdgeCheck(Multi_Image,num_Label)
% 作用:找出标记图像(Multi_Image中标号为num_Label的局部图的坐标范围
% Image_Labeled:标记图像
% num_Label:区域标记号
% [x1,y1,x2,y2]:标记区域的左上角和右下角坐标,x是列,y是行
X_MAX=0;X_MIN =0;Y_MAX=0;Y_MIN =0;
Image_Labeled = Multi_Image(:,:,num_Label);
% 计算指定标记的区域范围
H = size(Image_Labeled,1);
% 找出X_MIN和X_MAX
for j=1:H
% 从上到下,逐行寻找等于1的行
if max(Image_Labeled(j,:))==1
Y_MIN = j;
break;
end
end
for j=1:H
% 从下到上,逐行寻找等于1的行
if max(Image_Labeled(H+1-j,:))==1
Y_MAX = H+1-j;
break;
end
end
L = size(Image_Labeled,2);
% 找出Y_MIN和Y_MAX
for k=1:L
% 从左到右,逐行寻找等于1的列
if max(Image_Labeled(:,k))==1
X_MIN = k;
break;
end
end
for k=1:L
% 从右到左,逐行寻找等于1的列
if max(Image_Labeled(:,L+1-k))==1
X_MAX = L+1-k;
break;
end
end
Position_range =[X_MIN,Y_MIN,X_MAX,Y_MAX];
end
函数Image_Cut.m:
function Image = Image_Cut( Labeled_Pic,Position,label )
% 根据参数指定的范围将图像切割出来称为一个单独的小图片
% Labeled_Pic:标记的图像
% Position:要拷贝的区域
% label:标签号
% Image:返回一个切割好的局部图
TEMP = Labeled_Pic(Position(2):Position(4),Position(1):Position(3));
for i = 1:size(TEMP,1)
for j = 1:size(TEMP,2)
if TEMP(i,j) ~= label
TEMP(i,j) = 0;
end
end
end
Image = TEMP;
end
函数Image_Cut.m:
function Iamge_class = ratio_search( input_image )
% 作用:利用图像的占空比判断图像是什么类型
% input_image:输入的局部图,二值图,有效区域是标签(1,2,3...),背景是0
% Iamge_class:图像类型名称,例如:矩形
% 思路:
% 将三角形,矩形,五角形,六角形,圆形的占空比预先保存到一个元组中;
% 对输入图像计算占空比,然后和数组中的个元组素对比;
% 这只是个粗略的结果,根据得到了占空比进行邻近的几个排序,后续还需要进行轮廓验证
% 占空比模板库
Class_Module = {'triangle','rectangle','pentagon','hexagon','circle'};
Ratio_Module = [0.5,1,0.7,0.75,0.79];
% 图像大小
[m,n] = size(input_image);
% 计算占空比
index_vector = find(input_image ~= 0);
RATIO = size(index_vector,1)/(m*n);
TEMP = abs(Ratio_Module - RATIO);
ind = find(TEMP == min(TEMP));
% 取出图像名称
Iamge_class = Class_Module{ind};
end