此腳本的作用是圖檔壓縮(清晰度尚可的情況下,可達到8倍以上的壓縮比),是SVD的一個應用實踐,涉及PIL、numpy庫。
(python中處理圖檔的庫比較多,比如PIL、OpenCV、matplotlib等。)
主邏輯:讀取一個PNG圖檔,
RGB三原色特征使用svd進行主特征提取
根據不同清晰度使用全部(部分奇異值)進行圖像重組,生成相應的jpg檔案
by jntcf, 201712
# -*- coding: utf-8 -*-
from PIL import Image
import numpy as np
'''
此腳本的作用是圖檔壓縮,是SVD的一個應用實踐,涉及PIL、numpy庫
(python中處理圖檔的庫比較多,比如PIL、OpenCV、matplotlib等。)
主邏輯:讀取一個PNG圖檔,
RGB三原色特征使用svd進行主特征提取
然後輸出不同清晰度的jpg檔案
by jntcf, 201712
'''
def rebuild_img(u, sigma, v, percent): #p表示奇異值的百分比
m = len(u)
n = len(v)
a = np.zeros((m, n))
#根據指定的清晰度提取奇異值
#(清晰度越高,壓縮比越低,提取的奇異值的個數也就越多,圖檔也就越不會失真)
count = (int)(sum(sigma))
curSum = 0
k = 0
while curSum <= count * percent:
uk = u[:, k].reshape(m, 1)
vk = v[k].reshape(1, n)
a += sigma[k] * np.dot(uk, vk)
curSum += sigma[k]
k += 1
a[a < 0] = 0
a[a > 255] = 255
#按照最近距離取整數,并設定參數類型為uint8
return np.rint(a).astype("uint8")
def svdimage(filename, percent, outFolder):
img = Image.open(filename, 'r')
a = np.array(img)
#提取RGB的主特征(奇異值SVD),處理後根據指定清晰度(百分比)傳回新的RGB資料
u, sigma, v = np.linalg.svd(a[:, :, 0])
R = rebuild_img(u, sigma, v, percent)
u, sigma, v = np.linalg.svd(a[:, :, 1])
G = rebuild_img(u, sigma, v, percent)
u, sigma, v = np.linalg.svd(a[:, :, 2])
B = rebuild_img(u, sigma, v, percent)
#新的RGB疊加,儲存為JPG圖檔
I = np.stack((R, G, B), 2)
Image.fromarray(I).save(outFolder+"svd_" + str(p * 100) + ".jpg")
if __name__ == '__main__':
filename='e:\\1.png'#原始圖檔
outFolder='e:\\'#處理後的jpg圖檔輸出目錄
#按指定壓縮比進行圖檔處理(0.1 ~ 0.9)
#壓縮比越大(最大到0.1)處理後的圖檔越模糊
for p in np.arange(0.1, 1, 0.1):
svdimage(filename, p, outFolder)