Matlab implements image segmentation and target counting-morphological processing + watershed transformation method

Q number: 809315756

Based on morphological processing and watershed transformation, the foreground object segmentation and object counting in the image are realized, taking the soybean image as an example. The algorithm is implemented as follows:

1. Read the image and convert the image to grayscale. The implementation code is as follows:

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

2. Use the OTSU adaptive threshold algorithm to binarize the grayscale image and perform the inverse operation. The implementation code is as follows:

%% 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);

 

 3. Perform morphological processing on the binary image: perform the opening operation after the corrosion operation, and the implementation code is as follows:

%% 图像形态学处理
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)

  4. Perform distance transformation and initial watershed transformation on the binary image, and the implementation code is as follows:

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

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

 5. In general, the following call to imextendedmin should produce only small dots roughly in the middle of the cells being split. Overlay the mask on the original image using imshowpair and do the watershed transform again. The implementation code is as follows:

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)

 

6. Use the connected area marking method to count the number of targets, and mark the center point and the largest circumscribed rectangle. The implementation code is as follows:

[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) ]);

 The complete code is as follows:

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) ]);

 The above is all the code of matlab to realize image segmentation and target counting. If there are friends who don’t understand, welcome to leave a comment or send a private message, and you can also send a private message to the blogger for code customization.

Guess you like

Origin blog.csdn.net/qq_37904531/article/details/131130160