close all
clear all
I=imread('Chessboard.png');
bw=rgb2gray(I);
figure('name','rgb2gray');imshow(bw);
bw=im2bw(bw);
figure('name','im2bw');imshow(bw);
bw=~bw;
figure('name','~bw');imshow(bw);
se=strel('rectangle',[3,3]);%构造结构元素(Structuring element)。
bw=imerode(bw,se);
figure('name','imerode');imshow(bw);
bw=bwfill(bw,'hole');%填充二进制图像的背景色,只认孔为0的情况,用1填充
figure('name','bwfill');imshow(bw);
%寻找不包括孔连通域的边缘,并且把每个连通域的边界描出来
[B,L] = bwboundaries(bw,4); %二值图像的边界。
%B是一个P×1的cell数组,P为对象个数,每个cell是Q×2的矩阵,对应于对象轮廓像素的坐标。
%用法:B = bwboundaries(BW,conn)(基本格式)
%B是一个P*1的数组,P代表联通体个数,B内每行是一个Q*2的矩阵。
%Q内每一行表示联通体的边界像素的位置坐标,
%第一列是纵坐标Y,第二列是横坐标X,Q为边界像素的个数
%所以boundary(:,2)为X,boundary(:,1)为Y,
%[B,L]=bwboundaries(BW,n)
%L是一个标记矩阵,n只能是4,8,分别对应4邻域和8邻域
%
figure('name','bwboundaries'),imshow(label2rgb(L, @jet, [.5 .5 .5]))%显示图像
hold on
for k = 1:length(B)
boundary = B{k};%第K个对象的边缘
plot(boundary(:,2),boundary(:,1),'w','LineWidth',2)%整个循环表示的是用白色描边
end
% 找到每个连通域的质心
stats = regionprops(L,'Area','Centroid');%测量图像区域里每个已经标注的对象的面积和质心
% 循环历遍每个连通域的边界
for k = 1:length(B)
% 获取一条边界上的所有点
boundary = B{k};
% 计算边界周长
delta_sq = diff(boundary).^2; %行之间的差分(相当于求点点之间的距离((x1-x2)^2,(y1-y2)^2)),
%X = [1 1 1; 5 5 5; 25 25 25];
%Y = diff(X)Y =
% 4 4 4
%20 20 20
perimeter = sum(sqrt(sum(delta_sq,2)));%sum(sqrt((x1-x2)^2+(y1-y2)^2))将K对象的点点之间的距离求和,即计算边界周长
% 获取边界所围面积
area = stats(k).Area;
% 计算匹配度
metric =80*area/perimeter^2;%模式识别与图像处理
% 要显示的匹配度字串
metric_string = sprintf('%2.2f',perimeter);
% 标记出匹配度接近1的连通域
text(boundary(1,2)-35,boundary(1,1)+13,...
metric_string,'Color','black',...
'FontSize',12,'FontWeight','bold');