1. 程式人生 > >基於Java的影象象素處理(1)

基於Java的影象象素處理(1)

翻譯: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提供了一個對話方塊讓你設定他的斜率。 透明行為

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

(待續......)