基於Java的圖像象素處理(1)

原文作者:Richard G. Baldwin
翻譯:Olajavaman
本文是因爲我近期的工作需要用到Java處理圖像的相關知識,發現國內關於Java如何處理圖像象素的文章幾乎爲零,國外這個Richard是一個美國德州的高校教授,他編寫的這個e文材料,通俗易懂,故想翻譯出來給國內的Java程序員用,當然如果您的e文很好,建議看原文,因爲我畢竟非英語專業出身,翻譯不當之處,還請各位看官多多指點,另外,未經本人許可,這個譯文不得隨意轉載。
l         提綱
l         序言
l         背景材料
l         概論
l         對樣例代碼的討論
l         運行程序
l         總結
l         下一步
l         程序清單
序言
目的
這是一篇告訴你如何直接通過Java語言操作圖象象素的文章。
不是JAI(Java advance Image)的教程
如果您是檢索JAI的使用,而找到這個文章,當然也是受歡迎的  但是,我還是要羅嗦一下:這個畢竟不是一個JAI的教程,這個文章向您展示了一個如何利用常規算法直接操作象素以獲得一些特殊的圖像處理結果泥潭。.
直接和個別地操作圖像象素
在這個教程裏面我們將解釋如何簡單地操作象素:
1.         操作和修改一個特定地圖形象素
2.         顯示和修改原始圖象,如何比較?
程序框架或者是稱之爲驅動
這個程序可以用於想直接操作圖象象素的框架或者驅動的用途
如果將這個程序用爲驅動,你只要關注如何書寫和執行圖像處理算法,而不用爲如何處理圖像文件,圖象顯示等等的煩惱。
一個簡單的圖像象素操作案例
在這個教程中,我將提供和解釋一些如何直接操作象素的圖像處理的程序
這個教程的例子只是起到一個拋磚引玉的作用,但是這個例子和你未來的圖像處理意圖可能是有關聯的。
接下來的教程將展示一些很常見和不太常見的圖像處理程序,這些程序包含了:
l         高亮一個圖形的某個特殊區域
l         將圖像的一個部分和全部模糊
l         將圖像的一個部分和全部銳化
l         處理圖像邊界
l         進行圖像的色彩過濾
l         將圖像顏色反轉
l         將一個圖像融入另一個圖像
l         旋轉一個圖像
l         壓縮一個圖像成更小的尺寸
l         使用線性和非線性算法來控制一個圖像的亮度
l         其他的一些我在做這個課題研究時發現圖像處理手段
一下圖例是一些處理的例子
查看提示
你可以打開兩個瀏覽器來對比這些效果,會讓你更爲直觀。
 
高亮一個圖片
 
這個海星是在魚缸中拍攝的,高亮之後它看起來更像是一個潛水員在深海拍攝的效果

Fig(1)
上部是原始圖像, 下面是處理之後的圖像
這個程序是可以由用戶來控制這個聚光燈的射程的,換句話說,照明的範圍(從中心到四周)是可以調節的。
模糊一個圖像

圖2採用了一個常用算法來模糊一個圖像
上部是原始圖像, 下面是處理之後的圖像
這個模糊度同樣也是可控的,可以由不模糊到完全模糊範圍調節
銳化圖像
圖3展示了圖像銳化的算法, 一般來說銳化是用於展示圖像的細節。

Figure 3
圖3採用的是常用的銳化算法. 當然是否取得良好的結果, 必須由觀衆的眼睛來評測, 但是我認爲是有效果的, 上圖下部顯示出來的眼角皺紋和指甲的邊緣, 都是在上圖上部看不清楚的。
邊緣檢測
這個效果的用途一般是用於高亮兩個同一個圖像中的不同的物體邊緣, 這些邊緣一般會出現顏色的變化和產生陰影, 譬如文字或者符號在背景上, 也會產生邊緣。
圖4您可以看出這個邊緣的效果.
Figure 4
您可能非常認可這個算法, 因爲我們可以迅速的認出手指, 指甲, 眼睛, 虹膜以及鼻子的輪廓。
 
理論結合實際操作
接下來我會講一些基本算法理論, 當然包含上面的圖例算法, 我也會講述如何利用Java語言實現這些算法。我還會提到一些應用場合.
 
不承諾
我所提供的算法不是用於高質量的產品設計的, JAI裏面已經有許多很好的算法可以用來實現一些用途,我所提供的程序是用來讓你瞭解和開發自己的算法, 同時知道爲什麼要這樣做。
背景知識
圖像的結構, 存儲和渲染
 
