Tuesday, January 24, 2023

 ULANI 電子紙桌曆的遮騰筆記 (4)

想要改用規格書中實測顏色來作為dither的色盤,第一步當然就是得先實作一個dither演算法。這類的演算法百百種,比較廣為人知的應該就屬 Floyd–Steinberg 了(後面簡稱FS),畢竟從開始有彩色噴墨印表機,就常常看到這個名字,只是一直沒有去看過是怎麼做的。其實FS演算法很簡單,是一種誤差擴散的方式,維基百科上就可以找到說明了,還有偽程式碼的範例。基本上,FS是先找到「色盤中最接近這個圖素的顏色」,然後計算差值分散到鄰近的像素上。

由於擴散的方向都是往前不往後,所以實際只要掃過一遍整張圖,就可以計算完成。只是要分散運算的話直接是沒辦法切開,可能還得另外處理。

有了範例程式,就先試試看灰階的圖片,看起來沒有什麼問題。於是開始改成RGB的彩色,也就是原先的PIL傳回單一數值改成[R, G, B],然後使用numpy來處理。只是算出來的都是黑畫面,不曉得問題出在哪裡。後來看了另一篇文章,才猛然想起因為python沒有明確的型別,[R, G, B]非 primitive type 會是個指標 reference,所以運算之前得使用 .copy() 複製一份數值,才不會是 [0, 0, 0] 全黑。然後FS演算法中要找「色盤中最接近這個圖素的顏色」,就用RGB三個數值的幾何距離(RGB差值的平方和再取平方根)來計算,以最笨的方式依序比較七個基本色的距離就可以得到最接近色了。先求有再求快,到這邊算是完成了第一步。



No comments: