Matlab实现图像分割及目标计数-形态学处理+分水岭变换方法

Q号:809315756

基于形态学处理和分水岭变换实现图像中前景目标分割及目标计数,以黄豆图像为例。算法实现如下:

一、读取图像并将图像灰度化,实现代码如下:

img=imread('2.jpg'); %读取到一张图片
figure
subplot(211)
imshow(img);title('原始图像','fontsize',14);
subplot(212)
grayImg=rgb2gray(img);
imshow(grayImg);title('灰度图像','fontsize',14)

二、利用OTSU自适应阈值算法将灰度图像二值化处理后并取反运算,实现代码如下:

%% otsu二值化处理
Th=graythresh(grayImg);
binaryImg1=imbinarize(grayImg,Th);%自适应阈值
binaryImg2=imcomplement(binaryImg1);
figure
subplot(121);imshow(binaryImg1);title('otsu二值化','fontsize',14);
subplot(122);imshow(binaryImg2);title('二值图像求反运算','fontsize',14);

 

 三、对二值图像进行形态学处理:腐蚀运算后进行开运算,实现代码如下:

%% 图像形态学处理
se =strel('disk',3) ;%创建一个指定半径3的平面圆盘形的结构元素
rodeImg=imerode(binaryImg2,se);%腐蚀
openImg=imopen(rodeImg,se);%开运算
figure;
subplot(121);imshow(rodeImg);title('腐蚀运算','fontsize',14)
subplot(122);imshow(openImg);title('开运算','fontsize',14)

  四、对二值图像进行距离变换和初次分水岭变换,实现代码如下:

distBinary = -bwdist(~openImg);%二值图像的距离变换
figure
imshow(distBinary,[])
title('距离变换图像','fontsize',14)

Ld = watershed(distBinary);
figure
imshow(label2rgb(Ld))
title('初次分水岭变换后图像','fontsize',14)

 五、通常,对imextendedmin的以下调用应该只产生大致位于要分割的单元格中间的小点。使用imshowpair将蒙版叠加在原始图像上,并再次进行分水岭变换。实现代码如下:

mask = imextendedmin(distBinary,0.95);
figure
imshowpair(openImg,mask,'blend')
title('复合图像','fontsize',14)
%修改距离变换,使其仅在所需位置具有最小值,然后重复上述分水岭步骤。
distBinary2 = imimposemin(distBinary,mask);
Ld2 = watershed(distBinary2);
openImg2 = openImg;
openImg2(Ld2 == 0) = 0;

figure
imshow(openImg2)
title('去除粘连后二值图像','fontsize',14)

 

六、利用连通区域标记法统计目标数量, 并且标记中心点和最大外接矩形,实现代码如下:

[B,L,N]=bwboundaries(openImg2,4);
centroid = regionprops(L,'Centroid');%'Centroid'每个区域的质心(重心)
figure
imshow(img)
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','r','LineWidth',1);%绘制矩形,边框颜色为黄色
    text(centroid(i,1).Centroid(1,1)-15,centroid(i,1).Centroid(1,2)-15, num2str(i),'Color', 'k','fontsize',16);  
end
title(['黄豆数量:',num2str(N) ],'fontsize',14)
disp(['图中黄豆数量为:',num2str(N) ]);

 完整代码如下:

clc;clear;close all;
%读入图片 灰度处理
img=imread('2.jpg'); %读取到一张图片
figure
subplot(121)
imshow(img);title('原始图像','fontsize',14);
subplot(122)
grayImg=rgb2gray(img);
imshow(grayImg);title('灰度图像','fontsize',14)

%% otsu二值化处理
Th=graythresh(grayImg);
binaryImg1=imbinarize(grayImg,Th);%自适应阈值
binaryImg2=imcomplement(binaryImg1);
figure
subplot(121);imshow(binaryImg1);title('otsu二值化','fontsize',14);
subplot(122);imshow(binaryImg2);title('二值图像求反运算','fontsize',14);
% binaryImg2=binaryImg1;
%% 图像形态学处理
se =strel('disk',3,0) ;%创建一个指定半径5的平面圆盘形的结构元素,此时缺省值是4
rodeImg=imerode(binaryImg2,se);%腐蚀
openImg=imopen(rodeImg,se);%开运算
figure;
subplot(121);imshow(rodeImg);title('腐蚀运算','fontsize',14)
subplot(122);imshow(openImg);title('开运算','fontsize',14)

%% 二值图像的距离变换 分水岭变换

% distBinary = -bwdist(~binaryImg2);%二值图像的距离变换
distBinary = -bwdist(~openImg);%二值图像的距离变换
figure
imshow(distBinary,[])
title('距离变换图像','fontsize',14)

Ld = watershed(distBinary);
figure
imshow(label2rgb(Ld))
title('初次分水岭变换后图像','fontsize',14)
%理想情况下,对imextendedmin的以下调用应该只产生大致位于要分割的单元格中间的小点。
%将使用imshowpair将蒙版叠加在原始图像上。
mask = imextendedmin(distBinary,0.95);
figure
imshowpair(openImg,mask,'blend')
title('复合图像','fontsize',14)
%修改距离变换,使其仅在所需位置具有最小值,然后重复上述分水岭步骤。
distBinary2 = imimposemin(distBinary,mask);
Ld2 = watershed(distBinary2);
openImg2 = openImg;
openImg2(Ld2 == 0) = 0;

figure
imshow(openImg2)
title('去除粘连后二值图像','fontsize',14)

[B,L,N]=bwboundaries(openImg2,4);
centroid = regionprops(L,'Centroid');%'Centroid'每个区域的质心(重心)
figure
imshow(img)
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','r','LineWidth',1);%绘制矩形,边框颜色为黄色
    text(centroid(i,1).Centroid(1,1)-15,centroid(i,1).Centroid(1,2)-15, num2str(i),'Color', 'k','fontsize',16);  
end
title(['黄豆数量:',num2str(N) ],'fontsize',14)
disp(['图中黄豆数量为:',num2str(N) ]);

 以上就是matlab实现图像分割及目标计数的全部代码。如果有不懂的小伙伴儿,欢迎评论留言或者私信,代码订制也可私信博主。

猜你喜欢

转载自blog.csdn.net/qq_37904531/article/details/131130160