海洋面积:
海洋面积可看成是原灰度图像总像素点个数减去各个陆地连通区域像素点总和。
Matlab自带regionprops函数各参数解析超链接
Matlab代码:
clc;
clear;
close all;
%---------------1、 对 yaogan1 的图像进行处理,获取连续的边界,计算不同边界长度以及计算两类不同地物区域的面积。--------------------
pic=imread('yaogan1.bmp');
[row,column]=size(pic);
threshold=graythresh(pic); %采用otsu方法计算图像最佳阈值
binary_img=im2bw(pic,threshold); %灰度图转换成二值图像
SE=strel('square',3);
result_expand=imdilate(binary_img,SE); %膨胀
for i=floor(row/3):row
result_expand(i,1)=true;
end
fill_hole=imfill(result_expand,'holes'); %孔洞填充
% status=regionprops(fill_hole ,'Area' ,'PixelList' );
% for i=1:size(status)
% area(i)=status(i).Area;
% if area(i)<600
% pointList = status(i).PixelList; %每个连通区域的像素位置
% rIndex=pointList(:,2);cIndex=pointList(:,1);
% fill_hole(rIndex,cIndex)=0; %连通区域的面积不足600,置为背景颜色
% end
% end
fill_hole=bwareaopen(fill_hole,600); % bwareaopen消除区域像素点总数小于600的连通区域,与23-31行代码(已注释)等价
figure;
subplot(2,2,1);imshow(pic,[]);title('原图');
subplot(2,2,2);imshow(binary_img,[]);title('二值化');
subplot(2,2,3);imshow(result_expand,[]);title('膨胀');
subplot(2,2,4);imshow(fill_hole,[]);title('孔洞填充');
img_edge=edge(fill_hole,'sobel'); %sobel算子边缘检测
out_result=regionprops(fill_hole,'Area','Perimeter','Centroid'); %Area:连通区域像素点个数 Perimeter:连通区域周长 Centroid:连通区域质心
centroids = cat(1, out_result.Centroid); %获取连通区域质心
figure;
[B,L]=bwboundaries(fill_hole,'noholes'); %获取连通区域边界,和连通区域
RGB=label2rgb(L,'spring','c','shuffle'); %给连通区域上色
subplot(2,2,1);imshow(img_edge,[]);title('sobel算子边缘检测');
subplot(2,2,2);imshow(RGB,[]);title('陆地面积');
for i=1:size(out_result)
text(centroids(i,1), centroids(i,2),[num2str(i),':','面积=',num2str(out_result(i).Area)],'Color','b','FontSize',6);
end
hold on;
for j=1:length(B)
boundary=B{j};
plot(boundary(:,2),boundary(:,1),'b','LineWidth',1);
end
hold off;
subplot(2,2,3);imshow(RGB,[]);title('陆地边长');
for i=1:size(out_result)
text(centroids(i,1), centroids(i,2),[num2str(i),':','边长=',num2str(out_result(i).Perimeter)],'Color','b','FontSize',6);
end
hold on;
for j=1:length(B)
boundary=B{j};
plot(boundary(:,2),boundary(:,1),'b','LineWidth',1);
end
hold off;
%---------------------海洋部分--------------------------
sea=1-fill_hole; %先将原先处理好的二值图片进行灰度反转,将海洋区域置1,陆地区域置0
sea_status=regionprops(sea,'Area','Perimeter','Centroid');
sea_centroids=cat(1,sea_status.Centroid);
[B1,L1]=bwboundaries(sea,'noholes');
subplot(2,2,4);imshow(RGB,[]);title('海洋');
text(sea_centroids(1,1),sea_centroids(1,2),[num2str(i+1),':','面积=',num2str(sea_status.Area)],'Color','r','FontSize',10);
text(sea_centroids(1,1),sea_centroids(1,2)+50,[' 边长=',num2str(sea_status.Perimeter)],'Color','r','FontSize',10);
hold on;
for j=1:length(B1)
boundary=B1{j};
plot(boundary(:,2),boundary(:,1),'k','LineWidth',1);
end
hold off;
矩形检测:
从理论上看,矩形连通区域与其最小边界矩形的像素比是1,所以可自定义设置阈值大于0.95判断。
圆形检测:
从理论上看,设圆形半径为R,最小边界矩形即正方形边长为2R,圆形连通区域与其最小边界矩形的面积比为 π R 2 ( 2 R ) 2 = π 4 ≈ 0.7854 \dfrac{\pi R^2}{(2R)^2}=\dfrac{\pi}{4}\approx0.7854 (2R)2πR2=4π≈0.7854,所以可自定义设置阈值介于 [ 0.76 , 0.80 ] [0.76,0.80] [0.76,0.80]判断。
Matlab代码:
%-------------------2.对 4-2 的图像(将其转为灰度图像处理,即不利用颜色特征) ,通过分割,并基于形状特征实现圆和矩形的检测。---------------------
clc;
clear;
close all;
pic=imread('4-2.png');
gray_pic=rgb2gray(pic);
binary_img=1-im2bw(pic,0.73); %灰度图转换成二值图像,直接进行灰度反转,让图形区域置1
for i=202:265
binary_img(188,i)=1;
end
fill_hole=imfill(binary_img,'holes');
fill_hole=bwareaopen(fill_hole,10);
[B,L]=bwboundaries(fill_hole,'noholes');
out_result=regionprops(fill_hole,'Extent','Centroid','boundingbox'); %Extent:各连通区域像素点与最小边界像素点比值
centroids = cat(1, out_result.Centroid); %各连通区域质心
draw_rect=cat(1,out_result.BoundingBox); %各连通区域最小边界矩形
figure;
subplot(2,2,1);imshow(pic,[]);title('原图');
subplot(2,2,2);imshow(binary_img,[]);title('二值化');
subplot(2,2,3);imshow(fill_hole,[]);title('区域填充');
subplot(2,2,4);imshow(fill_hole,[]);title('圆和矩形检测');
hold on;
for i=1:size(out_result)
rectangle('position',draw_rect(i,:),'EdgeColor','y','LineWidth',2); %绘出各连通区域最小边界矩形
if out_result(i).Extent>0.95
text(centroids(i,1)-20, centroids(i,2)-10,'矩形','Color','b','FontSize',9);
text(centroids(i,1)-32, centroids(i,2)+10,num2str(out_result(i).Extent),'Color','b','FontSize',8);
elseif out_result(i).Extent>0.76&&out_result(i).Extent<0.80
text(centroids(i,1)-20, centroids(i,2)-10,'圆形','Color','b','FontSize',9);
text(centroids(i,1)-32, centroids(i,2)+10,num2str(out_result(i).Extent/(pi/4)),'Color','b','FontSize',8);
end
end
hold on;
for j=1:length(B)
boundary=B{j};
plot(boundary(:,2),boundary(:,1),'r','LineWidth',2);
end
hold off;