在传统的分割方法中,有许多的方法能实现图像分割,如:蛇模型(snack)、测地活动轮廓模型(GAC)、Mumford-Shah 模型、Chan-Vese 模型、直方图方法、核方法等等
在这些方法中,又分为边缘图像分割的方法、区域图像分割的方法、统计与信息论的方法,感兴趣的小伙伴可以自行了解,这里就不再过多赘述,下面我会提供三种方法的MATLAB源码以及实现过程
测地活动轮廓模型(GAC)基于蛇模型的改进,这一模型的优点是消除了经典 Snake 模型依赖于曲线参数的缺陷,即它是内蕴的,克服了传统标注点方法不能改变拓扑的缺点。
% 测地活动轮廓模型 Main
clear
file_path = 'D:\thyroid nodule\';
img_list = dir(strcat(file_path));
matArray = cell(1,26);
% 设置GAC模型参数
R = [130,80,110,85,130,130,130,60,130,100,130,130,110]; % 行位置
C = [120,120,140,125,120,120,120,100,120,70,120,120,140]; % 列位置
refGrayVal = 20; % 灰度强度差异
thresh = 0.01; % 非负标量的阈值电平
iterations = 300; % 迭代次数
for i = 3:15
img_name = img_list(i).name;
img = imread(strcat(file_path,img_name));
%转成灰度图像
Igray = rgb2gray(img);
matArray{2*i-5} = Igray;
%运行GAC模型
BW = GAC(Igray,R(i-2),C(i-2),refGrayVal,thresh,iterations);
matArray{2*i-4} = BW;
end
% 将结果分两次呈现
% 第一次
figure;
subplot(4,4,1);imshow(matArray{1});title('原始图像');
subplot(4,4,2);imshow(matArray{2});title('分割结果');
hold on
for i = 3:16
%显示结果
if mod(i,2)==1
subplot(4,4,i);imshow(matArray{i});title('原始图像');
end
if mod(i,2)==0
subplot(4,4,i);imshow(matArray{i});title('分割结果');
end
end
hold off
%第二次
figure;
subplot(3,4,1);imshow(matArray{17});title('原始图像');
subplot(3,4,2);imshow(matArray{18});title('分割结果');
hold on
for i = 19:26
%显示结果
if mod(i,2)==1
subplot(3,4,i-16);imshow(matArray{i});title('原始图像');
end
if mod(i,2)==0
subplot(3,4,i-16);imshow(matArray{i});title('分割结果');
end
end
hold off
function BW = GAC(Igray,R,C,refGrayVal,thresh,iterations)
% 选择种子位置
seeds = false(size(Igray));
seeds(R,C) = true;
% 设置权重数组
W = graydiffweight(Igray, seeds, 'GrayDifferenceCutoff',refGrayVal);
% 初始化
BW = imsegfmm(W, seeds, thresh);
% 优化处理
BW = activecontour(Igray,BW,iterations);
end
蛇模型是一种基于能量最小化的方法,用于在图像中找到对象的边界。这个模型可以看作是一个弹性曲线,它在图像中移动,试图紧密地贴合到感兴趣对象的边界。
%Snack模型,主函数
clear
file_path = 'D:\thyroid nodule\';
img_list = dir(strcat(file_path));
matArray = cell(1,26);
for i = 3:15
img_name = img_list(i).name;
img = imread(strcat(file_path,img_name));
matArray{2*i-5} = img;
Iterations = 100;
%运行Snack模型
bw = Snack(img,Iterations);
matArray{2*i-4} = bw;
end
% 将结果分两次呈现
% 第一次
figure;
subplot(4,4,1);imshow(matArray{1});title('原始图像');
subplot(4,4,2);imshow(matArray{2});title('分割结果');
hold on
for i = 3:16
%显示结果
if mod(i,2)==1
subplot(4,4,i);imshow(matArray{i});title('原始图像');
end
if mod(i,2)==0
subplot(4,4,i);imshow(matArray{i});title('分割结果');
end
end
hold off
%第二次
figure;
subplot(3,4,1);imshow(matArray{17});title('原始图像');
subplot(3,4,2);imshow(matArray{18});title('分割结果');
hold on
for i = 19:26
%显示结果
if mod(i,2)==1
subplot(3,4,i-16);imshow(matArray{i});title('原始图像');
end
if mod(i,2)==0
subplot(3,4,i-16);imshow(matArray{i});title('分割结果');
end
end
hold off
function bw = Snack(img,Iterations)
% 显示图像
figure,imshow(img);
title('Origicle Image');
% 选择初始轮廓
h = imfreehand(gca);
% 创建二值掩膜
BW = createMask(h);
% 预处理图像
img = rgb2gray(img);
img = imnoise(img, 'gaussian', 0.05);
bw = activecontour(img, BW, Iterations);
end
由于这个方法的掩膜是由自己画的,产生的图像没有一起生成,这里就展示第一张图像的
直方图方法对区间的中心部分密度估计较准,边缘部分较差
% 直方图方法
clear
file_path = 'D:\thyroid nodule\';
img_list = dir(strcat(file_path));
matArray = cell(1,26);
threshold = [130,110,80,100,100,50,30,60,80,100,70,80,30];
for i = 3:15
img_name = img_list(i).name;
img = imread(strcat(file_path,img_name));
%转成灰度图像
Igray = rgb2gray(img);
matArray{2*i-5} = Igray;
% 生成直方图
[counts, grayLevels] = imhist(Igray);
% 绘制直方图
figure, stem(grayLevels, counts);
% 二值化
binary_img = (Igray <= threshold(i-2));
matArray{2*i-4} = binary_img;
end
% 将结果分两次呈现
% 第一次
figure;
subplot(4,4,1);imshow(matArray{1});title('原始图像');
subplot(4,4,2);imshow(matArray{2});title('分割结果');
hold on
for i = 3:16
%显示结果
if mod(i,2)==1
subplot(4,4,i);imshow(matArray{i});title('原始图像');
end
if mod(i,2)==0
subplot(4,4,i);imshow(matArray{i});title('分割结果');
end
end
hold off
%第二次
figure;
subplot(3,4,1);imshow(matArray{17});title('原始图像');
subplot(3,4,2);imshow(matArray{18});title('分割结果');
hold on
for i = 19:26
%显示结果
if mod(i,2)==1
subplot(3,4,i-16);imshow(matArray{i});title('原始图像');
end
if mod(i,2)==0
subplot(3,4,i-16);imshow(matArray{i});title('分割结果');
end
end
hold off
之后,我还会发布基于深度神经网络FCN模型的图像分割的实现过程(Python篇),感兴趣的小伙伴可以关注一下。