基于FCM的脑出血CT影像分割算法设计(二)
一、引言
对于上一篇文献而言,在对其进行详细的图像处理后仍未能获得满意的效果。经过反思后发现,在上篇文章中所处理的CT图像中的血块与脑组织的像素范围存在重叠现象。于是我们转而选择了一副全新的CT图像作为样本展开操作,并最终获得了理想的实验结果。
设计要求:
① 在分析CT成像原理的基础上,设计脑出血CT图像的分割算法;
② 可实现疑似血肿区域的分割与提取;
③ 可估算疑似血肿区域的面积或体积;
通过编程技术实现所述的功能的同时,并对分割算法的稳定性、准确性以及精确度进行客观评价
二、设计步骤
1、预处理
通过阈值分割对颅骨进行去除操作
%预处理 去除颅骨部分
[m,n]=size(image); %用m,n表示图像的像素坐标
for i=1:m
for j=1:n % #遍历每个像素
if image(i,j)>220 %#当像素的灰度值大于220时,将该灰度更改为0
image(i,j)=0;
end
end
end
imwrite(image,'2image.jpg') %#将处理后的图像重新命名
figure
imshow(image);
代码解读


可以看出,在进行经由阈值分割处理后的图像分析时发现,在白色颅骨区域确实实现了较好的去除非 wanted区域。然而这一去除非 wanted区域的效果尚欠 ideal。经过不断调整试验后可找到最适的分割阈值以获得最优的结果。此外还可以借助形态学运算手段实现颅骨的去除(该队友已通过深入研究文献资料完成了这项工作(如有需要可进一步详述))。
2、FCM模糊聚类
% FCM聚类
clusterNum = 3; % 聚类数目,这里设置为3
fcmOptions = [3, 100, 1e-2, 1]; % FCM参数设置
[centers, U] = fcm(double(image(:)), clusterNum, fcmOptions);
% 提取边缘
backgroundIdx = find(U(1,:) > 0.5); % 背景类别索引
groundIdx = find(U(2,:) > 0.5); %
foregroundIdx = find(U(3,:) > 0.5); % 前景类别索引
% fgroundIdx = find(U(4,:) > 0.5);
% 创建边缘图像
edgeImage = zeros(size(image));
edgeImage(backgroundIdx) = 255; % 背景像素设为白色
edgeImage(groundIdx) = 125; % 灰色
edgeImage(foregroundIdx) = 0; % 前景像素设为黑色
% edgeImage(fgroundIdx) = 125;%
% 显示边缘图像
figure
imshow(uint8(edgeImage)),title('聚类数目为3');
imwrite(edgeImage,'3image.jpg')
代码解读

利用聚类算法处理后生成三个预期划分的区域,在这些区域中分离出的血块具有良好的聚类效果,并与周围脑组织区域几乎没有像素值范围上的交集。这种结构特征使得通过阈值分割能够有效地去除黑色脑组织以及其他环状结构。
%将图像边缘细分
[m,n]=size(edgeImage); %用m,n表示图像的像素坐标
for i=1:m
for j=1:n % #遍历每个像素
if edgeImage(i,j)>220 %#当像素的灰度值大于220时,将该灰度更改为0
edgeImage(i,j)=0;
end
end
end
imwrite(edgeImage,'4image.jpg') %#将处理后的图像重新命名
figure
imshow(edgeImage);
M=strel('disk',2);%创建一个圆形结构元素,2是从结构元素半径,沿水平轴和垂直轴的度量
CImage=imopen(edgeImage,M);
figure
imshow(CImage);
imwrite(CImage,'youzao.jpg');
代码解读

经分析可得,在此过程中已经较为准确地分离出血块组织;然而,在此过程中仍存在一些零散的像素干扰。为此建议将这些干扰点标记为噪声并予以去除
%去除噪点
binary_image=imread('youzao.jpg');
cc = bwconncomp(binary_image);
% 获取每个连通区域的像素数量
numPixels = cellfun(@numel, cc.PixelIdxList);
% 设置阈值,删除小于阈值的连通区域
threshold = 750; % 根据小点的大小调整阈值
binary_image_cleaned = binary_image;
binary_image_cleaned(vertcat(cc.PixelIdxList{numPixels < threshold})) = 0;
figure
% 显示清理后的二值图像
subplot(121);imshow('3.jpg');title('原图');
subplot(122);imshow(binary_image_cleaned);title('血块二值图');
代码解读

截止到目前,已经实现了对血块的分割与提取。接下来是计算。
3、面积计算
%读取脑出血图像
S=binary_image_cleaned;
% 计算二值图像中非零像素的总数
nonZeroPixels = sum(S(:));
% 计算脑出血的面积(以像素为单位)
bleedingArea = nonZeroPixels;
% 将面积转换为实际单位(例如平方毫米)
% 如果你知道图像的比例尺,可以使用它来进行转换
% 否则,你需要根据图像的分辨率来估计转换因子
conversionFactor = 0.25; % 假设每个像素代表0.25平方毫米
bleedingAreaInSquareMillimeters = bleedingArea * conversionFactor;
% 显示脑出血面积
disp(['脑出血面积(像素):' num2str(bleedingArea)]);
% disp(['脑出血面积(平方毫米):' num2str(bleedingAreaInSquareMillimeters)]);
代码解读
计算结果

主要基于统计像素数量的方法被用来评估出血区域的大小,并且是以单个像素为基本单位进行测量。若需采用国家规定的面积计量标准,则应依据不同图像的情况进行判断和确定。
三、结论与反思
采用该算法体系后,我们实现了对血肿区域的有效分离。这一过程包括获取目标区域及其面积信息两部分工作。基于FCM聚类算法,在实际应用中发现每次聚类结果在形状上一致但呈现不同色调,并给后续处理带来了一定困难;然而经过观察发现其变化呈现出周期性特征,在约三次迭代内即可恢复到理想状态并完成数值计算工作;此外该方法在分割精度方面表现优异:无论是基于阈值的操作还是面积计算均采用像素级别精确处理和运算
基于实验结果表明,在图像处理过程中所得处理后的图片质量也是该领域研究的重要考量之一。当雪景区域与颅内灰度值范围存在相近程度时,则会显著影响图像分割的效果;因此本文所采用的方法将不再适用。
