討論區快速選單
知識庫快速選單
掌握Salesforce雲端管理秘訣 網路投保旅行平安險 程式設計俱樂部Facebook粉絲團
[ 回上頁 ] [ 討論區發言規則 ]
[教學]抖色技巧
更改我的閱讀文章字型大小
作者 : chiuinan2(青衫)討論區板主 Visual C++ .NET卓越專家VC++一代宗師Visual Basic優秀好手資訊類作業求救卓越專家一般曠世奇才程式設計甘苦談優秀好手C++ Builder優秀好手上班族的哈拉園地優秀好手C++頂尖高手Assembly優秀好手貼文超過3000則人氣指數超過150000點
[ 貼文 3732 | 人氣 170106 | 評價 34520 | 評價/貼文 9.25 | 送出評價 125 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2006/5/16 下午 11:25:56
最近看到有人在問灰階的處理, 記得以前有寫過一篇文章, 找了很久終於找到了, 將它po出來給沒接觸過的人了解一下.
----------------------------------

影像色數轉換-抖色技巧 by 邱奕南

當一個影像的色盤色數減少,或是色盤顏色改變時,將該影像轉至新的色盤,必定會產生失真的現象。但如何彌補這個失真現象,便是本文所要探討的課題-抖色(Dither)技巧。以影像中的一個像素而言,轉變至新的色盤索引值,在新舊色點上的色彩必定有所差異,一般的彌補方式,大都採用誤差擴散法(Error Diffusion),將這個誤差擴散在鄰近的色彩點上,使得整體看來,該色點與與原色極為相近。這個方法,其實便是利用人眼的渲染特性:當人眼在看某個色點時,該色點的顏色,會受到鄰近的色點顏色所影響。以下便介紹幾種常見的抖色方法,這些方法的差異,主要在於誤差擴散的範圍與比例而已:

1.Floyd-Steinberg

- x 7
3 5 1

其中x表示目前的處理點。當該處理點找到最接近色時,便將該點顏色與最接近色顏色的誤差值,以7/16、3/15、5/16、1/16比例擴散到鄰近的點。而鄰近的點在找最接近色前,先依先前擴散過來的顏色誤差值進行調整,最對調整後的顏色值找最接近色,之後再將顏色誤差值擴散出去。重複這個步驟,直到所有影像點處理完為止。Floyd-Steinberg的抖色方法迅速且效果良好,為相當常用的抖色方法。

2.Stucki

- - x 8 4
2 4 8 4 2
1 2 4 2 1

Stucki使用了更多的點參與誤差擴散,以得到更好的效果。不過誤差擴散的範圍一大,其處理的速度便嚴重的下降,因此對於大型影像而言,一般很少採用這個方法。

3.Burkes

- - x 8 4
2 4 8 4 2

Burkes的方法可說是Floyd-Steinberg與Stucki的折衷方案,以求得效果與速度的平衡。

除了上述標準的三種方法外,其後還有許多人提出一些方法出來,但大抵和上述三種方法沒有太大不同,只是適用於不同的影像而已。這些方法計有:

1.Sierra

- - x 5 3
2 4 5 4 2
- 2 3 2 -

2.Jarvis, Judice, Vinke

- - x 7 5
3 5 7 5 3
1 3 5 3 1

3.Stevenson, Arce

- - - - x 32 -
12 - 25 - 30 - 16
- 12 - 26 - 12 -
5 - 12 - 12 - 5

作者 : chiuinan2(青衫)討論區板主 Visual C++ .NET卓越專家VC++一代宗師Visual Basic優秀好手資訊類作業求救卓越專家一般曠世奇才程式設計甘苦談優秀好手C++ Builder優秀好手上班族的哈拉園地優秀好手C++頂尖高手Assembly優秀好手貼文超過3000則人氣指數超過150000點
[ 貼文 3732 | 人氣 170106 | 評價 34520 | 評價/貼文 9.25 | 送出評價 125 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2006/5/16 下午 11:27:20
雖然抖色的方法相當常用,效果也很好,但對於轉成單色影像而言,其速度仍然嫌太慢了些。因此對於單色影像而言,還有一種八色抖動(Eight-Colordithering)技術可以運用,一般稱為Bayer抖色法,或半色調法(Halftone)。這個方法主要將把8x8的色素看成是一大塊的色點,而在這個色點中模擬出誤差擴散的效果,其成效雖不如標準的抖色方法,但因處理快速,效果也不錯,因此運用甚廣。該方法首先是計算出各點的灰度值(Gray Level),其計算方式如下:

Gray = 0.299*Red + 0.587*Green + 0.114*Blue

接著利用下列8x8的貝葉抖色表(或稱半色調矩陣),以8x8的影像點為單位,凡是該單位中的某一點灰度值大於該表對應的灰度值,便視為白,否則視為黑:

{{ 0,128, 32,160, 8,136, 40,168},
{192, 64,224, 96,200, 72,232,104},
{ 48,176, 16,144, 56,184, 24,152},
{240,112,208, 80,248,120,216, 88},
{ 12,140, 44,172, 4,132, 36,164},
{204, 76,236,108,196, 68,228,100},
{ 60,188, 28,156, 52,180, 20,148},
{252,124,220, 92,244,116,212, 84}};

這種方法比單純以灰度值128為鄰界點判斷黑白的方式效果來得好,但速度又相差不多,因此頗值得推廣運用。
作者 : chiuinan2(青衫)討論區板主 Visual C++ .NET卓越專家VC++一代宗師Visual Basic優秀好手資訊類作業求救卓越專家一般曠世奇才程式設計甘苦談優秀好手C++ Builder優秀好手上班族的哈拉園地優秀好手C++頂尖高手Assembly優秀好手貼文超過3000則人氣指數超過150000點
[ 貼文 3732 | 人氣 170106 | 評價 34520 | 評價/貼文 9.25 | 送出評價 125 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2006/5/16 下午 11:58:50
後記: 前面只是單純的講述, 可能對某些人還是不易了解. 以下我舉個簡單的例子:

假設半色調矩陣為:

unsigned char halftone[8][8] = {...}; (資料見前述)

對於一個二維影像, 假色其灰階值為gray[xsize][ysize], 那麼轉成黑白二色的方法便是:

for (y=0; y<ysize; y++)
  for (x=0; x<xsize; x++)
     if (gray[x][y] > halftone[x&7][y&7]) 實際灰階值 = 255;
     else 實際灰階值 = 0;

抖色的處理比較麻煩些:

for (y=0; y<ysize; y++)
  for (x=0; x<xsize; x++)
  {
     new_gray = 找gray[x][y]的最接近色 (該點的新顏色);
     delta = new_gray-gray[x][y]; // 誤差值 //
     gray[x][y] = new_gray;
     // 將誤差擴散到鄰近點, 注意這裡我沒去處理超出影像範圍的情況, 以及誤差擴散後的色點灰階值域是否超出範圍, 請自己加入相關的限制 //
     gray[x+1][y] += delta*7/16;
     gray[x-1][y+1] += delta*3/16;
     gray[x][y+1] += delta*5/16;
     gray[x+1][y+1] += delta/16;
   }

注意要先水平或垂直. 如果是處理彩色, 那麼就以R,G,B三個分量來進行處理即可.
作者 : chiuinan2(青衫)討論區板主 Visual C++ .NET卓越專家VC++一代宗師Visual Basic優秀好手資訊類作業求救卓越專家一般曠世奇才程式設計甘苦談優秀好手C++ Builder優秀好手上班族的哈拉園地優秀好手C++頂尖高手Assembly優秀好手貼文超過3000則人氣指數超過150000點
[ 貼文 3732 | 人氣 170106 | 評價 34520 | 評價/貼文 9.25 | 送出評價 125 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2006/5/16 下午 11:59:53
加一行將廣告拉到這裡來, 不然前篇的程式不太容易看.
作者 : chiuinan2(青衫)討論區板主 Visual C++ .NET卓越專家VC++一代宗師Visual Basic優秀好手資訊類作業求救卓越專家一般曠世奇才程式設計甘苦談優秀好手C++ Builder優秀好手上班族的哈拉園地優秀好手C++頂尖高手Assembly優秀好手貼文超過3000則人氣指數超過150000點
[ 貼文 3732 | 人氣 170106 | 評價 34520 | 評價/貼文 9.25 | 送出評價 125 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2006/5/17 上午 12:05:55
誤差部份寫錯了, 應該是舊點減去新點:

delta = gray[x][y] - new_gray;

也就是說, 原先亮度是8, 新的亮度是10, 因為目前的點提高了2個亮度, 那麼周圍的點應該合計減去2個亮度來平衡. 誤差值= 8-10 = -2, 擴散至鄰近點.
作者 : awinnew(Awin)
[ 貼文 79 | 人氣 7155 | 評價 90 | 評價/貼文 1.14 | 送出評價 13 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2006/5/18 下午 03:18:36
謝謝分享,有時真的是聽君一席話,勝讀十年書。
作者 : shing819(Clier) VC++曠世奇才貼文超過1000則人氣指數超過30000點
[ 貼文 1740 | 人氣 40353 | 評價 8630 | 評價/貼文 4.96 | 送出評價 84 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2006/5/20 上午 12:24:41

感謝分享
 板主 : 徵求中
 > 影像處理與計算機圖學 - 討論區
 - 最近熱門問答精華集
 - 全部歷史問答精華集
 - 影像處理與計算機圖學 - 知識庫
  ■ 全站最新Post列表
  ■ 我的文章收藏
  ■ 我最愛的作者
  ■ 全站文章收藏排行榜
  ■ 全站最愛作者排行榜
  ■  月熱門主題
  ■  季熱門主題
  ■  熱門主題Top 20
  ■  本區Post排行榜
  ■  本區評價排行榜
  ■  全站專家名人榜
  ■  全站Post排行榜
  ■  全站評價排行榜
  ■  全站人氣排行榜
 請輸入關鍵字 
  開始搜尋
 
Top 10
評價排行
影像處理與計算機圖學
1 Linkin 780 
2 CrazyStar 400 
3 青衫 360 
4 白老鼠(Gary) 330 
5 悠悠深藍 220 
6 none 220 
7 shou 200 
8 ultra 200 
9 ghost 140 
10 ozzy 130 
影像處理與計算機圖學
  專家等級 評價  
  一代宗師 10000  
  曠世奇才 5000  
  頂尖高手 3000  
  卓越專家 1500  
  優秀好手 750  
Microsoft Internet Explorer 6.0. Screen 1024x768 pixel. High Color (16 bit).
2000-2019 程式設計俱樂部 http://www.programmer-club.com.tw/
0.140625