在講述程序細節之前, 我要講清一些概念:在Java裏面圖像是如何構建, 存儲, 傳輸和渲染的。
色點的數組――象素
在現代計算機裏面, 爲了讓人們的視覺感受, 一個圖像是由一些點來組成, 這些顏色點很小, 乃至人們的眼睛沒法分辨出來他們的距離,所以人們視覺認爲是一片連續的顏色。這些色點稱之爲象素, 我們認爲這個也是圖像理論的起源。
圖像文件
這些象素被存放在文件中, 被一次錄入到文件裏面, 或者被重構成一個圖像, 顯而易見, 這麼多的象素放在一個文件裏面將是一個巨大的文件, 不同的文件格式有不同的壓縮算法,還原質量和有利有弊的特點,
對文件格式不敢興趣
我們對文件格式不敢興趣, 只是對解壓之後的像素感興趣, 我提供的驅動可以讀取gif, jpg和其他的一些格式。
取出象素點
我們最初感興趣於那些從文件解壓出來成一維狀態的象素點。 我們將把他們轉換成3維的結構, 以利於圖像處理,一旦我們理解了這些圖像處理的過程, 我們會發現3維的結構更方便處理一些。
顏色象素網格
每個3維的對象對應了一個象素的組成,當我們渲染的時候, 這些網格將按照橫豎排序,一條座標標識了這個象素的橫座標, 另一個是縱座標, 第3個是這個顏色(和透明度)的值。
返回基礎理論
在計算機裏面,一個象素由4個字節組成, 其中3個代表R,G, B的值, 另一個是表示透明度或者叫做alpha字節。
RGB的混合
一個顏色都是由R,G,B三種顏色混合而成,也就是說, 我們需要在計算機顯示一個顏色是, 就是定義了一定的R,G,B值
顏色的範圍
一個無符號位的顏色值可以是0-255(包含255),如果紅色爲的值是0就表示沒有紅色被混合在這個顏色裏面。
黑和白
如果R=0 G=0 ,B=0這個象素點是黑色, 如果R=255 G=255 ,B=255這個象素點是白色, 如果R=G=B!=0!=255,這個象素顏色就是灰色。
16百萬色
在黑色和白色之間, 每個RGB的值都有256中可能, 因此計算機可以顯示16百萬種顏色, 但是認得眼睛分辨不出來。.
顏色的底線
一個象素是由3個字節來表示他的顏色, 任何一個值的改變, 將改變這個顏色。
透明
我們將解釋透明, 這個 alpha 直接也是有256中可能, 如果是0, 表示完全透明, 反之=255的時候, 完全不透明。
0 - 255
作爲一個例子, 我們假設你要在一個玻璃的窗戶上刷上紫色漆,你可能看不到窗戶外面的綠樹,這個就是不透明。假設您刷的漆沾性不好, 在它幹了以後, 你可能還能透過紫色看到綠樹,這個就是很好的描繪了alpha字節的功效,當一個象素被防止在屏幕之後, 又有一個象素在同一個位置被防止, 那麼前一個象素是否顯示他的顏色將取決於後一個的alpha字節
四個字節被封裝成一個整數
當一個圖像文件被解壓之後, 每個象素被4個字節來表示, 剛好是整數方式, 然而你不要以爲真的是一個整數, 確確的說, 整數也是有四個無符號的字節首位相連組成的。
四個字節的順序
0-     透明度
1-     R 值
2-     G值
3-     B值
我們的任務是要獲得這些值, 可以通過移位運算>>和&與運算獲得各個字節的值。Java不支持無符號位的算法, 這個讓人覺得非常麻煩, 因此我們把一個象素轉換成int類型,讓算法更爲容易一些。
附註
我建議你們也學習一下我的其他的Java練習讀物,你可以獲得這些課程從這個網站:www.Gamelan.com. 或者在這個網站得到我的文章索引:www.DickBaldwin.com.
預覽程序
兩個程序一個接口
在這個課程裏面我將給出兩個程序和兩個接口。兩個程序是: ImgMod02.java 和 ProgramTest.java.爲了方便敘述, 我把這兩個程序合在一個源文件裏面。
那個ImgMod02 是一個框架程序. 另一個ProgramTest是一個圖像處理程序
接口的名字是 ImgIntfc02. 它位於獨立的源文件裏面。.
processImg 方法
在ProgramTest裏面,實現了 ImgIntfc02接口. 這個接口聲明瞭一個方法processImg, 所有實現類必須實例化的方法。
這個方面傳遞進來的是3維數組, 返回的也是處理過的3維數組。
處理前後的顯示
當processImg 返回3維數組之後,我們必須要在畫布上繪製原始圖像和處理之後的圖像
默認圖像處理方法
如果用戶沒有實例化具體的圖像處理方法,這個程序將實例化一個ProgramTest對象, 並用ProgramTest的processImg方法
默認的圖像文件是junk.gif, 在程序的當前目錄中
ProgramTest 的行爲
爲了方便敘述, 我們在處理ProgramTest 的processImg時, 只是在原始圖片時加了一個白線, 如Figure 5所示:
 
 
控制這個斜線
Figure 5 的斜線斜率=1。0,  ProgramTest提供了一個對話框讓你設定他的斜率。
透明行爲

在畫這線的時候,我們設置這個線是不透明的

(待續......)

作者的blog: http://blog.csdn.net/oldjavaman

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章