一.位图原理
以下面这张格式为bmp的照片为例:
查看图片属性:
信息显示图片大小为768k,位图大小计算:768*1024=786,486字节,这是不包含文件头信息的大小。
用UltraEdit打开lena.bmp,可以看到这个文件的全部数据如下图所示:
位图文件头:
位图信息头:
二.图像处理
原图(png格式):
属性:
16/32位位图对照:
实验选择的是工具是Adobe Photoshop 2021,简称PS
保存为32位位图:
查看属性:
图片大小:1MB10241024=1048632B
UltraEdit查看图片头文件信息如下
16位位图:
属性:
大小:515*1024=524344B
不包含文件文件头信息大小
UltraEdit查看图片头文件信息如下;
16/32位位图的区别:
32位位图:
16位位图:
肉眼看没什么区别,但是16位位图占的空间更小
256/16/单色位图对照
256色位图
大小:2571024=263222B
UltraEdit查看图片头文件信息如下:
16色位图:
大小:1281024=131190B
UltraEdit查看图片头文件信息如下:
单色位图:
大小:32*1024=32830B
UltraEdit查看图片头文件信息如下:
区别
256色:
16色:
单色:
颜色越小,占用空间越小
不同图片格式的压缩比
四张图片的格式不一样(png,jpg,bmp,gif):
大小分别为:700k,92k,772k,128k
三、图片处理编程
(一)奇异函数分解(SDV)
代码:
import numpy as np
import os
from PIL import Image
import matplotlib.pyplot as plt
import matplotlib as mpl
from pprint import pprint
def restore1(sigma, u, v, K): # 奇异值、左特征向量、右特征向量
m = len(u)
n = len(v[0])
a = np.zeros((m, n))
for k in range(K):
uk = u[:, k].reshape(m, 1)
vk = v[k].reshape(1, n)
a += sigma[k] * np.dot(uk, vk)
a[a < 0] = 0
a[a > 255] = 255
# a = a.clip(0, 255)
return np.rint(a).astype('uint8')
def restore2(sigma, u, v, K): # 奇异值、左特征向量、右特征向量
m = len(u)
n = len(v[0])
a = np.zeros((m, n))
for k in range(K+1):
for i in range(m):
a[i] += sigma[k] * u[i][k] * v[k]
a[a < 0] = 0
a[a > 255] = 255
return np.rint(a).astype('uint8')
if __name__ == "__main__":
A = Image.open("C:/Users/86152/Pictures/Feedback/lena.jpg", 'r')
print(A)
output_path = r'D:/photo1/SVD_Output'
if not os.path.exists(output_path):
os.mkdir(output_path)
a = np.array(A)
print(a.shape)
K = 50
u_r, sigma_r, v_r = np.linalg.svd(a[:, :, 0])
u_g, sigma_g, v_g = np.linalg.svd(a[:, :, 1])
u_b, sigma_b, v_b = np.linalg.svd(a[:, :, 2])
plt.figure(figsize=(11, 9), facecolor='w')
mpl.rcParams['font.sans-serif'] = ['simHei']
mpl.rcParams['axes.unicode_minus'] = False
for k in range(1, K+1):
print(k)
R = restore1(sigma_r, u_r, v_r, k)
G = restore1(sigma_g, u_g, v_g, k)
B = restore1(sigma_b, u_b, v_b, k)
I = np.stack((R, G, B), axis=2)
Image.fromarray(I).save('%s\\svd_%d.png' % (output_path, k))
if k <= 12