天天看點

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

程式源碼: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()函數的正确性,結果如下圖:

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

三、          手寫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()函數的正确性,結果如下圖:

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

Ø  【問題】

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

但是,我發現在讀入的過程中,每8個bit資料的開頭一個bit的讀入結果都是空(0*0的矩陣)。當我忽略空的結果後,總的資料量比正确結果要少——也就是說1bit為機關讀入會丢失部分資料,而8bit為機關讀入就沒問題。

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

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

繼續閱讀