3.5 灰度阈值变换
灰度阈值变换可以将一幅灰度图像转换成黑白的二值图像。用户指定一个起到分界线作用的灰度值,如果图像中某像素的灰度值小于该灰度值,则将该像素的灰度值设置为0,否则设置为255,这个起到分界线作用的灰度值称为阈值,灰度的阈值变换也常被称为阈值化或二值化。
3.5.1 理论基础
灰度阈值变换的函数表达式如下。
其中,T为指定的阈值。
图3.13给出了灰度阈值变换的示意图。
图3.13 灰度阈值变换示意图
灰度阈值变换的用途和可扩展性都非常广泛。通过将一幅灰度图像转为二值图像,可以将图像内容直接划分为读者关心的和不关心的两个部分,从而在复杂背景中直接提取出感兴趣的目标。因此它是图像分割的重要手段之一,这一点在第12章中还将进一步阐述。
3.5.2 MATLAB编程实现
MATLAB中和阈值变换有关的函数主要有两个——im2bw和graythresh,下面分别介绍。
1.函数im2bw可用于实现阈值变换,调用语法如下。
BW = im2bw(I, level)
参数说明:
• 参数I为需要二值化的输入图像;
• 参数level给出了具体的变换阈值,它是一个0~1之间的双精度浮点数,例如输入图像I为灰度范围在0~255之间的uint8图像,如果level=0.5则对应于分割阈值为128。
返回值:
• BW为二值化后的图像。
2.函数graythresh可以自适应地确定变换所用的“最优”阈值,调用形式如下。
thresh = graythresh(I)
参数说明:
• 参数I为需要计算阈值的输入图像。
返回值:
• thresh是计算得到的最优化阈值。
灰度阈值level既可以由经验确定,也可以使用graythresh()函数来自适应地确定。下面的程序分别展示了如何利用graythresh函数获得的阈值和自行设定的阈值进行阈值变换。
>> I = imread('rice.png') % 使用Matlab自带的rice.png图像 >> thresh = graythresh(I) % 自适应确定阈值 thresh = 0.5137 >> bw1 = im2bw(I, thresh); % 二值化 >> >> bw2 = im2bw(I, 130/255); % 以130为阈值实现二值化,注意要将此阈值转换至[0,1]区间 >> subplot(1,3,1); imshow(I); title(’原图像’); >> subplot(1,3,2); imshow(bw1); title(’自动选择阈值’); >> subplot(1,3,3); imshow(bw2); title(’阈值130');
上述程序的运行结果如图3.14所示。
图3.14 灰度阈值变换效果
由图3.14(b)和图3.14(c)可见,单纯的灰度阈值化无法很好地处理灰度变化较为复杂的图像,常常给物体的边缘带来误差,或者给整个画面带来噪点。这就需要通过其他的图像处理手段予以弥补,本书将在11.4节介绍相关的内容。
3.5.3 Visual C++实现
对于使用Visual C++软件,要实现阈值化只需逐行扫描图像,根据指定点的像素值与阈值的大小关系对其进行赋值即可。其编码如下。
/************************************************** void CImgProcess::Threshold(CImgProcess *pTo, BYTE nThres) 功能: 图像的阈值变换 参数: CImgProcess * pTo:输出CImgProcess对象的指针 BYTE nThres:设置的基准阈值 返回值: 无 ***************************************************/ void CImgProcess::Threshold(CImgProcess *pTo, BYTE nThres) { int i, j; BYTE bt; for(i = 0; i < m_pBMIH->biHeight; i ++) { for(j=0; j<m_pBMIH->biWidth; j++) { // 核心部分算法,小于nThres的设为0,其它设为255,从而得到二值图像 bt = GetGray(j, i); if(bt<nThres) bt = 0; else bt = 255; pTo->SetPixel(j, i, RGB(bt, bt, bt)); } } }
利用Threshold()函数实现阈值化变换的完整示例被封装在DIPDemo工程中的视图类函数void CDIPDemoView::OnPointThre()中,其中调用Threshold()函数的代码片断如下所示。
// 输出的临时对象 CImgProcess imgOutput = imgInput; // 调用Threshold方法进行阈值变换 imgInput.Threshold(&imgOutput, bThre); // bThre为变换的阈值 // 将结果返回给文档类 pDoc->m_Image = imgOutput;
上述程序运行时,会弹出对话框要求用户设置阈值参数。读者可以通过光盘中示例程序DIPDemo中的菜单命令“点运算→阈值变换”来观察处理效果。