1. 程式人生 > >60701BMP彩色影象轉化為灰度及二值影象

60701BMP彩色影象轉化為灰度及二值影象

1 概述

  多媒體技術是一門綜合了多種學科的新技術,其涉及到電腦科學與技術、通訊和網路技術、人工智慧技術、微電子技術、數字訊號處理、圖形處 理技術、聲像技術等諸多學科。許多新技術的不斷出現和體驗,帶給人們工作和生活巨大的改變。其應用已經滲透到社會生活和工作的各個方面。

 

1.1背景

   多媒體技術是20世紀80年代發展起來的一種新技術,是將文字、圖形、影象、動畫、聲音、視訊等資訊通過計算機處理,形成人機互動作用的技術。多媒體技術的發展同時也改變了計算機的使用領域,由僅僅限於專業辦公領域擴充套件到各行各業,以及家庭生活和大眾娛樂等方方面面。很大程度上改善了我們的學習和生活。隨著計算機技術、網路通訊技術、電子資訊等技術的快速發展,多媒體技術的應用和發展也面臨著更大的機遇。

圖1.1 多媒體技術與應用

  本課程多媒體技術與應用可分為多媒體實用技術和多媒體技術應用兩方面,其中多媒體技術應用於生活、教學、藝術等方面,多媒體實用技術可分為基本概念、多媒體計算機系統、多媒體音訊技術、多媒體視訊技術、多媒體資料壓縮技術、影象與影象處理技術、超文字與超媒體技術、多媒體應用系統設計、多媒體應用系統創作工具、多媒體應用程式設計、圖形、影象設計技術、數字音訊設計技術、數字視訊設計技術幾部分,本次課程選題為多媒體應用程式設計中的圖形、影象設計技術,基於C語言實現BMP彩色影象轉化為灰度及二值影象。

 

1.2設計的簡要介紹

  本次課程設計選題基於C語言實現一種BMP彩色影象轉化為灰度及二值影象程式,屬於多媒體實用技術中多媒體應用程式設計的一個分支,具體是一種圖形、影象設計技術,選取BMP彩色數字影象作為實驗目標,將其轉化為灰度模式和二值模式。本次課程設計將採用提出問題、分析問題、解決問題、驗證與實驗、總結的思路完成。

 

2 設計

BMP檔案因其“所見即所得”的特點,儘管檔案大小比較大,但是點陣圖檔案的簡單性、在微軟視窗和其他地方的廣泛使用以及這種格式的優秀文件標準以及沒有專利約束,使得它成為其他作業系統影象處理程式能夠讀寫的一種最為常用的格式。本次課程設計就是利用C語言實現其顏色模式的轉換。

 

2.1重要概念

2.1.1 BMP數字影象檔案結構

  Windows使用的圖形檔案格式主要是BMP圖形資訊檔案,在Windows背景下交換、執行與點陣圖相關的資訊的標準格式,同時BMP影象資訊檔案格式是全部影象資訊處理軟體都支援。Windows顯示影象資訊標準與繪畫影象均以BMP影象資訊格式。Windows3.0前期的BMP影象資料資訊格式和顯示器引數相關聯,故將此類BMP格式影象資訊檔案稱之為裝置引數相關點陣圖DDB(device-dependent bitmap)檔案資料格式。Windows3.0後期的BMP影象資料資訊和顯示器引數無關聯,故將此類BMP格式影象資訊檔案叫作裝置引數無關點陣圖DIB(device-independent bitmap) 資料格式,目標主要是讓Windows可以在任一類別的顯示裝置上呈現所留存的資料檔案。BMP點陣圖資訊資料採用檔案字尾名是BMP或bmp。

 

圖2.1 BMP檔案結構

  標準的點陣圖影象檔案結構是包含四部分組成:點陣圖檔案頭、點陣圖資訊頭、調色盤和定義點陣圖的資料序列,其具體的資料檔案格式特點和形式,點陣圖檔案結構如圖2.1所示。支援單色、16色、256色和全綵色(目前最高位為32位)四種影象方式;每個點陣圖檔案僅一幅儲存影象;影象儲存時提供兩種模式為非壓縮和壓縮。

 

