血细胞图像检测Matlab代码

发布时间:2024年01月04日

%% 预处理
clc;clear;close all;

%%主程序包含三个函数,分别是XingTaiXue、DongTai_OTSU、Hough,
%%分别对应了三种细胞计数与面积计算方法
I = imread('Orig_Cell.JPG');

%% 在原图画框,展示三种算法结果。
counts=1;%第几次裁剪细胞图像
while(1)
? ? %原图裁剪
? ? figure('Name','请拖动鼠标左键选择裁剪区域,并双击鼠标左键确定'),imshow(I);
? ? fprintf(['\n%%%%%%%%%%%%%%%%%%%%%% ?我是分割线,这是你第%d次裁剪细胞 ?' ...
? ? ? ? '%%%%%%%%%%%%%%%%%%%%%\n'],counts);
? ? counts=counts+1;
? ? % 定义裁剪区域
? ? Xcropped = imcrop([I]); %加中括号的目的是不在CommendWindow显示裁剪矩阵
? ? subplot(221); imshow(Xcropped); title('裁剪原图');

? ? % 形态学处理
? ? subplot(222); imshow(Xcropped); title('形态学处理'); hold on
? ? [XingTai,Num_XingTai,Area_XingTai] = XingTaiXue(Xcropped,1);

? ? %动态阈值处理
? ? M=256;
? ? Xcropped = Xcropped(:,:,1);
? ? subplot(223); imshow(Xcropped); title('动态阈值(OTSU)'); hold on
? ? [YuZhi,Num_Yuzhi,Area_YuZhi] = DongTai_OTSU(Xcropped,M,1);

? ? % 霍夫圆变换处理
? ? subplot(224); imshow(Xcropped); title('霍夫圆变换'); hold on
? ? %为了让霍夫圆在原图圈出
? ? [HuoFu,Num_Hough,Average_Hough_area] = Hough(Xcropped,1);

? ? %% 血细胞计数与面积计算
? ? fprintf('\n基于形态学的细胞个数统计:%d个\n',Num_XingTai);
? ? fprintf('基于形态学的细胞平均面积计算:%2.2f(pixels)\n',Area_XingTai);

? ? fprintf('\n基于OTSU动态阈值分割的细胞个数统计:%d个\n',Num_Yuzhi);
? ? fprintf('基于OTSU动态阈值分割的细胞平均面积计算:%2.2f(pixels)\n',Area_YuZhi);

? ? fprintf('\n基于Hough圆检测的细胞个数统计:%d个\n',Num_Hough);
? ? fprintf('基于Hough圆检测的细胞平均面积计算:%2.2f(pixels)\n', ...
? ? ? ? Average_Hough_area);
? ? %% 询问是否继续裁剪
? ? h=questdlg('你还想进行下一次裁剪吗?','下次否? ','Yes !','No !','Yes !');
? ? if strcmp(h,'No !') ? ?%选Yes则默认继续下次分割
? ? ? ? break
? ? end
end

DongTai_OTSU:

function [bw1,n,average_cell] = DongTai_OTSU(im,M,temp)
[m,n] = size(im);
p=ceil(m/M);
q=ceil(n/M);
bw1=zeros(m,n);

for i=1:p
    for j=1:q
        x1=0;x2=0;
        y1=0;y2=0;
        if j<q&&i<p
            tempI=im((i-1)*M+1:i*M,(j-1)*M+1:j*M);
            x1=(i-1)*M+1;x2=i*M;
            y1=(j-1)*M+1;y2=j*M;
        else if j==q&&i<p
                tempI=im((i-1)*M+1:i*M,(j-1)*M+1:end);
                x1=(i-1)*M+1;x2=i*M;
                y1=(j-1)*M+1;y2=n;
            else if i==p&&j<q
                    tempI=im((i-1)*M+1:end,(j-1)*M+1:j*M);
                    x1=(i-1)*M+1;x2=m;
                    y1=(j-1)*M+1;y2=j*M;
                else
                    tempI=im((i-1)*M+1:end,(j-1)*M+1:end);
                    x1=(i-1)*M+1;x2=m;
                    y1=(j-1)*M+1;y2=n;
                end
            end
        end
        
        T = graythresh(tempI);   %OTSU阈值
        tempBW=imbinarize(tempI,T);
        bw1(x1:x2,y1:y2)=tempBW;
    end
end
%%
OTSU_cell=not(bw1);
fill_image=imfill(OTSU_cell,'holes');%填充孔洞

