灰度图像形状的识别分类算法实现matlab
2016-07-22 20:58
706 查看
摘 要: 针对已经给出的图像,在分类之前,因为存在噪声和光照的不同,所以要先进行图像增强,并统一将图像转为二值图像。对图像进行边缘检测,可以很容易算出各个图像面积与周长二次方的比值关系,对图像进行直线检测, 可以获得图像中直线的特征,结合图像的以上两种特种对形状进行分类。
算法设计和推导:
1. 图像预处理部分,通过
9X9 均值滤波器,先对图像进行去噪,然后二值化图像。
2. 各个形状的面积和周长存在一定的特征关系,可据此对图像进行分类。
(令各形状的面积为S,周长为L,计算)
(1)圆形(半径为r1):S/L2
=(π*r12) / (2*π*r1)2
= 1 / 4*π= 0.0796
(2)正方形(边长为r2):S/L2 = r22
/ (4*r2)2
= 1/16 = 0.0652
(3) 矩形(不包含正方形) S/L2 < 1/16 = 0.0652
(4) 椭圆(不包含原) S/L2 < 1 / 4*π= 0.0796
据此方法,可对圆和正方形进行分类,将圆和正方形与另外两种形状区分开来,但无法对椭圆和矩形进行恰当分类。
3. 用霍夫变换对形状进行直线检测,获得直线特征(直线数量,直线长度),
若检测到直线数量不等于四条,可直接判断为圆或椭圆,计算直线长度,找出相等的直线对,若四条直线相等,可判断为正方形,若有两对相等的直线,可判断为矩形。
结合以上两种判断方法,对形状进行识别并分类。
实验设计和结果
1.预处理部分,对图像进行增强并二值化,实现代码如下:
function K2 = quzao(I)
K1=filter2(fspecial('average',[9,9]),I)/255;
thresh = graythresh(I);
K2 = im2bw(K1,thresh);
end
实现效果:
原图像 处理过的图像
原图像 处理过的图像
原图像 处理过的图像
原图像 处理过的图像
2.为了计算S/L2,需要获得图像中各形状对应的面积和周长,对二值化后的图像进行边缘提取,来获得形状的边界(以圆为例)
两张图像大小一样,分别计算每张图像值为1 的像素数量,计算比率,实现代码如下:
function r = Ratio(K,E)
[r1,c1] = size(K);
% [r2,c2] = size(E);
area = 0;
perimeter = 0;
for i = 1:r1
for j = 1:c1
if(K(i,j)==1)
area = area+1;
end
if(E(i,j)==1)
perimeter = perimeter+1;
end
end
end
r = area/(perimeter*perimeter);
end
每个形状各选择50张图像进行测试,查看各个不同形状所计算出的比率的分布情况,结果如下:
圆 正方形
长方形 椭圆
观察实验结果发现,圆和正方形的S/L2比值并未像预期那样为定值,但圆形的比值基本分布在0.085和
0.09之间,而其他形状算出的比值均未超过0.085,可据此将圆形与其他三个形状区分开来。
3.对图像进行直线检测
利用霍夫变换进行直线检测 ,可通过分析直线特征,根据获得的直线数量,计算出的直线长度来进行比较,具体实现如下
直线检测并进行正方形和长方形的判断并写入相应文件夹:
BW=edge(K,'canny'); %边缘检测
[H,T,R]=hough(BW); %霍夫变换进行直线检测
P=houghpeaks(H,5,'threshold',ceil(0.3*max(H(:))));
lines=houghlines(BW,T,R,P,'FillGap',30,'MinLength',60); %获得检测到的直线
[num1,num2] = size(lines); %获得直线的数量num2
if(num2 == 4) %若检测到为四条直线,逐一计算各条直线长度,存入l
for count=1:4
lines(count).long = sqrt((lines(count).point1(1)-lines(count).point2(1))^2 + (lines(count).point1(2)-lines(count).point2(2))^2);
l(count) = lines(count).long;
end
num = lineCompare(l); %比较直线长度,判断是否为矩形或正方形形
end
if(num==4 && num2 == 4) %判断为正方形
path = strcat('square\',int2str(index1));
imwrite(K,strcat(path,'.jpg'));
index1 = index1+1;
elseif(num==2 && num2 == 4) %判断为矩形
path = strcat('rectangle\',int2str(index2));
imwrite(K,strcat(path,'.jpg'));
index2 = index2+1;
通过直线的长度比较来进行判断,lineCompare函数代码如下
function num = lineCompare(l)
num = 0;
diff(12) = abs(l(1)-l(2)); %第一条直线与各直线进行比较,计算与其他直线的差值diff
diff(13) = abs(l(1)-l(3));
diff(14) = abs(l(1)-l(4));
if(diff(12)<5.5 || diff(13)<5.5 || diff(14)<5.5)
if(diff(12)<5.5 && diff(13)<5.5 && diff(14)<5.5) %若四条直线相等(即直线长度差值小于5.5),即判断为正方形
num = 4;
elseif(diff(12) < 5.5) %四条直线不相等,但直线1,2相等,判断直线3,4是否相等,若相等,即为矩形
diff(34) = abs(l(3) - l(4));
if(diff(34) < 5.5)
num = 2;
end
elseif(diff(13) < 5.5)
diff(24) = abs(l(2) - l(4));
if(diff(24) < 5.5)
num = 2;
end
elseif(diff(14) < 5.5)
diff(23) = abs(l(2)-l(3));
if(diff(23) < 5.5)
num = 2;
end
end
end
end
最终确定的程序执行步骤为,先进行直线检测将图像分为正方形和长方形,圆形和椭圆两类,正方形和长方形通过直线长度比较进一步分类,圆形和椭圆通过计算S/L2进一步划分。将每一张图像进行形状分类后写入对应的文件夹
4. 将最终程序用于形状的划分,统计分到每个问价下的各形状数量性能统计如下
文件夹\形状 | 圆 | 正方形 | 长方形 | 椭圆 |
circle | 276 | 2 | 3 | 60 |
square | 0 | 188 | 0 | 2 |
rectangle | 0 | 14 | 156 | 2 |
ellipse | 3 | 75 | 120 | 215 |
合计 | 279 | 279 | 279 | 279 |
正确率 | 98.9% | 67.4% | 56.0% | 77.1% |
图像预处理:
function K2 = quzao(I)
K1=filter2(fspecial('average',9),I)/255;
thresh = graythresh(I);
K2 = im2bw(K1,thresh);
end
周长面积比率:
function r = Ratio(K,E)
[r1,c1] = size(K);
% [r2,c2] = size(E);
area = 0;
perimeter = 0;
for i = 1:r1
for j = 1:c1
if(K(i,j)==1)
area = area+1;
end
if(E(i,j)==1)
perimeter = perimeter+1;
end
end
end
r = area/(perimeter*perimeter);
end
开始分类:
function split(file_path)
%file_path = 'test1\';% 图像文件夹路径
img_path_list = dir(strcat(file_path,'*.jpg'));%获取该文件夹中所有jpg格式的图像
img_num = length(img_path_list);%获取图像总数量
index1 = 1;
index2 = 1;
index3 = 1;
index4 = 1;
num = 0;
if img_num > 0 %有满足条件的图像
for j = 1:img_num %逐一读取图像
image_name = img_path_list(j).name;% 图像名
image = imread(strcat(file_path,image_name));
fprintf('%d %d %s\n',i,j,strcat(file_path,image_name));% 显示正在处理的图像名
K = quzao(image); % 调用去噪函数进行去噪
BW=edge(K,'canny'); %边缘检测
[H,T,R]=hough(BW); %霍夫变换进行直线检测
P=houghpeaks(H,5,'threshold',ceil(0.3*max(H(:))));
lines=houghlines(BW,T,R,P,'FillGap',30,'MinLength',60); %获得检测到的直线
[num1,num2] = size(lines); %获得直线的数量num2
if(num2 == 4) %若检测到为四条直线,逐一计算各条直线长度,存入l
for count=1:4
lines(count).long = sqrt((lines(count).point1(1)-lines(count).point2(1))^2 + (lines(count).point1(2)-lines(count).point2(2))^2);
l(count) = lines(count).long;
end
num = lineCompare(l); %比较直线长度,判断是否为矩形或正方形形
end
if(num==4 && num2 == 4) %判断为正方形
path = strcat('square\',int2str(index1));
imwrite(K,strcat(path,'.jpg'));
index1 = index1+1;
elseif(num==2 && num2 == 4) %判断为矩形
path = strcat('rectangle\',int2str(index2));
imwrite(K,strcat(path,'.jpg'));
index2 = index2+1;
else
E = edge(K);
r = Ratio(K,E);
if(r>0.086) %判断为圆
path = strcat('circle\',int2str(index3));
imwrite(K,strcat(path,'.jpg'));
index3 = index3+1;
else %判断为椭圆
path = strcat('ellipse\',int2str(index4));
imwrite(K,strcat(path,'.jpg'));
index4 = index4+1;
end
end
end
%图像处理过程 省略
else
fprintf('文件夹不存在!');% 显示正在处理的图像名
end
end
function num = lineCompare(l)
num = 0;
diff(12) = abs(l(1)-l(2)); %第一条直线与各直线进行比较,计算与其他直线的差值diff
diff(13) = abs(l(1)-l(3));
diff(14) = abs(l(1)-l(4));
if(diff(12)<5.5 || diff(13)<5.5 || diff(14)<5.5)
if(diff(12)<5.5 && diff(13)<5.5 && diff(14)<5.5) %若四条直线相等(即直线长度差值小于5.5),即判断为正方形
num = 4;
elseif(diff(12) < 5.5) %四条直线不相等,但直线1,2相等,判断直线3,4是否相等,若相等,即为矩形
diff(34) = abs(l(3) - l(4));
if(diff(34) < 5.5)
num = 2;
end
elseif(diff(13) < 5.5)
diff(24) = abs(l(2) - l(4));
if(diff(24) < 5.5)
num = 2;
end
elseif(diff(14) < 5.5)
diff(23) = abs(l(2)-l(3));
if(diff(23) < 5.5)
num = 2;
end
end
end
end
相关文章推荐
- matlab工具箱之人眼检测+meanshift跟踪算法--人眼跟踪
- C#调用Matlab引擎详细方法以及注意事项
- Sublime运行Matlab
- opencv和matlab矩阵类型数据相互传递
- matlab2016的License Manager Error解决方案
- MATLAB并行:parfor
- MATLAB2012a_for_win7_64
- Matlab之画图
- Matlab与C/C++混合编程接口及应用
- Matlab之文件读写
- Matlab之cell使用
- Matlab画图技巧之消除空白(二)
- matlab 画图中线型及颜色设置
- C语言实现Matlab自带的滤波filter()函数
- matlab的函数conv()的C语言实现
- Kalman滤波算法原理(Matlab/C/C++)
- Matlab中的CVX工具包安装
- Introduction to matlab 1
- 如何在python中读写和存储matlab的数据文件(*.mat)
- 机器学习中的相似性度量 (多种几何距离定义)