s1093350 Homework #5
1122 Digital Image
Processing Assignment #5報告
學號:s1093350 姓名:楊宜芳
主題:Run-Length
Based Image Compression 影像壓縮練習
問題與專案解決目標:
設計一個基於Run-Length的壓縮方法,對圖檔作無失真壓縮後儲存成新檔案,並計算三張圖的平均壓縮率(compression ratio)。
開發環境:Microsoft
Windows 11, Visual Studio Code 1.87.1, OpenCV 4.90, Python 3.8.13
程式架構與功能說明:
1.
用到的套件:PIL中的Image、os、struct,在程式中使用到的功能如下。
- Image:讀入圖像,使用 getdata() 和 size() 取得圖像的像素資料、尺寸
- os:使用 os.path.getsize() 取得檔案大小。
- struct:使用struct.pack() 將資料依指定格式轉為Byte型式,以使用二進制儲存,使用struct.unpack() 將資料轉回。
2.
壓縮圖像:使用Run-length方法對圖像進行壓縮。
- run_length() 副程式:對圖像進行Run-length壓縮,執行步驟如下:
- 取得圖像中所有像素的資料(RGB值)、圖像的尺寸。
- 將每行的像素資料儲存在二維list中。
- 對每一行遍歷該行中的所有像素,判斷是否有連續重複像素。
- 儲存該行中所有的(像素值,重複個數)資料。
- 回傳所有行的(像素值,重複個數)資料。
- save_compressed_data()
副程式:儲存壓縮資料,執行步驟如下。
- 以二進制寫入模式開啟文字檔。
- 使用struct.pack(),依據指定格式將資料轉換為二進制格式。其中,B 代表unsigned char,範圍為0~255,使用三個 B 來代表像素的RGB值(共3 Bytes)。I 代表unsigned
int,使用 I 來代表像素重複次數(4 Bytes),如下圖所示。
- 將壓縮資料以二進制寫入文字檔。
- 主程式:執行步驟如下。
- 設定所有圖像路徑,並使用迴圈對每張圖像做Run-length壓縮。
- 開啟檔案並呼叫run_length() 副程式進行壓縮。
- 設定壓縮檔的儲存路徑並呼叫save_compressed_data() 副程式進行儲存。
- 分別取得壓縮前後的檔案大小。
- 計算圖像的壓縮率(原圖大小/壓縮後大小),並印出該圖像的壓縮率。
- 所有圖像皆壓縮完後,計算並印出三張圖像的平均壓縮率。
3.
解壓縮圖像:
- load_compressed_data()
副程式:讀取壓縮檔並解壓縮,取得所有像素資料。執行步驟如下:
- 以二進制讀入模式打開文字檔。
- 讀入資料。其中,每次先讀取3個Bytes,對應RGB數值,接著再讀取4個Bytes,對應像素重複個數。
- 使用struct.unpack(),解析二進制資料。其中,使用'BBB'將三個Bytes解析成像素資料的RGB數值,使用'I'將四個Bytes解析成像素的重複個數。如下圖所示。
- 依據像素重複個數,將像素資料新增到list中。
- 重複2.~4.步驟直到讀完檔案。最後回傳存有所有像素資料的list。
- convert_to_image() 副程式:將像素資料轉換為圖像。執行步驟如下:
- 使用RGB模式創建指定大小的圖像。
- 將像素依序放入圖像中並回傳圖像。
- 主程式:執行步驟如下。
- 設定壓縮檔路徑,並使用迴圈對每個檔案做解壓縮。
- 指定解壓縮後圖像的寬度與高度(與原圖相同)。
- 呼叫load_compressed_data() 副程式,讀取壓縮檔並進行解壓縮,取得所有像素資料。
- 呼叫convert_to_image() 副程式,依據給定的圖像尺寸,使用得到的像素資料產生圖像。
- 儲存產生的圖像,並印出解壓縮完成訊息。
- 壓縮方法:使用Run-Length方式進行壓縮,並使用二進制格式儲存。
- 壓縮檔格式:文字檔(txt檔)
- 個別壓縮率及平均壓縮率(原圖大小/壓縮後大小):
- 原圖/壓縮後/解壓縮後的檔案大小:
原圖:
壓縮後:
影片:
留言
張貼留言