【數字圖像處理】pbm/pgm/ppm圖片的讀寫(Matlab)

版權聲明:本文爲博主原創文章,歡迎轉載。轉載請註明出處http://blog.csdn.net/jsgaobiao https://blog.csdn.net/jsgaobiao/article/details/50835878

程序源碼:http://download.csdn.net/detail/jsgaobiao/9456641

Ø  【作業要求】

1. Get your matlab platform ready. Payspecial attention to the image processing toolbox.

2.Use matlab functions to convert the attached image from .jpg to binary .ppm format. Save it as greens.ppm.

3. Write your own imread(‘*.ppm’) functioncode to read the newly generated .ppm file.

4. Submit your code, result, and report.

選做:嘗試設計你的 .pgm和.pbm讀寫程序。

 

Ø  【文件說明】

jpg2ppm.m:

Use matlab functions to convert theattached image from .jpg to binary .ppm format. Save it as greens.ppm

 

imread_pxm.m:

Myown imread() function code to read .ppm/.pgm/.pbm file which can beencoding ineither ASCII or Binary.

 

imwrite_pxm.m:

Myown imwrite() function code to write .ppm/.pgm/.pbm file which canbe encoding ineither ASCII or Binary.

 

test_imread_pxm.m:

Use imread_pxm() to readgreens.ppm/.pgm/.pbm && greens1.ppm/.pgm/.pbm, then show them to checkthe correctness of function imread_pxm().

 

test_imwrite_pxm.m:

Use imwrite_pxm to write .ppm/.pgm/.pbmencoding in ASCII/Binary mode, then show them to check the correctness offunction imwrite_pxm().

 

greens.ppm/.pbm/.pgm(Encoding in Binary) :

Images for imread_pxm() function to load.

 

greens1.ppm/.pbm/.pgm(Encoding in ASCII) :

Images for imread_pxm() function to load.

 

Ø  【作業思路】

一、          將jpg文件轉化成二進制編碼的.ppm文件

通過MATLAB自帶的函數imread()載入jpg的圖像數據部分,再使用imwrite()將上一步的結果寫成.ppm文件,’encoding’選項可以選擇’rawbits’和’ASCII’分別是二進制和ASCII編碼。

二、          手寫imread()實現讀取.ppm/.pgm/.pbm圖像的功能

我的imread_pxm()函數可以讀取二進制或ASCII編碼的.ppm/.pgm/.pbm文件。主要思路和注意點如下:

1、 圖像的頭部統一處理,都是由ASCII編碼的圖像類型(P1..P6)、寬、高和像素值範圍。其中.pbm沒有最後一個像素值範圍(因爲.pbm的像素值只可能是0/1);

2、 根據圖像類型(P1..P6)讀取圖像的數據部分,全部按uint8的類型讀入。需要注意P3和P6每個像素都有RGB信息,所以需要存入3維矩陣,其他類型存入二維矩陣;

3、 每種類型的圖像讀入後的矩陣具有不同的數據類型,fread讀入的結果默認是doublele類型,所以保存時需要強制轉換:.pgm/.ppm的數據轉換爲uint8,.pbm的數據轉換爲logical;

4、 ASCII編碼的數據要處理數據間的空格和換行符;

5、 .pbm的圖像數據在保存時需要0/1取反,否則顯示出來的結果會反色;

6、 .pbm的二進制編碼數據每行會按照8bit對齊,每行最後一個8bit數據的末尾會用0補齊,需要注意處理一下。

 

使用test_imread_pxm.m腳本可以測試P1..P6的圖像讀入並顯示,以檢測imread_pxm()函數的正確性,結果如下圖:

 

三、          手寫imwrite()實現將像素值矩陣寫成.ppm/.pgm/.pbm圖像的功能

我的imwrite_pxm(im, ptype, filename)函數可以將圖像數據矩陣im寫入二進制或ASCII編碼的.ppm/.pgm/.pbm文件,ptype指定了圖像和編碼的類型(P1..P6),filename指定了保存文件名,例如imwrite_pxm(im,6, ‘output.ppm’).

實現的主要思路和注意點如下:

1、 統一處理圖像的頭部,寫入ASCII編碼的圖像類型(P1..P6)、寬、高和像素值範圍。其中.pbm沒有最後一個像素值範圍(因爲.pbm的像素值只可能是0/1);

2、 根據圖像類型(P1..P6)寫入圖像的數據部分,以’wb’格式打開輸出文件後,直接使用fwrite()函數寫入即可。需要注意P3和P6每個像素都有RGB信息,所以需要寫入3維矩陣,其他類型寫入二維矩陣;

3、 .pbm的圖像數據在保存時需要0/1取反,否則顯示出來的結果會反色;

4、 .pbm的圖像數據是由0/1組成的,但是在寫入時,需要將它們合成8bit的數後,再寫入文件。和上文中提到的一樣,要特殊處理每行最後8bit的對齊。

 

使用test_imwrite_pxm.m腳本可以測試P1..P6的圖像寫出並顯示,以檢測imwrite_pxm()函數的正確性,結果如下圖:


 

Ø  【問題】

在手寫imread()函數中處理.pbm二進制編碼的圖像時,我首先嚐試了使用fread(fid, 1, ‘ubit1’),每次讀入1bit,這樣可以直接獲取0/1的數據而不需要每次讀一個uint8,再拆成8個0/1。

但是,我發現在讀入的過程中,每8個bit數據的開頭一個bit的讀入結果都是空(0*0的矩陣)。當我忽略空的結果後,總的數據量比正確結果要少——也就是說1bit爲單位讀入會丟失部分數據,而8bit爲單位讀入就沒問題。

我查閱了一些資料並沒有找到原因。記錄在此,希望日後可以解決。

 

 

上期謎語:日行七千裏(二字數字圖像術語)—— 量化


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