木瓜妮子多媒体开发教程---第三天---Android下图像灰度化和二值化

Android下图像灰度化和二值化

中间隔了几天,终于也拿到了暑期实习的offer,撒花庆祝.....偷笑

今天的项目主要是对图像的点像素处理,比如在文字识别的过程中,图像的色彩信息其实是毫无用处的,这时候对图像的灰度化和二值化尤其重要。那么,正题开始!

1.什么是灰度化

         在RGB模型中,如果R=G=B时,则像素的颜色表示一种灰度颜色,其中R=G=B的值叫灰度值,因此,灰度图像每个像素只需一个字节存放灰度值(又称强度值、亮度值),灰度范围为0-255。一般有以下四种方法对彩色图像进行灰度化。

               分量法

         将彩色图像中的三分量的亮度作为三个灰度图像的灰度值,可根据应用需要选取一种灰度图像。

f1(i,j)=R(i,j)f2(i,j)=G(i,j)f3(i,j)=B(i,j)                                                                                                                                          (3-1)

其中fk(i,j)(k=1,2,3)为转换后的灰度图像在(i,j)处的灰度值。

             最大值法

         将彩色图像中的三分量亮度的最大值作为灰度图的灰度值。

f(i,j)=max(R(i,j),G(i,j),B(i,j))                                                                                                                                                          (3-2)

             平均值法

         将彩色图像中的三分量亮度求平均得到一个灰度值。

f(i,j)=(R(i,j)+G(i,j)+B(i,j))/3                                                                                                                                                              (3-3)

            加权平均法

         根据重要性及其它指标,将三个分量以不同的权值进行加权平均。由于人眼对绿色的敏感最高,对蓝色敏感最低,因此,按下式对RGB三分量进行加权平均能得到较合理的灰度图像。

f(i,j)=0.30R(i,j)+0.59G(i,j)+0.11B(i,j))                                                                                                                                             (3-4)

         最常用的为公式3-4描述的加权平均法。


下述代码描述了如何用最简单的方法计算一个图片的灰度化:


for(int i=0;i<bmp.getWidth();i++){
	for(int j=0;j<bmp.getHeight();j++){
		int color = bmp1.getPixel(i, j);
		int alpha = color & 0xff000000;
		int gray = color &0x000000ff;//此时已经变成灰度图,red/green/blue为相同值。
		int newcolor = alpha | gray <<16 |gray <<8 |gray;
		bmp1.setPixel(i, j, newcolor);}}
bmp是原始bitmap文件,通过拿到bmp的每个像素,改变其像素值(红绿蓝三色设置成相同值),最后得到新的图像。


加权平均值法:

for(int i=0;i<bmp.getWidth();i++){
	for(int j=0;j<bmp.getHeight();j++){
		int color = bmp1.getPixel(i, j);
		int alpha = color & 0xff000000;
//		int gray = color &0x000000ff;//此时已经变成灰度图,red/green/blue为相同值。
		int red =  color &0x00ff0000;
		int green =  color &0x0000ff00;
		int blue =  color &0x000000ff;
		int gray = (int)(0.3*red+ 0.59*green+0.11*blue);
		int newcolor = alpha | gray <<16 |gray <<8 |gray;
		bmp1.setPixel(i, j, newcolor);							
		}
	}


也可以采用自带的算法,将图像的饱和度降为0,也可以实现灰度化的效果。


ColorMatrix cm1= new ColorMatrix();
cm1.setSaturation(0);
paint.setColorFilter(new ColorMatrixColorFilter(cm1));
canvas.drawBitmap(bmp, 0, 0, paint);


2.什么是二值化

图像的二值化处理就是将图像上的点的灰度置为0或255,也就是将整个图像呈现出明显的黑白效果,通常二值化会在对图片进行灰度化之后进行。二值化是将256个亮度等级的灰度图像通过适当的阈值选取来提取仍然可以反映图像整体和局部特征的一种算法。

在数字图像处理中,二值图像占有非常重要的地位,特别是在实用的图像处理中,通常要先进行二值图像处理,例如在分析图片的边缘特性等的过程中,要进行二值图像的处理与分析。

彩色图片含有大量的色彩信息,如果图像仅仅只有两种数值表示并且图像的集合性质只与像素值为0或255的点的位置有关,不再涉及像素的多级值,处理就会变得简单,算法也会更加简单,而且数据的处理和压缩量小。

为了得到理想的二值图像,一般采用封闭、连通的边界定义不交叠的区域。所有灰度大于或等于阈值的像素被判定为属于特定物体,其灰度值为255表示,否则这些像素点被排除在物体区域以外,灰度值为0,表示背景或者例外的物体区域。如何根据图像的不同场景设定二值化的阈值是个很重要的问题。

二值化选取阈值的方法是多样的,最常用的有以下几种:

1、灰度平局值值法:

中心思想是使用整幅图像的灰度平均值作为二值化的阈值,一般该方法可作为其他方法的初始猜想值。

2、百分比阈值(P-Tile法):

Doyle于1962年提出的P分位数法,这种算法可以说是最古老的一种阈值选取方法。该方法根据先验概率来设定阈值,使得二值化后的目标或背景像素比例等于先验概率,该方法简单高效,但是对于先验概率难于估计的图像却无能为力。

3、经典算法OTSU:

OTSU的中心思想是阈值T应使目标与背景两类的类间方差最大。

4、基于谷底最小值的阈值:

这个方法实用于具有明显双峰直方图的图像,其寻找双峰的谷底作为阈值,但是该方法不一定能获得阈值,对于那些具有平坦的直方图或单峰图像,该方法不合适。这个函数的实现是一个迭代的过程,每次处理前对直方图数据进行判断,看其是否已经是一个双峰的直方图,如果不是,则对直方图数据进行半径为1(窗口大小为3)的平滑,如果迭代了一定的数量比如1000次后仍未获得一个双峰的直方图,则函数执行失败,如成功获得,则最终阈值取两个双峰之间的谷底值作为阈值。

5、Kittler算法:

是一种快速的全局阈值法。它的效果不比OTSU差多少,但速度快好多倍,如果可以应用在图像质量不错的环境。它的中心思想是,计算整幅图像的梯度灰度的平均值,以此平均值做为阈值。

还有很多其它二值化算法,适用于不同特征的图像上,其算法的复杂度也不尽相同。

其实最简单的二值化算法只是在灰度值的算法基础上增加了一个判断:

for(int i=0;i<bmp.getWidth();i++){
	for(int j=0;j<bmp.getHeight();j++){
		int color = bmp1.getPixel(i, j);
		int alpha = color & 0xff000000;
		int gray = color &0x000000ff;//此时已经变成灰度图。
		<span style="color:#cc0000;">if (gray >95){gray = 255;}
		else {gray = 0;}</span>
		int newcolor = alpha | gray <<16 |gray <<8 |gray;
		bmp1.setPixel(i, j, newcolor);


项目最后的效果图:



  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值