**
**
所谓图像分割是指根据灰度、彩色、空间纹理、几何形状等特征把图像划分成若干个互不相交的区域,使得这些特征在同一区域内表现出一致性或相似性,而在不同区域间表现出明显的不同。简单的说就是在一副图像中,把目标从背景中分离出来。
一般来说,用于图像分割的算法主要有五类:
第一种是阈值分割方法( threshold segmentation method)。阈值分割是基于区域的分割算法中最常用的分割技术之一,其实质是根据一定的标准自动确定最佳阈值,并根据灰度级使用这些像素来实现聚类。
优缺点:计算简单,效率较高;只考虑像素点灰度值本身的特征,一般不考虑空间特征,因此对噪声比较敏感,鲁棒性不高。
其次是区域增长细分( regional growth segmentation)。区域增长算法的基本思想是将具有相似属性的像素组合以形成区域,即,首先划分每个区域以找到种子像素作为生长点,然后将周围邻域与相似属性合并其区域中的像素。
**优缺点:**对复杂图像分割效果好;但是算法复杂,计算量大;分裂有可能破坏区域的边界。
第三种是边缘检测分割方法( edge detection segmentation method)。边缘检测分割算法是指利用不同区域的像素灰度或边缘的颜色不连续检测区域,以实现图像分割。边缘检测技术通常可以按照处理的技术分为串行边缘检测和并行边缘检测。串行边缘检测是要想确定当前像素点是否属于检测边缘上的一点,取决于先前像素的验证结果。并行边缘检测是一个像素点是否属于检测边缘高尚的一点取决于当前正在检测的像素点以及与该像素点的一些临近像素点。
**优缺点:**边缘定位准确;速度快;但是不能保证边缘的连续性和封闭性;在高细节区域存在大量的碎边缘,难以形成一个大区域,但是又不宜将高细节区域分成小碎片;
第四种是基于聚类的分割( segmentation based on clustering)。基于聚类的算法是基于事物之间的相似性作为类划分的标准,即根据样本集的内部结构将其划分为若干子类,以使相同类型的类尽可能相似、不同的类型的类尽可能不相似。同一聚类中的点使用相同颜色标记,不同聚类颜色不同。
**优缺点:**传统 FCM 算法没有考虑空间信息,对噪声和灰度不均匀敏感。
最后是基于CNN中弱监督学习的分割。它指的是为图像中的每个像素分配语义标签的问题,又称语义分割。它由三部分组成。 1)给出包含哪些对象的图像。 2)给出一个对象的边框。 3)图像中的对象区域用部分像素标记。
**优缺点:**解决图像中的噪声和不均匀问题。可以用于抑制噪声、特性提取、边缘检测、图像分割等图像处理问题,处理灰度图像;选择何种网络结构是这种方法要解决的主要问题。需要大量数据,速度非常慢,结构复杂,分割精度与数据量有关。
使用支持向量机(SVM)实现自然图像自动分类的方法,利用区域分割方法将图像区分为前景和背景图像,进而提取前景图像的特征向量作为SVM训练样本,实现语义分类器。利用matlab中libsvm工具箱中,可以让用户利用ginput来提取背景的样本点和前景(待分割出来的目标)的样本点作为训练样本,而不需实现指定背景和前景的样本点,也不用额外的小软件来查看某点的RGB值,ginput即可。
原图:
选择、提取像素点:
提取后:
代码:
%%
tic;
close all;
% clear;
clc;
format compact;
%%
pic = imread('cat.jpg'); %导入图片
figure;
imshow(pic);
%% 确定训练集
TrainData_background = zeros(20,3,'double');
TrainData_foreground = zeros(20,3,'double');
% 背景采样
msgbox('请选择20个背景样本点','Background Samples','help');
pause;
for run = 1:20
[x,y] = ginput(1); %ginput函数直接提取像素点
hold on;
plot(x,y,'r*');
x = uint8(x);
y = uint8(y);
TrainData_background(run,1) = pic(x,y,1);
TrainData_background(run,2) = pic(x,y,2);
TrainData_background(run,3) = pic(x,y,3);
end
% 待分割出来的前景采样
msgbox('请选择20个前景样本点','Foreground Samples','help');
pause;
for run = 1:20
[x,y] = ginput(1);
hold on;
plot(x,y,'ro');
x = uint8(x);
y = uint8(y);
TrainData_foreground(run,1) = pic(x,y,1);
TrainData_foreground(run,2) = pic(x,y,2);
TrainData_foreground(run,3) = pic(x,y,3);
end
% let background be 0 & foreground 1
TrainLabel = [zeros(length(TrainData_background),1); ...
ones(length(TrainData_foreground),1)];
%% 建立支持向量机 基于libsvm
TrainData = [TrainData_background;TrainData_foreground];
model = svmtrain(TrainLabel, TrainData, '-t 1 -d 1');
%% 进行预测 i.e.进行图像分割 基于libsvm
preTrainLabel = svmpredict(TrainLabel, TrainData, model);
[m,n,k] = size(pic);
TestData = double(reshape(pic,m*n,k));
TestLabal = svmpredict(zeros(length(TestData),1), TestData, model);
%%
ind = reshape([TestLabal,TestLabal,TestLabal],m,n,k);
ind = logical(ind);
pic_seg = pic;
pic_seg(~ind) = 0;
figure;
imshow(pic_seg);
figure;
subplot(1,2,1);
imshow(pic);
subplot(1,2,2);
imshow(pic_seg);
%%
toc;