% figure('Name','二值化填充后'),imshow(fill_image);
delete_image = imclearborder(fill_image,4);%删除和图像边界相连的色块。
% figure('Name','删除白色无关区域'),imshow(delete_image);
final_image = bwareaopen(delete_image,200);%删除噪点
% figure('Name','处理后图像'),imshow(final_image);
if temp~=0
    hold on
    [~,n]=bwlabel(final_image);%标签化并计算个数
    
    t=1;
    Area_lk=[];
    %% 求平均面积
    sum_cell=0;
    [B,L] = bwboundaries(final_image,'noholes');
    stats = regionprops(L,'Area','Centroid');   %计算图像区域中像素个数、中心
    for k1 = 1:length(B)      %B是轮廓,k1相当于label值
        boundary = B{k1};
        plot(boundary(:,2),boundary(:,1),'r','LineWidth',2)
        
        area= stats(k1).Area;    %求出每个区域的面积
        Area_lk(t)=area;
        sum_cell=sum_cell+area;  %面积累加
        %%设置图像中字符显示的属性
        text(boundary(1,2)-5,boundary(1,1)+5,num2str(k1),'Color','w',...
            'FontSize',9,'FontWeight','bold')
        text(boundary(1,2)-15,boundary(1,1)+20,num2str(Area_lk(t),'%2.2f\n'),...
            'Color','g','FontSize',10,'FontWeight','bold')
        t=t+1;
    end
    average_cell=sum_cell/length(B);%求出平均面积
end
end


Hough

function [bw,n,average_cell] = Hough(im,temp)
%%
%形态学操作
se = strel('disk',2);

I_BW = im2bw(im,graythresh(im));
Ie = imerode(I_BW,se);
Iobr = imreconstruct(Ie,I_BW);
Iobrd = imdilate(Iobr,se);
bw = imreconstruct(imcomplement(Iobrd),imcomplement(Iobr));

%%
Rmin = 13;
Rmax = 50;
%centersBright是圆心;radiiBright是圆的半径
[centersBright, radiiBright] = imfindcircles(bw,[Rmin Rmax],'ObjectPolarity','bright');
viscircles(centersBright, radiiBright,'EdgeColor','b');

if temp~=0
    
    hough_area=[];         %单个霍夫圆的面积
    n= length(radiiBright);
    for i=1:n       %半径的个数,即统计出来有几个圆
        plot(centersBright(i,1), centersBright(i,2), ...
            'bo', 'MarkerSize',radiiBright(i),'MarkerFaceColor','y');
        hough_area(i)=pi*(radiiBright(i)+0.01)^2;%计算霍夫单个圆面积,半径+1最匹配
        
        % 将每个霍夫变换标准圆的面积展示在图中
        text(centersBright(i,1),centersBright(i,2),num2str(i),'Color','r',...
            'FontSize',9,'FontWeight','bold')
        text(centersBright(i,1),centersBright(i,2)+15,num2str(hough_area(i),'%2.2f\n'),...
            'Color','g','FontSize',9,'FontWeight','bold')
    end
    average_cell=sum(hough_area)/n;
end
end

XingTaiXue

function [cell_final,n,average_cell] = XingTaiXue(original_picture,temp)

gray_picture=im2gray(original_picture);
BW_image=imbinarize(gray_picture,graythresh(original_picture));%转换为二值图像
BW_image=imcomplement(BW_image);%翻转黑白
BW_fill_black=imfill(BW_image,'holes');%填补黑色洞

%初步开运算减少白色区域
se1=strel('disk',14);
BW_open=imopen(BW_fill_black,se1);

%对比开运算前后图像,找出被删除的细胞
BW_delete=BW_fill_black-BW_open;

%开运算对比后图像,消除因细胞大小改变产生的细胞轮廓
se2=strel('disk',6);
BW_comparison=imopen(BW_delete,se2);

%对图像进行彻底但不消失细胞的侵蚀,使细胞不再连接
se3=strel('disk',10);
BW_erode=imerode(BW_open,se3);

%与此前消失的细胞的图像合并,恢复他们
BW_combined=BW_comparison+BW_erode;

%删除和图像边界相连的对象。
cell_final = imclearborder(BW_combined,4);

%% 细胞计数
if temp~=0
    hold on
    [~,n]=bwlabel(cell_final);%标签化并计算个数

    t=1;
    Area_lk=[];
    %求平均面积
    sum_cell=0;
    [B,L] = bwboundaries(cell_final,'noholes');
    stats = regionprops(L,'Area','Centroid');   %计算图像区域中像素个数、中心
    for k1 = 1:length(B)      %B是轮廓,k1相当于label值
        boundary = B{k1};
        plot(boundary(:,2),boundary(:,1),'r','LineWidth',2)

        area= stats(k1).Area;    %求出每个区域的面积
        Area_lk(t)=area;
        sum_cell=sum_cell+area;  %面积累加

        text(boundary(1,2)-5,boundary(1,1)+5,num2str(k1),'Color','w',...
            'FontSize',9,'FontWeight','bold')
        text(boundary(1,2)-15,boundary(1,1)+20,num2str(Area_lk(t),'%2.2f\n'),'Color','g',...
            'FontSize',10,'FontWeight','bold')    %%设置图像中字符显示的属性
        t=t+1;
    end
    average_cell=sum_cell/length(B);%求出平均面积
end
end

文章来源:https://blog.csdn.net/xdpcxq1029/article/details/135394275
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。