武汉理工大学《图像处理程序设计》说明书
1.引言
所谓图像分割是指根据灰度、彩色、空间纹理、几何形状等特征把图像划分成若干个互不相交的区域,使得这些特征在同一区域内,表现出一致性或相似性,而在不同区域间表现出明显的不同[37].简单的讲,就是在一幅图像中,把目标从背景中分离出来,以便于进一步处理。图像分割是图像处理与计算机视觉领域低层次视觉中最为基础和重要的领域之一,它是对图像进行视觉分析和模式识别的基本前提.同时它也是一个经典难题,到目前为止既不存在一种通用的图像分割方法,也不存在一种判断是否分割成功的客观标准。
阈值法是一种传统的图像分割方法,因其实现简单、计算量小、性能较稳定而成为图像分割中最基本和应用最广泛的分割技术.已被应用于很多的领域,例如,在红外技术应用中,红外无损检测中红外热图像的分割,红外成像跟踪系统中目标的分割;在遥感应用中,合成孔径雷达图像中目标的分割等;在医学应用中,血液细胞图像的分割,磁共振图像的分割;在农业工程应用中,水果品质无损检测过程中水果图像与背景的分割。在工业生产中,机器视觉运用于产品质量检测等等。在这些应用中,分割是对图像进一步分析、识别的前提,分割的准确性将直接影响后续任务的有效性,其中阈值的选取是图像阈值分割方法中的关键技术。
2.阈值分割的基本概念
图像阈值化分割是一种最常用,同时也是最简单的图像分割方法,它特别适用于目标和背景占据不同灰度级范围的图像[1]。它不仅可以极大的压缩数据量,而且也大大简化了分析和处理步骤,因此在很多情况下,是进行图像分析、特征提取与模式识别之前的必要的图像预处理过程。图像阈值化的目的是要按照灰度级,对像素集合进行一个划分,得到的每个子集形成一个与现实景物相对应的区域,各个区域内部具有一致的属性,而相邻区域布局有这种一致属性。这样的划分可以通过从灰度级出发选取一个或多个阈值来实现。
阈值分割法是一种基于区域的图像分割技术,其基本原理是:通过设定不同的特征阈值,把图像像素点分为若干类.常用的特征包括:直接来自原始图像的灰度或彩色特征;由原始灰度或彩色值变换得到的特征.设原始图像为f(x,y),按照一定的准则在f(x,y)中找到特征值T,将图像分割为两个部分,分割后的图像为
.,.,,10tyxfbtyxfbyxg
若取 :b0=0(黑),b1=1(白),即为我们通常所说的图像二值化。
武汉理工大学《图像处理程序设计》说明书
(原始图像) (阈值分割后的二值化图像)
一般意义下,阈值运算可以看作是对图像中某点的灰度、该点的某种局部特性以及该点在图像中的位置的一种函数,这种阈值函数可记作
T(x,y,N(x,y),f(x,y))
式中,f(x,y)是点(x,y)的灰度值;N(x,y)是点(x,y)的局部邻域特性.根据对T的不同约束,可以得到3种不同类型的阈值[37],即
点相关的全局阈值T=T(f(x,y))
(只与点的灰度值有关)
区域相关的全局阈值T=T(N(x,y),f(x,y))
(与点的灰度值和该点的局部邻域特征有关)
局部阈值或动态阈值T=T(x,y,N(x,y),f(x,y))
(与点的位置、该点的灰度值和该点邻域特征有关)
所有这些阈值化方法,根据使用的是图像的局部信息还是整体信息,可以分为上下文无关(non-contextual)方法(也叫做基于点(point-dependent)的方法)和上下文相关(contextual)方法(也叫做基于区域(region-dependent)的方法);根据对全图使用统一阈值还是对不同区域使用不同阈值,可以分为全局阈值方法(global
thresholding)和局部阈值方法(local thresholding,也叫做自适应阈值方法adaptive
thresholding);另外,还可以分为双阈值方法(bilever thresholding)和多阈值方法(multithresholding)
3. 设计原理说明
这次VC++设计主要是基于迭代阈值图像分割法,它的设计方法如下。初始阈值选取为图像的平均灰度T0,然后用T0将图像的象素点分作两部分,计算两部分各自的平均灰度,小于T0的部分为TA,大于T0的部分为TB
计算 21BATTT ,将T1 作为新的全局阈值代替T0,重复以上过程,如此迭代,直至TK 收敛,即TK+1 =TK
经试验比较,对于直方图双峰明显,谷底较深的图像,迭代方法可以较快地获得满意结果。
对于背景和物体直方图双峰明显的图像进行迭代阈值分割,把目标从背景中分离出来,以便于进一步处理。此次设计就是利用VC平台建立一个软件程序对图像武汉理工大学《图像处理程序设计》说明书
进行迭代阈值分割。VC界面比比较简洁,主要功能是打开目标背景BMP图像文件,并且在主界面下显示图像。通过对图像的迭代阈值分割操作,然后将已经分割的图像在主界面下显示。
4.算法流程设计
Fig.1算法流程图
5.实现步骤
1) 打开VC++软件,进入主界面,建立一个单文档的应用项目。
2) 在主框架添加菜单“图像处理”,并在此菜单下添加如下子菜单“显示原图像”、“图像阈值分割”、“显示图像分割结果”
3)把代码输入后编译通过,实现“显示原图像”功能,并以对话框的形式显示
4)对图像作“迭代阈值分割”处理
5)在主界面下显示“迭代阈值分割”的图像,并以对话框的形式显示。
6)保存图像文件
打开图像 显示图像 对图像进行阈值分割
显示处理后的图像 结束 开始 武汉理工大学《图像处理程序设计》说明书
6.运行结果的截图
Fig.2主界面
Fig.3 显示原目标背景图像
武汉理工大学《图像处理程序设计》说明书
Fig.4 显示迭代阈值分割结果
武汉理工大学《图像处理程序设计》说明书
7.部分主要程序代码
//图像阈值分割程序
#include "stdafx.h"
#include "windowsx.h"
#include "math.h"
#include "YuZhiChuLidib.h"
#include "MainFrm.h"
///***************************************************************/
/*函数名称:Diedaifazhi(int *tongji)
/*函数类型:void
/*参数说明:tonji ---直方图灰度值统计
/*功能:对图像进行迭代阀值选取。
/***************************************************************/
void CYuZhiChuLiDib::Diedaifazhi(int *tongji)
{
// 循环变量
LONG i;
LONG j;
// 指向DIB象素指针
LPBYTE p_data;
// 找到DIB图像象素起始位置
p_data = GetData();
// DIB的宽度
LONG wide = this->GetDibWidthBytes();
// DIB的高度
LONG height = this->GetHeight();
// 迭代阀值
int T1, T2;
T1 = 127;
T2 = 0;
// 临时变量
int Temp0, Temp1, Temp2, Temp3;
Temp0 = Temp1 = Temp2 = Temp3 = 0;
while (true)
{
// 计算下一个迭代阀值
for (i = 0; i < T1 + 1; i++)
{
Temp0 += tongji[i] * i;
Temp1 += tongji[i];
}
for (i = T1 + 1; i < 256; i++) 武汉理工大学《图像处理程序设计》说明书
{
Temp2 += tongji[i] * i;
Temp3 += tongji[i];
}
T2 = (Temp0 / Temp1 + Temp2 / Temp3) / 2;
// 看迭代结果是否已收敛
if (T1 == T2)
break;
else
T1 = T2;
}
// 对各像素进行灰度转换
for (j = 0; j < height; j ++)
{
for (i = 0; i < wide; i ++)
{
// 读取像素
unsigned char temp = *((unsigned char *)p_data + wide * j + i);
// 判断像素灰度值是否超出范围
if (temp < T1)
temp = 0;
else
temp = 255;
// 回写处理完的像素
*((unsigned char *)p_data + wide * j + i) = temp;
}
}
}
void CYuZhiChuLiDib::Fenbutongji(int *tongji)
{
// 循环变量
LONG i;
LONG j;
//变量初始化
memset(tongji,0,sizeof(int) * 256);
// 指向DIB象素指针
LPBYTE p_data;
// 找到DIB图像象素起始位置
p_data = this->GetData();
// DIB的宽度
LONG wide = GetDibWidthBytes();
// DIB的高度
LONG height = GetHeight();