(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;
}

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM