基于形态学处理+分水岭变换实现图像的分割及计算图片内物体的个数
编码解决思路
1. 读取图片并灰度化处理
clc;clear;close all;
%读入图片 灰度处理
figure
img=imread('C:\Users\Administrator\Desktop\黄豆.png'); %读取到一张图片
subplot(121)
imshow(img);title('原图','fontsize',16);
axis on
subplot(122)
grayImg=rgb2gray(img);
imshow(grayImg);title('灰度','fontsize',16)
axis on
2. 自适应阈值二值化处理后并取反运算
%% 二值化处理后取反运算
figure
Th=graythresh(grayImg);
binaryImg1=imbinarize(grayImg,Th);%自适应阈值
binaryImg2=imcomplement(binaryImg1);
subplot(121);imshow(binaryImg1);title('自适应阈值','fontsize',16);axis on
subplot(122);imshow(binaryImg2);title('图像求反运算','fontsize',16);axis on
3. 图像形态学处理
%% 图像形态学处理:腐蚀后开运算
se =strel('disk',5,4) ;%创建一个指定半径5的平面圆盘形的结构元素,N可以被忽略,此时缺省值是4
rodeImg=imerode(binaryImg2,se);%腐蚀
openImg=imopen(rodeImg,se);%开运算
figure;
subplot(121);imshow(rodeImg);title('腐蚀','fontsize',16)
subplot(122);imshow(openImg);title('开运算','fontsize',16)
4. 二值图像的距离变换、分水岭变换
%% 二值图像的距离变换 分水岭变换
figure
distBinary = -bwdist(~openImg);%二值图像的距离变换
imshow(distBinary,[])
figure
Ld = watershed(distBinary);
imshow(label2rgb(Ld))
理想情况下,对imextendedmin的以下调用应该只产生大致位于要分割的单元格中间的小点。将使用imshowpair将蒙版叠加在原始图像上。修改距离变换,使其仅在所需位置具有最小值,然后重复上述分水岭步骤。
%理想情况下,对imextendedmin的以下调用应该只产生大致位于要分割的单元格中间的小点。
%将使用imshowpair将蒙版叠加在原始图像上。
figure
mask = imextendedmin(distBinary,0.95);
imshowpair(openImg,mask,'blend')
%修改距离变换,使其仅在所需位置具有最小值,然后重复上述分水岭步骤。
distBinary2 = imimposemin(distBinary,mask);
Ld2 = watershed(distBinary2);
openImg2 = openImg;
openImg2(Ld2 == 0) = 0;
figure
imshow(openImg2)
程序运行结果
MATLAB程序源代码(全部代码)
clc;clear;close all;
%读入图片 灰度处理
figure
img=imread('C:\Users\Administrator\Desktop\黄豆.png'); %读取到一张图片
subplot(121)
imshow(img);title('原图','fontsize',16);
axis on
subplot(122)
grayImg=rgb2gray(img);
imshow(grayImg);title('灰度','fontsize',16)
axis on
%% 二值化处理
figure
Th=graythresh(grayImg);
binaryImg1=imbinarize(grayImg,Th);%自适应阈值
binaryImg2=imcomplement(binaryImg1);
subplot(121);imshow(binaryImg1);title('自适应阈值','fontsize',16);axis on
subplot(122);imshow(binaryImg2);title('图像进行求反运算','fontsize',16);axis on
%% 图像形态学处理:腐蚀后开运算
se =strel('disk',5,0) ;%创建一个指定半径5的平面圆盘形的结构元素,此时缺省值是4
% se =strel('square',5);
% se =strel('rectangle',[6 2]);
rodeImg=imerode(binaryImg2,se);%腐蚀
openImg=imopen(rodeImg,se);%开运算
figure;
subplot(121);imshow(rodeImg);title('腐蚀','fontsize',16)
subplot(122);imshow(openImg);title('开运算','fontsize',16)
%% 二值图像的距离变换 分水岭变换
figure
distBinary = -bwdist(~openImg);%二值图像的距离变换
imshow(distBinary,[])
figure
Ld = watershed(distBinary);
imshow(label2rgb(Ld))
%理想情况下,对imextendedmin的以下调用应该只产生大致位于要分割的单元格中间的小点。
%将使用imshowpair将蒙版叠加在原始图像上。
figure
mask = imextendedmin(distBinary,0.95);
imshowpair(openImg,mask,'blend')
%修改距离变换,使其仅在所需位置具有最小值,然后重复上述分水岭步骤。
distBinary2 = imimposemin(distBinary,mask);
Ld2 = watershed(distBinary2);
openImg2 = openImg;
openImg2(Ld2 == 0) = 0;
figure
imshow(openImg2)
[B,L,N]=bwboundaries(openImg2,4);
disp(['图中共有',num2str(N),'个连通分量' ]);
fig=figure;
image(img);
hold on;
for k=1:length(B)
boundary=B{k};
if(k>N)
plot(boundary(:,2),boundary(:,1),'r','LineWidth',2); %显示内部边界
else
plot(boundary(:,2),boundary(:,1),'y','LineWidth',2); %显示外部边界
end
end
% figure(7);
% imshow(grayImg);
%% 单个枸杞面积
STATS=regionprops(L,'Area');%获得每个联通域的面积大小,保存在数组area中
area=[STATS.Area];%每个连通区域的面积
centroid = regionprops(L,'Centroid');%'Centroid'每个区域的质心(重心)
for i=1:N
hold on
plot(centroid(i,1).Centroid(1,1),centroid(i,1).Centroid(1,2), 'ro','MarkerFaceColor','r');
end
status=regionprops( L,'BoundingBox');%regionprops统计被标记的区域的面积分布,显示区域总数。'Bounding
for i=1:N
rectangle('position',status(i).BoundingBox,'edgecolor','g','LineWidth',1);%绘制矩形,边框颜色为黄色
text(centroid(i,1).Centroid(1,1)-15,centroid(i,1).Centroid(1,2)-15, num2str(i),'Color', 'm','fontsize',16);
end
disp(['图中枸杞数量为:',num2str(N) ]);
%
% magnifyOnFigure(fig, 'displayLinkStyle', 'straight',...%显示连接线为一条实线
% 'EdgeColor', 'k',...%边框颜色
% 'magnifierShape', 'rectangle',...%放大的形状为矩形,默认为矩形
% 'frozenZoomAspectratio', 'on',...%强制在X轴和Y轴上使用相同的缩放倍数,以保持纵横比
% 'edgeWidth', 1);%边框线宽
% magnifyOnFigure(fig, 'displayLinkStyle', 'straight',...%显示连接线为一条实线
% 'EdgeColor', 'k',...%边框颜色
% 'magnifierShape', 'rectangle',...%放大的形状为矩形,默认为矩形
% 'frozenZoomAspectratio', 'on',...%强制在X轴和Y轴上使用相同的缩放倍数,以保持纵横比
% 'edgeWidth', 1);%边框线宽