如何直接有效的解決問題是一門藝術(shù)。我們是做產(chǎn)品、做系統(tǒng)、做服務(wù)的,不是玩技術(shù)的,需要做的是在最短的時(shí)間內(nèi)以最有效的方式來解決工作中面對(duì)的難題。就在剛才,用了半小時(shí)不到時(shí)間,俺用一種極其簡單、直接、有效、霸道的方法解決了照片的反轉(zhuǎn)負(fù)沖特效問題。這種解決問題的思路值得總結(jié)推廣。
反轉(zhuǎn)負(fù)沖(反轉(zhuǎn)片)是一種攝影拍攝技術(shù),它通過拍攝后反轉(zhuǎn)沖洗,得到色彩鮮艷的照片,非常養(yǎng)眼,F(xiàn)在都是數(shù)碼相機(jī)了,可以通過圖像處理算法來模擬反轉(zhuǎn)片的效果,比如說,“光影魔術(shù)手”就提供了5種反轉(zhuǎn)片特效:(1)素淡人像;(2)淡雅色彩;(3)真實(shí)色彩;(4)艷麗色彩;(5)濃郁色彩。且看(5)濃郁色彩的效果:
左邊是處理前的圖像,右邊是處理后的圖像,可以看到,處理后的圖像顏色格外飽滿。我目前開發(fā)的一款圖像處理軟件,一個(gè)難題就是處理后的照片色彩會(huì)變暗,這個(gè)反轉(zhuǎn)負(fù)沖特效的效果正是我所需要的。
且看“光影魔術(shù)手”怎樣描繪“反轉(zhuǎn)片”功能——
“模擬反轉(zhuǎn)片的效果,是《光影魔術(shù)手》最重要的功能之一。經(jīng)處理后照片反差更鮮明,色彩更亮麗。算法經(jīng)多次改良后,暗部細(xì)節(jié)得到最大程度的保留,高光部分無溢出,紅色還原十分準(zhǔn)確,色彩過渡自然艷麗,絕無色斑!提供多種模式供用戶選擇,其中人像模式對(duì)亞洲人的膚色進(jìn)行了優(yōu)化,不會(huì)出現(xiàn)膚色偏黃現(xiàn)象。獨(dú)有的暗部增補(bǔ)算法不僅增強(qiáng)了暗部, 同時(shí)令高光部分的表現(xiàn)更出色,絕對(duì)沒有霧感引入。精心設(shè)計(jì),專業(yè)效果!強(qiáng)烈推薦所有用戶使用! ”
下面且看俺怎么在半小時(shí)內(nèi)將這個(gè)光影魔術(shù)手引以為豪的功能給集成到俺自己的軟件中來。
第一步,先查資料。以關(guān)鍵字“反轉(zhuǎn)片”+“算法”在google搜索,搜到的都是說“光影魔術(shù)手”這效果多NB多NB的文章,沒參考意義。
第二步,在金山詞霸網(wǎng)上輸入“反轉(zhuǎn)片”,查出來英文單詞是 “reversal film”,然后在google scholar中搜索 “reversal film algorithm”,沒介紹的。在 google 中搜索“reversal film algorithm”,沒有一篇文章講了實(shí)質(zhì)性內(nèi)容的。進(jìn) google code search 搜索 “reversal film”,沒一個(gè)有實(shí)質(zhì)性內(nèi)容的。進(jìn) cnki 搜索 “reversal film”和“反轉(zhuǎn)片”,沒一個(gè)有實(shí)質(zhì)性內(nèi)容的。這下完蛋了,沒參考的,眼看要個(gè)屁了。
第三步,反轉(zhuǎn)片這個(gè)效果很重要,一定有很多人用 photoshop 處理過。搜“反轉(zhuǎn)片”,專門找介紹怎么用 photoshop 進(jìn)行反轉(zhuǎn)負(fù)沖處理的文章。找到幾篇講如何手動(dòng)進(jìn)行反轉(zhuǎn)負(fù)沖特效處理的文章,比如這一篇:http://www.windsn.com/article.asp?id=478。這篇文章中的效果是很NB的。通過閱讀這篇文章發(fā)現(xiàn),“反轉(zhuǎn)片”僅僅是點(diǎn)操作即可,它與像素的鄰域無關(guān),與圖像的統(tǒng)計(jì)信息無關(guān)。
第四步,天空一聲巨響,頭腦一片閃亮。通過第三步,可以推測,反轉(zhuǎn)負(fù)沖實(shí)際上只是一個(gè) RGB 空間到 RGB 空間的映射而已。只需要對(duì)于RGB空間的任意一個(gè)顏色,計(jì)算出它所對(duì)應(yīng)的顏色,做一個(gè)替換即可。
第五步,如何尋找這個(gè)映射呢?利用歸約解決問題。
Udi Manber 的《算法引論-一種創(chuàng)造性的方法》第10章《歸約》的引言部分講了這樣一個(gè)故事——
有人問一個(gè)數(shù)學(xué)家和她的丈夫如下問題:假設(shè)你在地下室,想燒開水怎么辦?數(shù)學(xué)家說,她會(huì)上到廚房并在那里燒水。她的丈夫回答類似。那人繼續(xù)問:假設(shè)你在廚房,想燒開水怎么辦?她丈夫回答說:“這很容易的,將水壺灌滿然后點(diǎn)燃煤氣!倍鴶(shù)學(xué)家回答:“我的答案更簡單。到地下室去,在那里我已經(jīng)知道如何解決這個(gè)問題了!
就讓我們回到“地下室”去解決這個(gè)問題。前面說過,光影魔術(shù)手可以實(shí)現(xiàn)反轉(zhuǎn)片的效果。因此,建立一張圖片,讓這張圖片上包含所有的RGB顏色值,然后用光影魔術(shù)手去處理這張圖片,得到的效果圖另存下來,這就得到了一個(gè)RGB空間到RGB空間的映射。通常,RGB的每一個(gè)Channel是1個(gè)Byte,那么將全部的RGB顏色值放到一張圖片上去,這張圖片就太大了,需要256×256×256個(gè)像素。為了減少處理量,對(duì)RGB空間進(jìn)行采樣,只選擇Channel值為偶數(shù)的色彩,這樣,就把RGB空間壓縮到 128×128×128大小了,也就是一張1024×2048的圖片即可。下面是生成算法:
ImageRgb24 img = new ImageRgb24(1024, 2048);
for (int x = 0; x < 128; x++)
{
for (int y = 0; y < 128; y++)
{
for (int z = 0; z < 128; z++)
{
int index = x * 128 * 128 + y * 128 + z;
img[index] = new Rgb24(x * 2, y * 2, z * 2);
}
}
}
將上面的圖片存為 bmp 格式:
用 光影魔術(shù)手 的5種反轉(zhuǎn)片特效分別進(jìn)行處理,另存為5個(gè) bmp 文件。每一個(gè)bmp文件,代表1種反轉(zhuǎn)片特效,假設(shè)某個(gè)特效的 bmp 的圖儲(chǔ)加載在一個(gè)名為 img 的 ImageRgb24 中,則 img[color.Red / 2 * 128 * 128 + color.Green / 2 * 128 + color.Blue/2] 就是色彩 color 反轉(zhuǎn)片處理后的色彩了。下面是使用“濃郁色彩”bmp圖片映射后的效果圖,是不是和光影魔術(shù)手處理結(jié)果很像呢?
通過對(duì)光影魔術(shù)手的進(jìn)一步分析,發(fā)現(xiàn)它的反轉(zhuǎn)片特效并不完全是點(diǎn)操作,比如說,截取一張圖片的一部分,處理后相同位置的像素和全張圖片處理后相同位置的像素并不一樣,而是有比較小的差異?赡芩鶕(jù)色彩的概率分布進(jìn)行了進(jìn)一步的處理。不過無所謂了,前面這些已經(jīng)夠用了。
想起了讀研究生時(shí)的一個(gè)故事。老師布置了閱讀題目,讓寫一份讀書報(bào)告。我將那個(gè)主題的文章查了幾十篇,然后進(jìn)行資料分類,寫出了一篇很漂亮的讀書報(bào)告。很幸運(yùn)的被老師選為3份最優(yōu)秀的讀書報(bào)告,上講臺(tái)去講。我這份報(bào)告寫得很好,但是報(bào)告里寫的內(nèi)容我是完全不明白,結(jié)果講的一塌糊涂。不一定非要懂才能寫得好一份報(bào)告,你只需要善于歸納總結(jié)即可。
到目前為止,反轉(zhuǎn)片的原理俺依然是毫無頭緒,但問題已經(jīng)解決了——我成功將這一特效用寥寥幾行代碼實(shí)現(xiàn),集成在我的程序中!解決問題是一門藝術(shù)。