圆形"/>
matlab判断图像是否为标准圆形
本例中判断一个图像是否为标准的原型有如下步骤:
1.读取图片
2.去除图片噪声
3.寻找边界
4.判断提取出来的边界是否是一个圆
下面是具体步骤:
1.读取图片
其中要将图片转化为二值图像,使用的最新的方法时候imbinarize,如果用不了的话也可以先使用graythresh方法选择阈值,再通过im2bw转为二值图像。
clc,clear
%% 1.读取图片
rgb=imread('pillsetc.png');
I=rgb2gray(rgb);
%转化为二值图片
%bw=imbinarize(I);
threshold =graythresh(I);%取阈值
bw=im2bw(I,threshold);
2.去除图片噪声
使用imfill函数填充图像
%% 2.去除噪声
bw = bwareaopen(bw,30);
se = strel('disk',2);
bw = imclose(bw,se);
bw = imfill(bw,'holes');%填充subplot(1,3,1),imshow(rgb),title('原图')
subplot(1,3,2),imshow(I),title('灰度图')
subplot(1,3,3),imshow(bw),title('处理后的二值图像')
3.寻找边界
[B,L] = bwboundaries(bw,···)函数拿到连通分量
- B是连通分量,L是标记矩阵,B内每一行是一个 Q x 2 的矩阵, Q内每一行表示连通体的边界像素的位置坐标(第一列是纵坐标Y,第二列是横坐标X),Q为边界像素的个数.
- L是一个标记矩阵.
for k = 1:length(B)boundary = B{k};%第k个连通分量plot(boundary(:,2), boundary(:,1), 'w', 'LineWidth', 2)%第一列是纵坐标Y,第二列是横坐标X
end
利用上述循环来为每一个连通分量圈出一个圆圈。
下面是这部分的完整代码:
%% 3.找边界
%B是一个 P x 1 的数组,其中P代表连通体的个数.B内每一行是一个 Q x 2 的矩阵,
%Q内每一行表示连通体的边界像素的位置坐标(第一列是纵坐标Y,第二列是横坐标X),Q为边界像素的个数.%L是一个标记矩阵.
[B,L] = bwboundaries(bw,'noholes');
figure
subplot(1,2,1),imshow(label2rgb(L, @jet, [.5 .5 .5])),title('填充颜色')
subplot(1,2,2),imshow(label2rgb(L, @jet, [.5 .5 .5])),title('增加白色边界')
hold on
for k = 1:length(B)boundary = B{k};%第k个连通分量plot(boundary(:,2), boundary(:,1), 'w', 'LineWidth', 2)%第一列是纵坐标Y,第二列是横坐标X
end
hold off
4.判断提取出来的边界是否是一个圆
利用metric = 4*pi*area/perimeter^2公式. 如果得到的metric是1则说明是一个圆,小于1说明不太圆。
regionprops函数度量图像区域属性:
- ‘Area’:是标量,计算出在图像各个区域中像素总个数。
- ‘Centroid’:是1行ndims(L)列的向量,给出每个区域的质心(重心)
4.判断提取出来的边界是否是一个圆
%metric = 4*pi*area/perimeter^2. 如果得到的metric是1则说明是一个圆,小于1说明不太圆
stats = regionprops(L,'Area','Centroid');%用来度量图像区域属性,'Centroid':是1行ndims(L)列的向量,给出每个区域的质心(重心)
threshold = 0.94;
figure
imshow(label2rgb(L, @jet, [.5 .5 .5])),title('增加白色边界')
hold on
for k = 1:length(B)boundary = B{k};%第k个连通分量plot(boundary(:,2), boundary(:,1), 'w', 'LineWidth', 2)%第一列是纵坐标Y,第二列是横坐标X
end
% loop over the boundaries
for k = 1:length(B) %遍历每一个连通分量% obtain (X,Y) boundary coordinates corresponding to label 'k'boundary = B{k};% compute a simple estimate of the object's perimeterdelta_sq = diff(boundary).^2; perimeter = sum(sqrt(sum(delta_sq,2)));% obtain the area calculation corresponding to label 'k'area = stats(k).Area;% compute the roundness metricmetric = 4*pi*area/perimeter^2;% display the resultsmetric_string = sprintf('%2.2f',metric);% mark objects above the threshold with a black circleif metric > thresholdcentroid = stats(k).Centroid;plot(centroid(1),centroid(2),'ko'); %如果哪个连通分量的判断结果大于0.94,则在中心标记oendtext(boundary(1,2)-35,boundary(1,1)+13,metric_string,'Color','y',...'FontSize',14,'FontWeight','bold');endtitle('值越接近1说明越接近圆');
hold off
下面是最终结果,程序设置,如果使用公式metric = 4*pi*area/perimeter^2得到的结果大于0.94这说明差不多符合一个标准圆
更多推荐
matlab判断图像是否为标准圆形
发布评论