2.1.2 灰度影象

  在計算機領域中,灰度(Gray scale)數字影象是每個畫素只有一個取樣顏色的影象。這類影象通常顯示為從最暗黑色到最亮的白色的灰度,儘管理論上這個取樣可以是任何顏色的不同深淺,不同亮度上的不同顏色。灰度影象與黑白影象不同,在計算機影象領域中黑白影象只有黑白兩種顏色,灰度影象在黑色與白色之間還有許多級的顏色深度。但是,在數字影象領域之外,“黑白影象”也表示“灰度影象”,例如灰度的照片通常叫做“黑白照片”。在一些關於數字影象的文章中單色影象等同於灰度影象,在另外一些文章中又等同於黑白影象。

  灰度影象經常是在單個電磁波頻譜如可見光內測量每個畫素的亮度得到的。用於顯示的灰度影象通常用每個取樣畫素8 bits的非線性尺度來儲存,這樣可以有256種灰度(8bits就是2的8次方=256)。這種精度剛剛能夠避免可見的條帶失真,並且非常易於程式設計。在醫學影象與遙感影象這些技術應用中經常採用更多的級數以充分利用每個取樣10或12 bits的感測器精度,並且避免計算時的近似誤差。在這樣的應用領域流行使用16 bits即65536個組合(或65536種顏色)。

 

2.1.3 二值影象

  二值影象是每個畫素只有兩個可能值的數字影象。人們經常用黑白、B&W、單色影象表示二值影象,但是也可以用來表示每個畫素只有一個取樣值的任何影象,例如灰度影象等。

二值影象經常出現在數字影象處理中作為影象掩碼或者在影象分割、二值化和dithering的結果中出現。一些輸入輸出裝置,如鐳射印表機、傳真機、單色計算機顯示器等都可以處理二值影象。二值影象經常使用點陣圖格式儲存。

 

2.2 相關原理、演算法

2.2.1 彩色轉灰度方法一

  任何顏色都有紅、綠、藍三原色組成,假如原來某點的顏色為 RGB(R,G,B),那麼,我們可以通過下面幾種方法將其轉換為灰度:

  浮點演算法: Gray=R*0.3+G*0.59+B*0.11

  整數方法: Gray=(R*30+G*59+B*11)/100

  移位方法: Gray =(R*28+G*151+B*77)>>8;

  平均值法: Gray=(R+G+B)/3;

  僅取綠色: Gray=G;

  通過上述任一種方法求得 Gray 後,將原來的 RGB(R,G,B)中的R,G,B 統一用 Gray 替換,形成新的顏色 RGB(Gray,Gray,Gray),用它替換原來的 RGB(R,G,B)就是灰度圖。

 

2.2.2 彩色轉灰度方法二

  改變象素矩陣的 RGB 值,來達到彩色圖轉變為灰度圖加權平均值演算法: 根據光的亮度特性, 其實正確的灰度公式應當是

  R=G=B=R*0.299+G*0.587+B0.144

  為了提高速度我們做一個完全可以接受的近似,公式變形如下:

  R=G=B=(R*3+G*6+B)/10

 

2.2.3 彩色轉二值影象

  二值圖只有兩個顏色,黑和白,而灰度有256種顏色,將灰度轉化為二值是選取一個閾值,將灰度值大於這個閾值的置成白色,反之為黑色。

  關於閾值的選取有固定值法、雙峰法、P引數發、大津法(0tsu法或最大類間方差法)、最大熵閾值法、迭代法(最佳閾值法)等方法。

 

2.3 設計思路

  需求分析,按照選題要求,將採用讀取檔案,選擇功能,執行操作的思路完成程式,具體邏輯結構如圖2.2。即目標程式的邏輯為主函式開始執行,讓使用者輸入待處理檔案(原始檔)和目標檔案絕對路徑,判斷是否正確,正確進行下一步讓使用者選擇功能,根據使用者選擇功能呼叫相應的函式執行相應的操作,即為目標設計程式工作流程。

 

圖2.2 目標程式工作流程

  流程設計,為實現上述目標程式,將採用程式準備、讀入檔案路徑、功能函式設計、功能整合的設計思路完成目標程式。

 

2.3.1 程式準備

  1)根據2.1.1,定義點陣圖檔案頭

  這部分資料塊位於檔案開頭,用於進行檔案的識別。典型的應用程式會首先普通讀取這部分資料以確保的確是點陣圖檔案並且沒有損壞。所有的整數值都以小端序存放(即最低有效位前置)。

