s1091444 作業 6

同步發布於 titaliu1224.github.io

功課要求

附件中為三張利用將晶片高度以色彩視覺化後的圖片。 

請設計一個基於Run-Length 的壓縮法方,對圖檔作無失真壓縮後儲存成新檔案。 

 

部落格上應敘述你的壓縮方法,提供壓縮檔之格式,並計算三張圖的平均壓縮率

(compression ratio)。



成果




開發環境

  • Windows 10 
  • Visual Studio Code 
  • Python 3.9.16 
  • OpenCV 4.5.4

實作

使用的 libraries 如下:

import cv2, os
import matplotlib.pyplot as plt
import numpy as np


1/ 利用迴圈讀入三張圖片

建立一個儲存三張圖片路徑的 list ,使用迴圈讀入圖片並送至 compress(original_img, compress_file) 進行壓縮,取得壓縮率並儲存在 compress_ratio[i] 中。


2/ 壓縮圖片

2.1/ 計算圖片大小

使用 os.path.getsize(filename) 取得圖片大小,並使用 with open(compress_file, "w") as file 寫入壓縮檔案中,做為解壓縮時建立 array 的參考。

2.2/ 將二維的圖片轉為一維

三個 channel 的值不會一樣,所以三個通道必須分開儲存。
一維的圖片比較好操控,而且能夠增加壓縮的效率,所以使用 flatten() 將二維的矩陣轉換至一維。

2.3/ Run-Length Encoding

遍歷矩陣中所有的 pixel ,如果當前 pixel 和上一個 pixel 相等,數量就 + 1,不相等就將當前 pixel 的值和數量寫入 .dat 檔中。
並且利用 \n 來分隔每個 channel 的資料。

2.4/ 計算壓縮率

首先,利用 os.path.getsize(filename) 取得檔案大小。
壓縮率的計算為 原檔案大小 / 壓縮檔案大小,相除之後使用 formatted string 顯示在表格中。


3/ 解壓縮圖片

在 main() 中呼叫 decompress(compress_file) 來將剛才產生的 dat 檔轉換回圖片並使用 plt 顯示。

3.1/ 創建畫布

使用 img_size = file.readline().rstrip('\n').split(", ") 取得圖片的大小之後,建立一個擁有三個元素的二維 list ,每一個元素是儲存 B, G, R 單個通道的資料,每一個元素的大小為 img_size[0] * img_size[1] 。 
同時,使用 file.read().split("\n") 讀取剩下的資料,每一個通道的值是使用 `\n` 做分割,其中每一個 pixel 的值用 , 分割。

3.2/ 將 pixel 填上 array

image_bgr 中,依序填入 B, G, R 通道的資料。


3.3/ Merge 三個通道成一張圖片

將填好值的一維 array 使用 reshape() 轉換成二維矩陣,並使用 cv2.merge() 合併三個通道,使其變成 BGR 的彩色圖片。 <br>
由於要在 plt 做顯示,所以使用 cv2.cvtColor() 將 BGR 轉換成 RGB 。


4/ 計算平均壓縮率


將三張圖片的壓縮率加總後平均並輸出,最後使用 plt.show() 顯示圖片。


總結

Run-length encoding 可以用來壓縮相同顏色連續出現的圖片,不過如果圖片沒有大量相同的顏色相鄰,壓縮效果可能會不太好。

參考資料



留言

這個網誌中的熱門文章

rzwang Homework #1

s1101438 Homework #1

s1093309 作業6