图像是由一个个像素点组成,像素点就是颜色点,而颜色最简单的方式就是用RGB或RGBA表示
图像将像素信息按照 一定格式,一定顺序(即编码) 存在硬盘上的 二进制文件 中
1. 文件名和路径
2. 文件格式
3. 压缩参数(jpeg图像的压缩质量等)
将而二进制文件还原为 像素排布
目的:压缩 (有损压缩,无损压缩)减小数据大小
有损压缩: 解压缩后的数据与压缩前的数据不一致.在压缩的过程中要丢失一些人眼和人耳所不敏感的图像或音频信息,而且丢失的信息不可恢复。
无损压缩: 压缩前和解压缩后的数据完全一致。优化数据的排列等。
补充:【端到端指的是直接输入原始数据,让模型自己去学习特征,最后输出结果
非端到端呢,简单来说,就是我们的输入数据首先经过人工处理,在喂给模型去训练】
常见编码:PNG 无损压缩,BMG 无损压缩,JPEG 有损压缩
PNG图像格式文件(或者称为数据流)由一个8字节的PNG文件署名(PNG file signature)域和按照特定结构组织的3个以上的数据块(chunk)组成。
PNG定义了两种类型的数据块,一种是称为关键数据块(critical chunk),这是必需的数据块,另一种叫做辅助数据块(ancillary chunks),这是可选的数据块。
Critical Chunk(关键数据块),有四种类型:
IHDR,header chunk,包含有图像基本信息,作为第一个出现的数据块并且只出现一次。
PLTE,palette chunk,调色板数据块,必须存放在图像数据块之前。
IDAT,image data chunk,存储实际的图像数据。PNG数据包允许包含多个连续的图像数据块。
IEND,image trailer chunk,图像结束数据,表示PNG数据流结束。

其中ihdr的结构为:4字节为chunk length,4字节为chunk type
剩下13字节的ihdr为:
宽(无符号整,4字节)
高(无符号整,4字节)
bit deep位深(无符号char,1字节)
颜色类型(无符号char,1字节)
压缩方法/滤波方法/隔行扫描法(都是unsigned char 1字节)
https://www.jb51.net/article/199586.htm
# 首先读取二进制文件
f = open("E:/DeepLearning/计算机视觉/cv101-master/dataset/lena.png", 'rb')
print(f)
# <_io.BufferedReader name='E:/DeepLearning/计算机视觉/cv101-master/dataset/lena.png'># head
file_sign = f.read(4)
print("head:", file_sign)
#换行符文件结束符
sign1 = f.read(4)
print("换行符和文件结束符:", sign1)
#head: b'\x89PNG'
#换行符和文件结束符: b'\r\n\x1a\n'length = struct.unpack('I', f.read(4))
print(length)
type = f.read(4)
print(type)
#(218103808,)
#b'IHDR'width = struct.unpack('I', f.read(4))
print("宽度:", width)
height = struct.unpack('I', f.read(4))
print("高度:", height)
# 感觉有点问题
#宽度: (131072,)
#高度: (131072,)
bit = struct.unpack('B',f.read(1))
print("位深:", bit)
color = struct.unpack('B',f.read(1))
print("颜色:", color)
#位深: (8,)
#颜色: (2,)a = struct.unpack('B',f.read(1))
b = struct.unpack('B',f.read(1))
c = struct.unpack('B',f.read(1))
print("a,b,c: ",a,b,c)
# a,b,c: (0,) (0,) (0,)-- 文件头:文件类型、文件大小、位图数据的起始位置
-- 位图信息头:图像尺寸、位深图、压缩方式
-- 调色板: 存储位深小于8的像素点信息
-- 位图数据:存储图像中每个像素点的颜色信息
位深的概念:
BMP格式中,每个像素点的颜色信息可以使用不同的位深度表示,如1位(单色)、4位(16色)、8位(256色)、16位、24位(真彩色)和32位等。其中,1位表示每个像素点只有黑和白两种颜色;4位表示每个像素点可以有16种颜色;8位(0~255)表示每个像素点可以有256种颜色;16位、24位和32位则表示每个像素点的颜色可以用不同的颜色通道(如红、绿、蓝)进行表示
基本规则如下:
- 文件头(14b):
- 表示符:BM(2b)
- 文件大小 (4b)
- 保留量 (4b)
- 偏移量 (4b)
- 位图头 (40b)
- 字节头大小 4b
- 宽 4b
- 高 4b
- 颜色通道数 2b
- 位深 2b
- 位图数据
- 从左到右,从上到下
- 所占空间为宽乘以高乘以位数除以8
- 补齐4字节
# 以bmp为例
# 首先读取二进制文件
f = open("E:/DeepLearning/计算机视觉/cv101-master/dataset/lena.bmp", 'rb')
print(f)
#<_io.BufferedReader name='E:/DeepLearning/计算机视觉/cv101-master/dataset/lena.bmp'># 先读取头文件
# 2字节标识符
file_sign = f.read(2)
print("标识符:", file_sign)
#标识符: b'BM'# 4字节文件大小
file_size_byte = f.read(4)
# 需要解码
import struct
file_size = struct.unpack("i", file_size_byte)
print("文件大小:", file_size)
#文件大小: (786486,)# 4字节保留
f.read(4)
# 4字节数据偏移量
offset = struct.unpack("i", f.read(4))[0]
print("偏移量:", offset)
#偏移量: 54# 位图头读取
# 字节头解码
bm_header_size = struct.unpack('i', f.read(4))
print("字节头大小:", bm_header_size)
width = struct.unpack('i', f.read(4))
print("宽度:", width)
height = struct.unpack('i', f.read(4))
print("高度:", height)
channels = struct.unpack('
-- joint photographic experts group
-- 有损压缩格式
-- DCT和量化实现
-- 具体步骤:
1. 预处理:rgb->YCbCr
2. DCT变换:
- 图像划分成8*8的patch
- 每个patch做DCT变换
3. 量化:
- 量化频域信号
- 舍弃高频信号
4. 编码:
- 熵编码技术对DCT信号编码
- 保留主分量,舍去噪声分量
- 常见的两种实现方式:
* baseline jpeg:常规方式,编码顺序为从左至右从上至下
* progressive jpeg:内容从模糊到清晰,将图像分为多个扫描,每个扫描中先编码大致轮廓,然后在后续扫描中添加细节
from PIL import Image
# 读取图像
img = Image.open('E:/DeepLearning/计算机视觉/cv101-master/dataset/lena.bmp')
plt.imshow(img)
plt.show()# 查看图像大小
print('image shape:', img.size)
# 查看图像格式
print('format:', img.format)
# 查看图像通道数
print('mode:', img.mode)# 获取像素值
# 通常是将其转换为其他格式来使用像素值,例如
import numpy as np
img_array = np.asarray(img)
print(img_array[:3, :3, 0])输出:

image shape: (512, 512)
format: BMP
mode: RGB
[[226 226 223]
[226 226 223]
[226 226 223]]
# PIL提供了保存图像的方法,即
img.save('../../dataset/pil_lena.bmp')import cv2
img = cv2.imread('E:/dataset/lena.bmp')#路径中不能有中文!!!plt.imshow(img)
plt.show()#读取默认bgr
img = cv2.imread('E:/notebook/lena.bmp')
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)plt.imshow(img)
plt.show()
# 在读取图像时,imread还有个隐藏参数,可以直接将彩色图像转化为灰度图像
img = cv2.imread('E:/notebook/lena.bmp', 0)
img = cv2.cvtColor(img, cv2.COLOR_GRAY2RGB)plt.imshow(img)
plt.show()
opencv提供函数保存图像,其格式为:
cv2.imwrite(filename, image, [params])
其中,参数分别是: 文件名, 图像数据,可选参数:文件格式
img = cv2.imread('E:/notebook/lena.bmp')
cv2.imwrite('E:/notebook/lena.png', img)
cv2.imwrite('E:/notebook/lena_90.jpg', img, [cv2.IMWRITE_JPEG_QUALITY, 90])#压缩质量90kb
cv2.imwrite('E:/notebook/lena_10.jpg', img, [cv2.IMWRITE_JPEG_QUALITY, 10])#压缩质量10kb

cv2直接读取到图像的内容,pil读取图像的区块
cv2支持的图像格式更多,保存图像时能够控制图像质量,需要空间转换
pil适合简单的图像查看应用场景,opencv适合处理计算机视觉任务。
#方法一:使用PIL库
from PIL import Image
img = Image.open('test.jpg')
img.save('testpil.png')
#方法二:使用opencv库
from cv2 import imread, imwrite
image = imread("test.jpg", 1)
imwrite("testcv.png", image)def png2jpg(filename, quality_value, save_folder):# 不依赖opencv或者pil库,从二进制文件直接解析png文件,并保存成jpeg格式。# 其中,jpeg格式的压缩参数由输入指定。# # 输入: # filename: str, png图像路径# quality_value: 压缩质量参数# save_folder: 保存的目标路径# # 图像保存文件名:# # 返回值:# 返回0