编程小知识之 Dithering
本文簡單介紹了 Dithering(抖動) 的一些知識
圖形后處理有一種操作稱為 Dithering(抖動),所謂 Dithering,就是一種能夠在較小色彩空間上"模擬出"較大色彩空間的圖像處理方法,說的有些抽象,我們來舉個例子:
假設我們需要在顯示器上顯示以下圖片(圖片來自這里):
圖片的像素格式為 RGB24RGB24RGB24(像素的 R,G,BR,G,BR,G,B 通道各占 111 個字節(888 位),一個像素占用 333 個字節(共 242424 位)),RGB24RGB24RGB24 格式的像素總共能夠表達 224=167772162^{24} = 16777216224=16777216 種不同的顏色,現在的大部分顯示器也能夠顯示這么多種顏色(這里我們暫時忽略伽馬校正等因素的影響),所以我們不用對圖片做什么特殊處理,直接輸出顯示即可~
但是如果顯示器能夠顯示的顏色數量有限(譬如只能顯示 216216216 種顏色),那么就需要對原圖片進行處理了,一種簡單的方法就是對圖片像素進行截斷或者舍入處理,但是這樣會讓圖片產生明顯的色帶(color banding)現象,譬如上面所示的圖片,經過(像素)截斷(舍入)之后,大概會顯示成這個樣子(圖片來自這里):
可以看到顯示效果很差,那有沒有辦法改善呢?答案就是使用 Dithering(抖動): Dithering(抖動) 通過調整一個像素周圍像素的顏色值,使人眼產生錯覺,從而"模擬出"更多的顯示顏色(譬如將黑白兩種顏色并列在一起就可以"模擬出"灰色(人眼錯覺的關系)),仍然拿上面的圖片舉例,經過 Dithering(抖動) 之后,顯示效果會變成這樣(圖片來自這里):
可以看到顯示效果較之前的版本要好了不少(雖然兩者的顏色空間(使用到的顏色數量)其實是相同的)
那具體 Dithering(抖動) 是怎么調整圖片像素的呢?方法其實有不少,這里我們簡單介紹一下經典的 Floyd–Steinberg 算法,算法的基本思想就是使用誤差擴散(error diffusion),所謂誤差擴散,簡單來說,就是將像素截斷或者舍入之后的顏色誤差擴散(添加)到周圍的像素顏色上去, Floyd–Steinberg 算法采用的誤差擴散方式如下所示(圖片來自wiki):
圖中的 * 號代表的就是當前正在處理(抖動)的像素,該像素截斷或者舍入之后的顏色誤差會按 7/16,1/16,5/16,3/167/16, 1/16, 5/16, 3/167/16,1/16,5/16,3/16 的比例添加到其 右, 右下, 下, 左下 的像素上去, wiki 上已經給出了相關偽碼,這里也有一份完整的代碼實現(基于 Unity),有興趣的朋友可以仔細看看~
參考資料
- Floyd-Steinberg Dithering
- Image Dithering: Eleven Algorithms and Source Code
- Dithering-Unity3d
- Ordered dithering
總結
以上是生活随笔為你收集整理的编程小知识之 Dithering的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 图像抖动(加入随机噪声+矩阵有序抖动)J
- 下一篇: JVM原理(二)执行引擎篇(JVM程序执