影象的本質是什麼?對不同的人來說這是不同的東西。在計算機的世界中,啥東西都是資料,影象也是一種資料。從自然界的光變成計算機的資料,需要通過取樣和量化的處理。影象在計算機中,其實是乙個二維陣列,從數學上來說,這其實是乙個矩陣。影象中的每乙個點都是個四維向量,也就是(r,g,b,a), 在rgba色彩空間中,我們可以使用乙個矩陣對每乙個點(r,g,b,a)作矩陣乘法運算,這樣就可以對影象色彩進行變換。這種做法其實是從三維空間座標系中的仿射變換類推過來的。具體關於仿射變換,可以參考 對於仿射變換的介紹。
色彩矩陣就是這個用來對色彩作仿射變換的矩陣。這是乙個5*5的矩陣,如圖
圖 5色彩空間矩陣
其實和在空間中的仿射變換完全一樣,可以實現縮放,旋轉,平移等功能。我看到網上有個人寫了一篇深入淺出的文章"gdi+ colormatrix的完全揭秘與**實現" 寫得不錯,只是沒有理解到colormatrix應用的精髓。簡單套用了一些什麼顏色剪下,顏色旋轉,顏色平移的概念,這些東西其實在三維空間中很好理解,但是在色彩空間中,就完全不是那麼回事情了,什麼叫做顏色旋轉60度呢? 這東西忽悠人很有用,只是看完了還是不知道怎麼用,有興趣的同學可以去看看。我下面舉幾個例子,說明colormatrix的具體應用。
灰度化是指去除影象的彩色資訊,講所有的色調歸為0,所有的飽和度也歸為零。這個世界上有很多種不同的灰度化的演算法,隨便寫個演算法,弄篇*****搞個碩士畢業應該不成問題,比如說所有的顏色替換成r' = g' = b' = (r+b+g)/3。有一種很通用的灰度化演算法如下,這其實是ntsc的色彩權重。
r'=b'=g' = 0.299*r + 0.587*g + 0.114*b
那如果我們要使用colormatrix, 可以用以下的矩陣:
float
ptsarray =
,new
float
,new
float
,new
float
,new
float };
得到的結果如下:
再引用一下裡的這篇文章 ,如果用他的演算法,那麼矩陣如下
float
ptsarray =
,new
float
,new
float
,new
float
,new
float };
使用colormatrix調整色彩很簡單,用m11對紅色乘乙個係數,用m51對紅色加乙個值,這樣就可以簡單地調整紅色。其他b,g,a通道以此類推。例如下面這個矩陣可以把增加紅色25.5個畫素(如果使用24bppargb):
可以用以下矩陣,將每個通道增加25.5的亮度。
類似的,你可以認為使用以下矩陣,能將每個通道公升高10%的對比度:
很不幸,這是錯的。這個演算法裡面有個關鍵的問題是overflow,如果我們直接使用這個矩陣,你會看到影象上會有溢位,導致你的影象慘不忍睹。我在網上查到有個很髮指的做法可以解決這個問題,雖然發指,但是能解決!就是把最下面的項修正一點點,這樣影象就不溢位了。看下面這個矩陣。
這個矩陣比較複雜,飽和度需要通過不同的色彩權值來修正。我這裡只提供乙個能用的矩陣,具體可以參考這篇*****:
講了那麼多個矩陣,最後讓我們來看看在gdi+裡面colormatrix這個類到底怎麼用:
filestream
fs =
newfilestream
(image,
filemode
.open,
fileaccess
.read);
image
img =
image
.fromstream(fs,
false
,false
);bitmap
bmp =
newbitmap
(img);
img.dispose();
fs.close();
graphics
g =this
.creategraphics();
float
rwgt = 0.3086f;
float
gwgt = 0.6094f;
float
bwgt = 0.0820f;
float
s = 1.2f;
float
ptsarray =
,new
float
,new
float
,new
float
,new
float };
// create a colormatrix
colormatrix
matrix =
newcolormatrix
(ptsarray);
imageattributes
attr =
newimageattributes
();
// set color matrix
attr.setcolormatrix(matrix,colormatrixflag
.default,
coloradjusttype
.default);
// draw image with no affects
g.drawimage(bmp, 0, 0, 200, 150);
// draw image withimageattributes
g.drawimage(bmp,new
rectangle
(205, 0, 200, 150),, 0,bmp.width, bmp.height,
graphicsunit
.pixel, attr);
// dispose
bmp.dispose();
g.dispose();
多少博士大牛在研究這些不同的矩陣以期獲得更強悍的效果。此外還有好多人申請了各種各樣的專利來保護這個色彩變換,所以如果大家想混一篇簡單的*****好畢業,這是個很好的方向。隨便改兩個數字,乙個新的矩陣就出來了,然後版面費一交,就可以發表了。當然,這也是個蠻有意思的題目,可以做很多比較和研究,這些就不是我這種it民工該講的東西了。
使用GDI 進行開發的一些問題(7)
我最近一直在顏色空間中糾結,前面講的透明不透明只是一種特殊的顏色。今天我準備要講的是真正的修正顏色。我們使用的數位相機有不同的型號,感光的ccd效能也是不一樣的,再加上天氣或者周圍光線的原因,我們排出來的 可能會偏色。此外,為了做一些特殊處理,可能需要將 中某乙個特殊的區域顏色進行修正。比如臉色可以...
開發遇到的一些問題
持續更新 1.禁止以複製 貼上以及剪下的方式操作密碼框中的內容 password bind copy cut paste function 2.當頁面取值為乙個字段,但是欄位中有很多資料,用,分割,展示的時候要換行,如何處理?半形的不斷行的空白格 推薦使用 半形的空格 全形的空格 3.比較值時,需要...
SQLite使用的一些問題
1 檢視裡支援as也支援 表名.欄位名 這種寫法 create view 檢視名稱 as select 專案列表.專案id as 序號,專案列表.專案名 as 姓名,屬性分類列表.屬性名 as 屬性名,屬性值列表.屬性值 as 屬性值 from 專案列表,屬性值列表,屬性分類列表 where 屬性值...