當前位置: 首頁 > 新聞動態

談談數字圖像的縮放算法檔

2012-08-23 強訊科技 供稿 【
  圖像的概念很容易理解,你睜開眼睛,所看到的都是圖像了。數字圖像的縮放,是一個十分有趣的問題,又是一個看似簡單,但又有些復雜的問題。

數字圖像的縮放,是一個十分有趣的問題,又是一個看似簡單,但又有些復雜的問題。許多朋友在具備一定的計算機圖形編程的基礎知識以后,都可以自己設計出一些簡單的位圖縮放算法。在計算機圖形學和數字圖像處理等學科里面,已經詳細的研究過了數字圖像縮放這個問題,并且已經有了成熟的算法。一些朋友由于沒有學習過計算機圖形學和數字圖像處理,所以憑借自己的想法設計的位圖縮放算法存在許多缺陷。在本文中,我將和大家一起來研究這個問題,并且學習前人所總結出來的算法。

圖像的概念很容易理解,你睜開眼睛,所看到的都是圖像了。而一幅畫、一張照片,則是現實生活中記錄圖像的手段和載體。在科學上,我們需要對我們的研究對象建立起數學模型,因此有必要建立起圖像的數學模型。一幅圖像的數學模型可以簡單的定義如下:
+-----------------------------------------------------+
    Image = f(x, y);
    其中x, y 為[0, 1] 上的實數
    對于灰度圖像Image 也為[0, 1] 上的實數
    對于彩色圖像Image 則由R, G, B 三個分量組成
+-----------------------------------------------------+
由于定義域和值域都在[0, 1] 上,因此被稱為連續圖像模型
連續圖像模型可以精確而完整的刻畫所要描述的圖像,然而在現實世界中,絕大多數圖像都是無法通過這個數學模型進行描述的,因為現實世界中的圖像,是不可能通過函數解析式的方法進行描述的。更多的時候,我們只能使用相機將現實圖像的一部分信息,保存在膠片上,或者是使用畫筆在畫紙上繪制出圖像。正是由于圖像的這個特點,我們所建立的連續的圖像模型,對研究圖像而言,并沒有什么用武之地,而傳統的數學研究方法也因此無法用運用到圖像上。

為了更加有效的研究和處理圖像,我們利用離散數學的理論知識,為現實圖像建立起了數字圖像模型,并且使用計算這個強大的工具來幫組我們研究和處理圖像。數字圖像模型的定義如下:
+-----------------------------------------------------+
    Image = array(i, j);
    通常情況下i 是大于等于0, 小于等于w 的整數
    而j 是大于等于0, 小于等于h 的整數
    array 可以理解為一個矩陣
    Image 的取值范圍為大于等于0, 小于等于255 的整數
    對于灰度圖像Image 表示某點的亮度值
    對于彩色圖像Image 則由R, G, B 三個分量組成
+-----------------------------------------------------+
其中的w, h 通常被稱為一幅數字圖像的寬度和高度。這里,數字圖像的寬度和高度,與一幅數字圖像在顯示器上實際的寬度和高度,有著一定的對應關系的,這個大家應該都很容易理解。我們所要討論的數字圖像的縮放問題,就是要改變一幅圖像的寬度和高度,并且使array(i, j) 這個矩陣中的數據相應的改變,使得圖像按比例的進行縮放。

在數字圖像處理上,數字圖像的縮放又被稱作重采樣濾波,這很抽象但是卻又深刻揭示出數字圖像縮放的本質。當你將重采樣濾波這個概念理解了,你會發現位圖縮放是如此的簡單明了,并會驚奇的發現重采樣濾波是如此的神奇而深刻。

現在為了敘述的方便,我們將現實生活中所遇到的圖像稱為現實圖像,將照片等稱為物理圖像,將連續圖像模型成為連續圖像,將數字圖像模型成為數字圖像或位圖。那么,我們來看看一幅數字圖像的產生過程。

首先,需要使用相機對現實圖像進行拍照,產生照片,即物理圖像。在物理圖像中,僅僅記錄了現實圖像中的一部分信息。然后要將照片放到掃描儀上進行掃描,這個過程中圖像從物理圖像變換為了數字圖像,在計算機中產生通常所說的位圖。在圖像從物理圖像變換為數字圖像這個過程中,最關鍵的地方就是采樣與量化,這兩個概念大家也許都非常熟悉,但是我們仍然需要深刻的理解和思考。

假如說,在掃描的過程中,我們將掃描的分辨率設置較大,也就是采樣率設置較大,則掃描出來的數字圖像的分辨率也較大,也就是圖像的寬度和高度都較大,反之,則是變小。讓我們再來深刻的理解下重采樣濾波這個概念,所謂重采樣濾波,指的是根據數字圖像,以某種方式重建出物理圖像,并且對這個重建出來的物理圖像,以所需要的采樣率進行重新采樣。

讓我們來設想這樣一個過程,我們有一幅寬高分別為(w1, h1) 的位圖A,我們想要將其縮放為寬高為(w2, h2) 的位圖B. 我們可以通過這樣的手段來完成縮放,也就是花一千塊左右,買一臺佳能的彩色激光打印機,將位圖A 用打印機打印出來。然后再買一個惠普的掃描儀,以(w2, h2) 的掃描分辨率,將前面打印出來的圖片掃描到電腦。這樣,我們就順利地完成了位圖的縮放。當然,這樣的做法成本太高,先后需要花去一千多塊的大洋,而且費時又費力,是個理論上可行卻不實用的辦法。但是,這個辦法,足以生動而清晰地說明數字圖像縮放的本質和方法。

讓我們再來體會一下重采樣濾波的深刻吧,即重建物理圖像,然后以你所需要的分辨率進行重新采樣。在計算機世界里,數字圖像是很容易描述的,用一個二維數組就可以簡單的描述一幅數字圖像。然而,我們怎樣才能從已有的數字圖像,重建其物理圖像呢?好好想想吧,想不出來就只快點準備兩千塊大洋,去買打印機和掃描儀吧。不是吧大哥,難道我真要去買打印機,趕快揭曉答案。

好吧不開玩笑了,現在揭曉答案。在計算機中,重建物理圖像其實是一種計算模型而已,物理圖像在計算機世界里面是無法真正的重建的,畢竟計算機是離散系統,而物理圖像是連續的事物,計算機無法完整而精確的進行描述。然而我們卻可以找到多種的計算模型,來描述我們需要重建的物理圖像。需要注意的是,我們找到的是計算模型,然后我們要根據這個計算模型,來進行重新采樣。

圖像從現實圖像到物理圖像再到數字圖像的變換過程,是一個不可逆的變換過程,在每一次變換過程中,都會丟失掉大量的信息,是不可逆的。如果想要從數字圖像重建物理圖像,其實是在已有的數字圖像數據的基礎上,對物理圖像做出的一種近似而已。對于已有的數字圖像,我們有多種計算模型,來重建物理圖像,而這個重建的物理圖像,一般都是通過前面所講的連續圖像模型來描述。先介紹最簡單的計算模型,最近鄰算法。

請大家思考這樣一些問題:
    1. 我有一張320 * 240 * 24bit 色的BMP 圖片,對于圖片上任一點(i, j) 我們都可以知道它的RGB 顏色值,但是如果我想知道(101.3, 98.6) 點的顏色值,我們該怎么辦呢?

    2. 我希望將一張320 * 240 * 24bit 色的BMP 圖片,縮放為1005 * 754 * 24bit 色的BMP 圖片,該如何進行重新采樣呢?

第一個問題,也就是數字圖像縮放的第一步,重建物理圖像。如果我們采用最近鄰算法,對于一個非整數的坐標點,我們選取距離這個點最近的整數坐標點的顏色值,作為其顏色值。也就是說,我們簡單的將(101.3, 98.6) 的顏色值取為點(101, 99) 的顏色值。解決了這個問題,我們的腦子里面其實就放著一幅連續的圖像了,并且對于這個連續圖像上的任意一個像素點,我們都可以計算出其顏色值。

第二個問題,則是如何在重建起來的物理圖像上進行重采樣。所謂采樣,就是要取得每個需要采樣的顏色值,也就是要用一個二重循環,處理完1005 * 754 個點,并且計算出每個點的顏色值。簡單的代碼如下:
+-------------------------------------------------------------------------+
    DWORD color;
    int   i;
    int   j;
    for (j=0; j<754; j++)
    {
        for (i=0; i<1005; i++)
        {
            color = resample(i, j);         // 計算重采樣點的顏色值
            putpixel(destbmp, i, j, color); // 將采樣點繪制到目的位圖上
        }
    }
+-------------------------------------------------------------------------+

對于每個重采樣點的顏色值的計算方法,則是需要根據原始的數字圖像、你所選用的計算模型和由計算模型所重建的物理圖像來共同決定。對于我們上面的例子,可以先計算出寬高縮放比,進而建立起原始圖像和目的圖像中像素點的對應關系和變換公式,根據變換公式,計算出目的圖像中(i, j) 點在 原始圖像中對應的點的坐標(x, y),根據重建物理圖像的計算模型,計算出原始圖像中(x, y) 點的顏色值 c,然后將c 作為結果繪制到目的圖像中的(i, j) 上。當你處理完目的圖像中的每一個像素點,也就完成了數字圖像的縮放了。

對于我們所舉的例子,可以寫出如下的代碼:
+-------------------------------------------------------------------------+
    int   w1     = 320;
    int   h1     = 240;
    int   w2     = 1005;
    int   h2     = 754;
    float xratio = (float) w1 / w2;
    float yratio = (float) h1 / h2;
    int   i;
    int   j;
    float x;
    float y;

    for (j=0; j<754; j++)
    {
        for (i=0; i<1005; i++)
        {
            x = i * xratio;
            y = j * yratio;
            color = getpixel(srcbmp, (int)(x + 0.5), (int)(y + 0.5));
            putpixel(destbmp, i, j, color);
        }
    }
+-------------------------------------------------------------------------+

其中| x = i * xratio; y = j * yratio; | 兩句代碼體現采樣的位置,即在重建出來的圖像的什么位置進行采樣,而| color = getpixel(srcbmp, (int)(x + 0.5), (int)(y + 0.5)); | 這句代碼則體現了采樣的結果,即在重建出來的圖像的(x, y) 處的采樣的顏色值到底是多少。

請大家認真體會其中的深刻意義,所謂重建物理圖像,實際上是無法真正重建的,也就是說這只是一種計算模型,一種方法。而重采樣濾波,則是在計算模型的基礎上進行的重新采樣。數字圖像縮放的精妙和深刻之處,就被重采樣濾波這樣一段話,簡短而深刻地概括了。

通過以上的介紹,大家應當明白了數字圖像縮放的基本原理和實現方法,并且能夠利用最近鄰法的計算模型,寫出通用的位圖縮放程序。可以看到,位圖縮放的算法框架其實是非常簡單的,關鍵還是需要理解其中的原理和方法。位圖縮放的最近鄰算法,在我的圖形庫中已經實現,大家可以在我的圖形庫中找到代碼進行參考。

接下來介紹更多的重建物理圖像的計算模型。除了最近鄰點算法之外,還有雙線性插值算法和曲面插值算法。其中雙線性插值算法比較簡單,且易于計算,因此在工程上得到了廣泛的運用。而曲面插值可以得到更好的圖像效果,但是其插值原理和計算方法都比較復雜,本文不再介紹。

所謂線性插值,大家應該不陌生,舉個最簡單的例子來說明問題。f(99) = 32, f(100) = 65, 用線性插值法求f(99.3) 的值。方法如下:

  f(100) - f(99)      f(100) - f(99.3)
----------------- = --------------------
    100 - 99             100 - 99.3

根據以上方程即可求出f(99.3) 的值。之所以稱為線性,是由于三個點都位于一條直線上。將以上的線性插值推廣到二維情況,即是我們通常所說的雙線性插值。

同樣用一個例子說明問題:
f(123, 221) = 231, f(124, 221) = 35
f(123, 222) = 213, f(124, 222) = 86
求f(123.8, 221.2) 的顏色值。
解,利用一維的線性插值,根據f(123, 221)   和f(123, 222)   求得f(123, 221.2)
    利用一維的線性插值,根據f(124, 221)   和f(124, 222)   求得f(124, 221.2)
    利用一維的線性插值,根據f(123, 221.2) 和f(124, 221.2) 求得f(123.8, 221.2)
    問題得解。

在雙線性茶值中,大家可以證明先沿x 坐標計算和先沿y 坐標計算,最終的結果都是一樣的。當然,在實際運用中,大家還需要推算出通用的計算公式,在這里僅僅是以例子說明問題。

講了這么多,應該是把數字圖像縮放這個問題介紹得比較清楚了。大家關鍵還是需要理解數字圖像的本質,采樣和量化的概念,以及根據數字圖像重建物理圖像和重采樣,即重采樣濾波。最后再告訴大家兩個概念,即數字圖像的縮小,被稱為降采樣濾波,而放大則稱為過采樣濾波(這個不知道是不是這樣叫的,就算我自己發明的叫法吧)。希望大家再看完本文以后,能夠有所收獲,理解數字圖像縮放的原理和方法,并且實現自己的位圖縮放程序。

分享到:

北京強訊科技有限公司-呼叫中心專家 版權所有© 2013     客戶服務熱線:400-700-8003   值班電話:151-2001-5266

  • 聯系電話    北京總部:(010)82015266  上海:(021)64865166  廣州:(020)83503506
现代战争走势图 北京pk10今天开奖记录 闲徕麻将赚钱 新浪体育加载失败 公式规律-王中王 沈阳麻将最大多少番 nike新浪体育网 惠州滴滴打车z赚钱吗 广西快乐双彩预测 012曾道人三尾中特书 体球比分网 网易比分直播 秒速时时彩哪个平台好 三人麻将游戏 竞猜足球指数 江西时时彩稳赚技巧 福建福彩网