s1093304 作業6

一、作業說明

主題: Run-Length Based Image Compression 練習

附件中為三張利用將晶片高度以色彩視覺化後的圖片。請設計一個基於 Run-Length 的壓縮方法,對圖檔作無失真壓縮後儲存成新檔案。部落格上應敘述你的壓縮方法,提供壓縮檔之格式,並計算三張圖的平均壓縮率(compression ratio)。

二、開發環境

  • Windows 10
  • Visual Studio Code 1.76.1
  • Python 3.9.15
  • OpenCV 4.6.0

三、實作過程

  • 首先訂定讀取原圖檔案路徑、壓縮檔檔案路徑、解壓縮圖片路徑
    圖一、原圖檔案路徑、壓縮檔檔案路徑(存成dat檔)、解壓縮圖片路徑

  • 對3個bmp檔進行壓縮後,分別計算三張圖片的壓縮率和平均壓縮率 (壓縮率 = 原圖大小 / 壓縮檔大小)
    圖二、壓縮圖片將其存成dat檔,並計算壓縮率

  • 其中,compress_image()是進行圖片壓縮的函式,此函式主要執行以下三步驟
    1. 讀取圖片並取得其圖片長寬。
    2. 使用cv2.split()將圖像拆成三通道後,分別執行run_length_encode()方法對圖片進行壓縮。
    3. 並將壓縮的值以逗點隔開再加上圖片的長寬資訊後,存成dat檔。
      圖三、將要讀取的原圖

  • 其中run_length_encode()的執行流程如下
    1. 透過groupby將 data 列表中連續重複的元素分組,相同的元素被放在一起形成一個 group
    2. 遍歷每個group,並將 group 的長度(即連續出現的次數)和 group 的元素值(val)組成一個子列表
    3. 每個子列表的意思為[連續的元素值個數, 元素],ex:[2485284, 0]代表有連續2485284個0
    4. 所有子列表蒐集成encoded_data後(可當作二維陣列),再將該二維陣列攤平成一維後回傳
      圖四、run_length_encode()
      圖五、encoded_data的結構,例如其中[2485284, 0]代表有連續2485284個0

  • 三張圖片壓縮後的壓縮率如下,分別為2.4681.4332.690,三張圖的平均壓縮率為2.197
    圖六、三張圖的壓縮率與平均壓縮率
    圖七、上排為原圖檔案大小(大小都是13.9MB),下排為對應的壓縮檔大小(分別為5.669.755.19MB)
    圖八、壓縮檔內的資料,第一行為圖片的高與寬,第二行開始存放壓縮資料,內容為[連續次數, value]循環下去
  • 接著進行解壓縮,使用decompress_image()函式,主要執行以下4步驟
    1. 讀取dat檔並取得圖像的高和寬
    2. 解壓縮,由於每一對的第一個元素表示數值的重複次數,第二個元素表示數值本身,根據重複次數 count 將數值 value 重複添加到 channel 列表中
    3. 使用 reshape 方法將數組的形狀調整為 (image_height, image_width),最後生成包含所有通道數據的列表,並將其作為參數傳遞給 cv2.merge 把解壓縮後的通道數據合併成完整的圖像
    4. 最後使用cv2.imwrite()將解壓縮後的圖像寫入到指定的輸出路徑。
      圖九、decompress_image()解壓縮

  • 最後使用np.array_equal()來比較解壓縮的圖片和原圖是否相等,實際結果為相等
    圖十、比對解壓縮後的圖片和原圖是否相等
    圖十一、解壓縮的圖片和原圖相同
    圖十二、解壓縮後的圖

    影片Demo

留言

這個網誌中的熱門文章

rzwang Homework #1

s1093350 Homework #2

s1091537 Homework #1