圖2.3 點陣圖檔案頭

  2)定義檔案資訊頭(DIB頭)

  這部分告訴應用程式影象的詳細資訊,在螢幕上顯示影象將會使用這些資訊,它從檔案的第15個位元組開始。這部分資料塊對應了Windows和OS/2中的內部使用的頭結構以及其它一些版本的變體。但所有版本均以一個DWORD位(32位)開始,用以說明該資料塊的大小,使得應用程式能夠根據這個大小來區分該影象實際使用了哪種版本的DIB頭結構。

  存在多種版本的頭結構的原因是微軟對DIB格式進行過多次擴充套件。圖2.4即為所有不同版本的DIB頭:

圖2.4 不同版本的DIB頭

  BITMAPCOREHEADER之後的版本都只是在前一版本結構末尾追加欄位。

  出於相容性的考量,大多數應用程式使用較舊版本的DIB頭儲存檔案。在不考慮OS/2的情況下,目前通用的格式為BITMAPINFOHEADER版本,內容在圖2.5中列出。除非有特殊說明,其中所有值均為無符號整數。

 

圖2.5 BITMAPINFOHEADER版本DIB頭

  3)定義調色盤

  這部分定義了影象中所用的顏色。如上所述,點陣圖影象一個畫素接著一個畫素儲存,每個畫素使用一個或者多個位元組的值表示,所以調色盤的目的就是要告訴應用程式這些值所對應的實際顏色。

  典型的點陣圖檔案使用RGB彩色模型。在這種模型中,每種顏色都是由不同強度(從0到最大強度)的紅色(R)、綠色(G)和藍色(B)組成的,也就是說,每種顏色都可以使用紅色、綠色和藍色的值所定義。

  在點陣圖檔案的實現中,調色盤可以包含很多條目,條目個數就是影象中所使用的顏色的個數。每個條目用來描述一種顏色,包含4個位元組,其中三個表示紅色、綠色和藍色,第四個位元組沒有使用(大多數應用程式將它設為0);對於每個位元組,數值0表示該顏色分量在當前的顏色中沒有使用,而數值255表示這種顏色分量使用最大的強度。

  4)定義其他資料

  X Window System使用類似的.XBM格式表示一位黑白影象以及.XPM(pixelmap)表示彩色影象。另外還有一種.RAW格式,它除了儲存原始資料之外沒有任何其他資訊。其他還有Portable Pixmap file format(.PPM)和Truevision TGA(.TGA),但是它們用得很少或者只用於特殊目的。儘管其他格式也儲存為“點陣圖”(與向量圖不同),但是它們使用資料壓縮或者顏色索引,所以它們不是嚴格意義上的點陣圖。

  由於包含有冗餘資訊,許多BMP檔案使用類似於ZIP這樣的無損資料壓縮演算法能夠獲取很好的壓縮效果。

 

2.3.2 讀入檔案路徑

  定義兩個大小為100的字元陣列儲存路徑,輸出提示,讓使用者輸入絕對路徑,並存儲在字元陣列中。判斷字元數字內路徑是否為空,為空則開啟失敗。注意原始檔是rb+的開啟方式,而目標檔案是wb的開啟方式。

 

2.3.3 功能函式彩色轉灰度影象設計

1)讀取點陣圖頭結構和資訊頭,

2)修改資訊頭,修改檔案頭,

3)建立調色盤,

4)寫入檔案頭、資訊頭、調色盤

5)呼叫2.2.2的公式將點陣圖資訊轉為灰度,

6)釋放記憶體空間,關閉檔案

 

2.3.4 功能函式彩色轉二值影象設計

1)建立點陣圖檔案頭,資訊頭,調色盤

2)讀入源點陣圖檔案頭和資訊頭

3)修改檔案頭,資訊頭資訊

4)將點陣圖檔案頭,資訊頭和調色盤寫入檔案

5)將彩色圖轉為二值圖,這裡選取閾值為90

6)釋放記憶體空間,關閉檔案

 

2.3.5 功能整合

1)輸入檔案路徑

2)判斷路徑是否合法

3)輸出功能選項

4)輸入選擇功能

5)根據選擇功能呼叫函式

6)執行成功輸出提示符

 

3 實現

3.2 開發環境

作業系統:使用Windows10專業版64位作業系統

開發語言:C語言

開發工具:Dev-C++

 

3.2 主要程式碼與說明

3.2.1 程式準備

