本文主讲图像分割部分的内容,这个只是图像处理中的一个部分。我总觉得,学习某个方面知识的时候,不要满足于对于该模块的学习,也要对于该模块在实际应用中整个应用的运作情况做些大体了解,了解其基本的运作原理。个人觉得这对于我们加深对这个模块的理解非常有帮助。对于整个图像处理大概的框架,我查阅资料后画了一个图:
目录
图像分割
概念:把图像空间按照一定的要求分成一些“有意义”的区域的技术叫做图像分割。对于本文需要讲述的图像分割技术,我画了一个知识结构图:
图像分割从本质上说是将各像素(像素块)进行分类的过程。分类所依据的特性可以是像素的灰度值、颜色或多谱特性、空间特性和纹理特性等。基于阈值选取的图像分割方法:
设输入图像为,输出图像为
,阈值为T,则
阈值变换:
比如数组 a = [120, 254, 0, 200, 99];设定一个阈值125, 并对a进行阈值变换, 那么a中凡是大于125的, 则变为255, 小于等于125的则变为0。这样a经过阈值变换后变为[0, 255, 0, 255, 0] 。
语法: BW = im2bw(I, level); % level的形式在下文会列举
话不多说,直接上代码:
% 读取matlab自带的图像gantrycrane,并提取边缘
I=imread('gantrycrane.png');
figure; %创建一个新的图窗窗口
imhist(I);
title('直方图');
newI=im2bw(I,100/255);
% 根据上面直方图选择阈值100,划分图像的前景和背景
figure;
subplot(1,2,1);imshow(I);
title('原始图像');
subplot(1,2,2);imshow(newI);
title('分割后图像');
运行结果如下:
由于篇幅有限,我就每一个大类列举一个方法来讲解。
基于阈值选取的图像分割方法
直方图阈值法
阈值的选择,可以通过观察灰度直方图来选择。当灰度图像中画面比较简单且对象物体的灰度分布比较有规律,背景和对象物体在图像的灰度直方图上各自形成一个波峰,由于每两个波峰间形成一个低谷,因而选择双峰间低谷处所对应的灰度值为阈值,可将两个区域分离。把这种通过选取直方图阈值来分割目标和背景的方法称为直方图阈值双峰法
例子分析:这张图片是我从百度上下载的野菊花和其对应的灰度直方图
从灰度直方图中可以看出,有一个谷底位于150左右的位置,接下来对其应用阈值分割的方法,选取两个不同的阈值->90和150。分别用matlab打印出来查看效果:
具体代码如下:
I=imread('flower.jpg');
Image90 = im2bw(I,95/255);
Image150 = im2bw(I,150/255);
% 根据上面直方图选择阈值100,划分图像的前景和背景
figure;
subplot(1,3,1);imshow(I);
title('(a) 原始图像');
subplot(1,3,2);imshow(Image90);
title('(b) 阈值为90时');
subplot(1,3,3);imshow(Image150);
title('(c) 阈值为150时');
基于区域的图像分割方法
四叉树分解
四叉树的简单分裂算法:
设R代表整个正方形图像区域,P代表逻辑谓词。从最高层开始,把R连续分裂成越来越小的1/4的正方形子区域Ri,并且始终使P(Ri)=TRUE(规定区域内满足相同或者相似的条件)。如果P(R) =FALSE(区域内像素区域之间不满足相同或者相似的条件),那么就将图像分成四等分。如果P(Ri)=FALSE,那么就将Ri分成四等分,如此类推,直到Ri为单个象素。图像的四叉分解
四叉树结构如下:
matlab代码如下:(matlab中自带的例子稍加修改,详情可输入help qtdecomp查看~):
%自带图片liftingbody.png
I = imread('liftingbody.png');
blocks = imread('liftingbody.png');
S = qtdecomp(I,0.27);
for dim = [512 256 128 64 32 16 8 4 2 1]
numblocks = length(find(S==dim));
if (numblocks > 0)
[values, r, c] = qtgetblk(blocks, S, dim)
;%读取S中所有尺寸为dim x dim的block,r和c是所有块的左上角点位置
values(1:end,1,:)=0;
%修改所有block的左、上边界为黑色
values(1,1:end,:)=0;
blocks= qtsetblk(blocks,S,dim,values);
%用修改后的block去替换S中的现有block
end
end
blocks(end,1:end) = 1;
blocks(1:end,end) = 1;
subplot(1,2,1);imshow(I);
title('(a)原始图像');
subplot(1,2,2), imshow(blocks,[])
title('(b)四叉树分解效果');
实验截图:
基于边缘检测的图像分割
边缘检测
图像边缘:图像边缘是图像最基本的特征,边缘在图像分析中起着重要的作用。所谓边缘指图像局部特性的不连续性。例如灰度级、纹理结构或颜色的突变处成为边缘。比较常见的突变是灰度级突变。灰度级突变有:
- 阶跃状
- 脉冲状
- 屋顶状
边缘检测中,其一阶导数在边缘位置取得极值。二阶导数在边缘位置处得零。
边缘上的这种变化可以通过微分算子进行检测:
- ¨一阶导数:通过梯度来计算
- ¨二阶导数:通过拉普拉斯算子来计算
一阶导数:用梯度算子来计算
- ¨特点:对于亮的边,边的变化起点是正的,结束是负的。对于暗边,结论相反。常数部分为零。
- ¨用途:用于检测图像中边的存在
二阶导数:通过拉普拉斯来计算
- ¨特点:二阶微分在亮的一边是正的,在暗的一边是负的。常数部分为零。
- ¨用途:确定边上的像素是在亮的一边,还是暗的一边,0用于确定边的准确位置
详细点此图像处理边缘检测的微分算子
接下来动手实践,我选取了素有图像处理“标准图”之称的Lena的照片。
实验代码:
I0=imread('lenna.tif');
figure;
imhist(I);
I=rgb2gray(I0);%转化为灰度图像
figure;
subplot(2,3,1);imshow(I);
title('原图像');
I90 = im2bw(I,110/255);
disp('Roberts算子自动选择阈值为:');
disp(110/255);
subplot(2,3,2);imshow(I90);
title('阈值为110的灰度图像');
BW1=edge(I,'roberts'); %以自动阈值选择法地图像进行Roberts算子检测
[BW1,thresh1]=edge(I,'roberts');
%返回当前Roberts算子边缘检测的阈值
disp('Roberts算子自动选择阈值为:');
disp(thresh1);
subplot(2,3,3);imshow(BW1);
title({'自动阈值的Roberts';'算子检测';thresh1*255});
BW2=edge(I,'sobel'); %以自动阈值选择法地图像进行sobel算子检测
[BW2,thresh2]=edge(I,'sobel'); %返回当前Roberts算子边缘检测的阈值
subplot(2,3,4);imshow(BW2);
title({'自动阈值的sobel算子'; '边缘检测';thresh2*255});
BW3=edge(I,'prewitt'); %以自动阈值选择法地图像进行prewitt算子检测
[BW3,thresh3]=edge(I,'prewitt'); %返回当前prewitt算子边缘检测的阈值
subplot(2,3,5);imshow(BW3);
title({'自动阈值的prewitt';'算子边缘检测';thresh3*255});
I90 = im2bw(I,70/255);
subplot(2,3,6);imshow(I90);
title('阈值为70的灰度图像');
图像灰度直方图:
实验结果: