為什麼要把彩色轉黑白兩色呢?
這不是為了耍帥,而是因為點陣式印表機,只能印出黑白兩色 (連灰色都沒有)
(非黑即白,機器撞下去的點就是黑,沒有撞的就是白)
如果你的印表機,是點陣印表機,
把你的圖片用這個程式跑一下,可以確保你印出來的是相同的結果。
使用程式說明:
不要直接開啟程式
請在 我的電腦 或 檔案總管 (或桌面)
將圖片的圖示 移到程式的圖示上
就可以跑了
使用程式請注意:
1. 請用 24 位元 BMP檔, 最快的轉檔方法,就是用小畫家開你的圖,
然後另存新檔成 24 bit 點陣圖。
2. 如果圖跑不出來,請盡量把原圖的長和寬改成24的倍數,再跑一次。
相關討論
目前這方面的演算法,分為混色(dithering) 和 誤差擴散法 (error diffusion)
這支程式使用的是後者,
之所以叫做誤差擴散,是因為一個點算出來的結果會影響下一個點
可以修正某些在中間亮度判定錯誤的問題。
而目前有三種演算法可以選用
分別是Floyd-Steinberg、Jarvis-Judice-Ninke 和 Stucki
效果其實差不多,不過還是有細微的差異。
由於太多人用這些演算法跑Lena圖,所以我就不用Lena圖了...
上面這張圖,用三種演算法跑起來的結果都差不多。
(僅在於點的位置不同而已)
讓我們換一張圖來試試看 (三張圖演算法擺放位置不變,懶得標了..)
這張圖就有細微的差別
我的感覺是
Floyd-Steinburg:顆粒最細
Jarvis-Judice-Ninke:顆粒最濃
Stucki:折衷
Jarvis-Judice-Ninke演算法
function y = jj_ninke(x)
height=size(x,1);
width=size(x,2);
y=uint8(zeros(height,width));
z=zeros(height+3,width+3);
z(2:height+1,2:width+1)=x;
for i=3:height+1,
for j=3:width+1,
if z(i,j)<128
y(i-1,j-1)=0;
e=z(i,j);
else
y(i-1,j-1)=255;
e=z(i,j)-255;
end
z(i,j+1)=z(i,j+1)+7*e/48;
z(i,j+2)=z(i,j+2)+5*e/48;
z(i+1,j-2)=z(i+1,j-2)+3*e/48;
z(i+1,j-1)=z(i+1,j-1)+5*e/48;
z(i+1,j)=z(i+1,j)+7*e/48;
z(i+1,j+1)=z(i+1,j+1)+5*e/48;
z(i+1,j+2)=z(i+1,j+2)+3*e/48;
z(i+2,j-2)=z(i+2,j-2)+1*e/48;
z(i+2,j-1)=z(i+2,j-1)+3*e/48;
z(i+2,j)=z(i+2,j)+5*e/48;
z(i+2,j+1)=z(i+2,j+1)+3*e/48;
z(i+2,j+2)=z(i+2,j+2)+1*e/48;
end
end
Floyd Steinburg用的擴散法 (用上述程式e去乘)
Jarvis-Judice-Ninke用的擴散法 (用上述程式e去乘)
參考書目:Introduction to digital processing with MATLAB, MacAndrew/Wang/Tseng, CENGAGE Learning.