(6)比特平面分层(Bit Plane Slicing)

知道术语的英文翻译很重要,因为百度高质量的博文和文章比谷歌搜索到的要少。

 

对于灰度图而言,一个像素点由8个比特组成。代替突出灰度级范围,我们可以突出特定比特来为整个图像外观作出贡献(理解这一点很重要)一副8比特灰度图可考虑分层1到8个比特平面。很容易理解的是,4个高阶比特平面,特别是最后两个比特平面,包含了在视觉上很重要的大多数数据。而低阶比特平面则在图像上贡献了更精细的灰度细节。

 

比特平面分层最重要的是它的分层算法,算法依据就是上段的黑体字,突出该层的比特,如何突出则是每一层分层算法需要考虑的。开始看这一章节内容的时候,没有关注到比特平面分层的作用是什么,以为只是简单的把每一层的比特提取出来建立比特平面图。所以有了下面的算法:

//下面的color都是争对灰度而言的

private int bitLevel(int color, int level) {
	int color_lev1 = color & 1;   //00000001
	int color_lev2 = color & 0x2; //00000010
	int color_lev3 = color & 0x4; //00000100
	int color_lev4 = color & 0x8; //00001000
	int color_lev5 = color & 0x10;//00010000
	int color_lev6 = color & 0x20;//00100000
	int color_lev7 = color & 0x40;//01000000
	int color_lev8 = color & 0x80;//10000000
	int color_lev;// = color & 0x80;
	color_lev = color & (1 << level)//level取值为0到7
	return (255 << 24) + (color_lev << 16) + (color_lev << 8) + color_lev;
}

 这个算法的作用就是简单的提取每一层的比特,但我忽略了“突出该层比特”的要义。实际结果也证明是错误的,例如第一层,值不是0就是1,这样的色值显示出来就是纯黑,根本显现不了第一层比特的贡献。突出分层的最好做法就是二值化,因为每个像素点每层比特的值只有1(有贡献)和0(无贡献),我们要做的就是突出1值。真正的分层算法如下:

第一层:

第一层位置上的值只能是0和1,所以值为0时,可令其转换值为255

private int bitLevelOne(int color){
	int gray = color >> 8 & 0xFF;
	int color_lev;
	if(gray == 1)color_lev = 255;
	else color_lev = 0;
	return (255 << 24) + (color_lev << 16) + (color_lev << 8) + color_lev;
}

 (实验是以《数字图像处理》书中提供的样图作处理的,该图本身就是8比特的灰度图,传给函数的参数值是argb像素点值,该值a=r=g=b,所以取出右边的8位即得到它的灰度图,同样为了“突出”考虑,alpha通道取255)

原图:(500x1192像素的灰度图)

第一层平面图:

 

其它层级的分层算法如上依次类推,如果该层级的比特值为1,则二值化为255,如果为0,则二值化为0。比如第六层分层算法如下

private int bitLevelSixth(int color) {
	int gray = color >> 8 & 0xFF;
	int color_lev6 = gray & 0x20;// 00100000
	int color_lev;
	if (color_lev6 == 0x20)
		color_lev = 255;
	else
		color_lev = 0;
	return (255 << 24) + (color_lev << 16) + (color_lev << 8) + color_lev;
}

 注意:上述算法涉及到各种移位等操作,实际结果效率比较低,这里暂不考虑这一点,只说明实际的比特平面分层算法的原理。

第6,7,8层结果如下:

    

 

比特平面分层的另一个应用是在图像压缩中,从上面的分层图结果来看,我们只需要使用高阶的几层便能重建原图,这也就意味着可以使用比原来更少的比特层来构建原图(比如4层,这样就减少了50%的存储量)。

使用6,7,8三个平面重建的算法和结果如下:

private int combine678(int color){
	int gray = color >> 8 & 0xFF;
	int colors = gray & 0xE0;//11100000
	return (255 << 24) + (colors << 16) + (colors << 8) + colors;
}

 

 

posted on 2015-07-04 18:52  Matrixin  阅读(12448)  评论(0编辑  收藏  举报

导航