根據2.3.1進行程式準備,程式碼及註釋如下:

     /* 定義點陣圖檔案頭 */   
    typedef struct tagBITMAPFILEHEADER  
    {  
        unsigned short bfType;//檔案格式  
        unsigned long bfSize;//檔案大小  
        unsigned short bfReserved1;//保留  
        unsigned short bfReserved2;//保留   
        unsigned long bfOffBits; //DIB資料在檔案中的偏移量  
    }fileHeader;  
    /* 點陣圖資料資訊結構 */  
    typedef struct tagBITMAPINFOHEADER  
    {  
        unsigned long biSize;//該結構的大小,BITMAPINFOHEADER結構所需要的字數   
        long biWidth;//檔案寬度,畫素為單位   
        long biHeight;//檔案高度,畫素為單位,為正數,影象是倒序的,為負數,影象是正序的   
        unsigned short biPlanes;//平面數,為目標裝置說明顏色平面數,總被置為1   
        unsigned short biBitCount;//顏色位數,說明位元數/畫素   
        unsigned long biCompression;//壓縮型別,說明資料壓縮型別   
        unsigned long biSizeImage;//DIB資料區大小,說明影象大小,位元組單位   
        long biXPixPerMeter;//水平解析度,畫素/米  
        long biYPixPerMeter;//垂直解析度  
        unsigned long biClrUsed;//多少顏色索引表,顏色索引數   
        unsigned long biClrImporant;//多少重要顏色,重要顏色索引數,為0表示都重要   
    }fileInfo;  
    /* 調色盤結構 */  
    typedef struct tagRGBQUAD  
    {  
        unsigned char rgbBlue; //藍色分量亮度  
        unsigned char rgbGreen;//綠色分量亮度  
        unsigned char rgbRed;//紅色分量亮度  
        unsigned char rgbReserved;  
    }rgbq;  
    /* 其他資料 */   
    typedef struct OtherData    
    {    
        unsigned char extradata;    
        struct OtherData *next;    
    }OtherData;  

 

3.2.2 讀入檔案路徑

根據2.3.2讀入檔案路徑,程式碼如下:

char inPath[100],outPath[100];  
scanf("%s",inPath);  
scanf("%s",outPath);  
FILE *fp1 = fopen(inPath, "rb+");  
if (fp1 == NULL)  
{  
    printf("開啟檔案fp1失敗");  
    return 0;  
}  
FILE *fp2 = fopen(outPath, "wb");  
if (fp1 == NULL)  
{  
    printf("開啟檔案fp2失敗");  
    return 0;  
}  

 

3.2.3 功能函式彩色轉灰度影象設計

根據2.3.3,其中將點陣圖資訊轉為灰度程式碼如下:

    /* 將點陣圖資訊轉為灰度 */   
    //儲存bmp一行的畫素點  
    unsigned char ImgData[3000][3];  
    //將灰度影象存到一維陣列中  
    unsigned char ImgData2[3000];  
    for (i = 0; i<fi->biHeight; i++)  
    {  
        for (j = 0; j<(fi->biWidth + 3) / 4 * 4; j++)  
        {  
            for (k = 0; k<3; k++)  
            fread(&ImgData[j][k], 1, 1, fp1);  
        }  
        for (j = 0; j<(fi->biWidth + 3) / 4 * 4; j++)  
        {  
            ImgData2[j] = int((float)ImgData[j][0] * 0.114 +  
                (float)ImgData[j][1] * 0.587 +  
                (float)ImgData[j][2] * 0.299);  
        }  
        //將灰度圖資訊寫入  
        fwrite(ImgData2, j, 1, fp2);  
    }  

 

3.2.4 功能函式彩色轉二值影象設計

根據2.3.4,其中將彩色圖轉為二值圖程式碼如下:

    /*將彩色圖轉為二值圖*/  
    a=(unsigned char *)malloc((fi->biWidth*3+3)/4*4);//給變數a申請源圖每行畫素所佔大小的空間,考慮四位元組對齊問題  
    c=(unsigned char *)malloc((fi->biWidth+3)/4*4);//給變數c申請目標圖每行畫素所佔大小的空間,同樣四位元組對齊  
    for(i=0;i<fi->biHeight;i++)//遍歷影象每行的迴圈  
    {  
        for(j=0;j<((fi->biWidth*3+3)/4*4);j++)//遍歷每行中每個位元組的迴圈  
        {  
            fread(a+j,1,1,fp1);//將源圖每行的每一個位元組讀入變數a所指向的記憶體空間  
        }  
        for(j=0;j<fi->biWidth;j++)//迴圈畫素寬度次,就不會計算讀入四位元組填充位  
        {  
            b=(int)(0.114*(float)a[k]+0.587*(float)a[k+1]+0.299*(float)a[k+2]);//a中每三個位元組分別代表BGR分量,乘上不同權值轉化為灰度值  
            if(90<=(int)b)   
                b=1;//將灰度值轉化為二值,這裡選取的閾值為190  
            else   
                b=0;  
            c[j]=b;//儲存每行的二值  
            k+=3;  
        }  
        fwrite(c,(fi->biWidth+3)/4*4,1,fp2);//將二值畫素四位元組填充寫入檔案,填充位沒有初始化,為隨機值  
        k=0;  
    }  

 

3.2.5 功能整合

根據2.3.5,功能整合可採取如下格式:

int main(void)  
{  
    scanf("%s",inPath);  
    scanf("%s",outPath);  
    FILE *fp1 = fopen(inPath, "rb+");  
    FILE *fp2 = fopen(outPath, "wb");  
    scanf("%d",&n);  
    switch(n)  {  
        case 1:  {  
                  if(colorToGray(fp1,fp2) == 1)  
                  {  
                        printf("success\n");  
                   }  
                   break;  
            };  
         case 2:  
                {  
                    if(colorToTwoValue(fp1,fp2) == 1)  
                    {  
                          printf("success\n");  
                    }  
                    break;  
             }  
          default: break;  
        }  
}  

 

4 結論

4.1 程式執行結果

圖4.1 彩色轉灰度功能實現

 

圖4.2 彩色轉二值圖功能實現

 

4.2 問題與解決

4.2.1 使用方法

  本次課程設計中,彩色圖轉變為灰度圖使用加權平均值演算法,彩色影象轉變為二值圖使用固定閾值法,作為改進可使用迭代法已達到最佳效果,使用固定閾值有的圖無法達到想要的效果,如都低於閾值或都高於閾值。

 

4.2.2 問題

  1)C語言中“\\”表示“\”,第一個表示轉義字元,如果絕對路徑裡面用“\”,則需要用“\\”表達,也可用“/”表達,如C:/Users/zander/Desktop/1.bmp。

  2)知網和維基百科上面的內容可以寫參考文獻,百度或其他部落格上的內容不太好寫參考文獻。

  3)程式碼高亮處理後,再複製HTML格式到word文件,方便閱讀,但是也存在一些問題,比如再次複製到編譯器中前面會加序號,直接在word中刪除一行,則會導致兩行顏色一樣。

  4)同一個word檔案用Word開啟和用WPS開啟排版略有變化,通過輸出PDF格式可以解決,如輸出併發送PDF格式列印,但是由PDF檔案打印出來頁邊距比word格式直接打印出來頁邊距略大。

 

4.3 感想和總結

  通過本次課程設計,對《多媒體技術與應用》這門課有了進一步的理解,在課程設計的過程中,通過查閱資料深刻地感受到多媒體技術在工作生活中應用之廣。隨著移動網際網路時代的發展,物聯網大資料時代的到來,多媒體技術無論是教育還娛樂方面都有應用,將來還會進一步深入到生活的方方面面,可見其重要性。本次課程設計的選題是C語言實現BMP格式檔案彩色轉灰度與二值影象,通過提出問題、分析問題、解決問題、驗證與實驗、總結這一流程,對圖形、影象處理技術有了深刻的認識,中間發現了一些問題,解決了一些問題,還有很多功能可以完善,對程式的設計實現流程有了進一步的理解,稍微複雜的功能採用設計然後實現可以起到事半功倍的效果,遠比直接敲程式碼效率高。資料的蒐集要有根據,有權威性,有代表性,不僅可以讓查閱者方便查詢驗證,也是對正確性的一層保障。

 

參考文獻

[1]田振蒙.多媒體技術的應用現狀及其發展前景研究[J].科技傳播,2018,10(22):162-163.

[2]李威,張銀玲,趙婷婷.BMP數字影象的認識與應用[J].科技資訊,2016,14(36):30+91.

[3]維基百科編者. 灰度影象[G/OL]. 維基百科, 2018(20180225)[2018-02-25]. https://zh.wikipedia.org/w/index.php?title=%E7%81%B0%E5%BA%A6%E5%9B%BE%E5%83%8F&oldid=48445073.

[4]維基百科編者. 二值影象[G/OL]. 維基百科, 2017(20171214)[2017-12-14]. https://zh.wikipedia.org/w/index.php?title=%E4%BA%8C%E5%80%BC%E5%9B%BE%E5%83%8F&oldid=47367413.

[5]維基百科編者. BMP[G/OL]. 維基百科, 2018(20180531)[2018-05-31].

https://zh.wikipedia.org/w/index.php?title=BMP&oldid=49784725

 

 

相關