开发环境:win10,X86架构,基于Matlab2018b
整体代码思路:
Image = imread('cell1.jpg');
figure(1),subplot(231),imshow(Image);
title('原图');
Theshold = graythresh(Image);%取得图象的全局域值
Image_BW = im2bw(Image,Theshold);%二值化图象
subplot(232),imshow(Image_BW);
title('初次二值化图像');imwrite(Image_BW,'初次二值化图像_1.jpg');
Image_BW_medfilt= medfilt2(Image_BW,[9 9]);
subplot(233),imshow(Image_BW_medfilt);
title('中值滤波后的二值化图像');imwrite(Image_BW_medfilt,'中值滤波后的二值化图像_1.jpg');
Optimized_Image_BW = Image_BW_medfilt|Image_BW;
subplot(234),imshow(Optimized_Image_BW);
title('进行“或”运算优化图像效果');imwrite(Optimized_Image_BW,'进行“或”运算优化图像效果_1.jpg');%通过“初次二值化图像”与“中值滤波后的二值化图像”进行“或”运算优化图像效果
Reverse_Image_BW = ~Optimized_Image_BW;
subplot(235),imshow(Reverse_Image_BW);
title('优化后二值化图象取反');imwrite(Reverse_Image_BW,'优化后二值化图象取反_1.jpg');
%填充二进制图像的背景色,去掉细胞内的黑色空隙
Filled_Image_BW = bwfill(Reverse_Image_BW,'holes');
subplot(236), imshow(Filled_Image_BW);
title('已填充背景色的二进制图像');imwrite(Filled_Image_BW,'已填充背景色的二进制图像_1.jpg');
%对图像进行开运算,去掉细胞与细胞之间相粘连的部分
SE = strel('disk',5);
Open_Image_BW = imopen(Filled_Image_BW,SE);
figure(2), subplot(131),imshow(Open_Image_BW);
title('开运算后的图像');imwrite(Open_Image_BW,'开运算后的图像_1.jpg');
X2=~Open_Image_BW;
Qt=bwdist(X2);
L2=watershed(-Qt,8);
I=L2==0;
I2= Open_Image_BW&~I;
W2=bwareaopen(I2,200);%去除小面积
melt_W2 = melt( W2,6 );
subplot(132),imshow(melt_W2);title('分水岭分割后的图像');imwrite(W2,'分水岭分割后的图像_1.jpg');
%细胞不密集时需要对遗漏的单细胞进行补充
W3=Open_Image_BW-W2;
W4_1=bwareaopen(W3,150);%去除分水岭间隙产生的小面积
se1= strel('rectangle',[1 10]);
W4_2= imerode(W4_1, se1);%腐蚀掉分水岭间隙产生的大面积的竖条
se2= strel('disk',1);
W4= imdilate(W4_2, se2);%对得到的遗漏的单个细胞进行膨胀
W5=W4+melt_W2;
subplot(133),imshow(W5),title('优化后的分水岭后图像');imwrite(W5,'优化后的分水岭后图像_1.jpg');
save 分割.mat W5
%-----------------------------------------------
%-------------开始计算细胞数--------------------
%-----------------------------------------------
[Label,Number]=bwlabel(W5,8);%初步取得细胞个数
Array = bwlabel(W5,8);%取得贴标签处理后的图像
Sum = zeros(Number);
%依次统计贴标签后数组
for i=1:Number
[r,c] = find(Array==i);%获取相同标签号的位置,将位置信息存入[r,c]
rc = [r c];
Num = length(rc);%取得vc数组的元素的个数
Sum([i])=Num;%将元素个数存入Sum数组
end
N = 0;
%假如Sum数组中的元素大于了1000小于1500;表示有两个细胞相连,1500-2000,三个细胞;2000-2500,四个细胞,2500以上5个细胞(可以根据实际图像更改)
for i=1:length(Sum)
if (Sum(i))<500
N;
else if 1000<(Sum(i)) < 1500
N = N+1;
else if 1500<(Sum(i))<2000
N=N+2;
else if 2000<(Sum(i))<2500
N=N+3;
else N=N+4;
end
end
end
end
end
%-------------------------------------------
%------------------统计最终细胞数-----------
%-------------------------------------------
Number2 = Number+N;
figure(3);
imt=imread('cell1.jpg');
edgeshow(W5,imt);
效果图片: