210.BMP彩色影像轉化為灰度及二值影像
- 2019 年 10 月 3 日
- 筆記
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("successn"); } break; }; case 2: { if(colorToTwoValue(fp1,fp2) == 1) { printf("successn"); } 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