当前位置: 首页 > news >正文

图像的读取与保存

图像是由一个个像素点组成,像素点就是颜色点,而颜色最简单的方式就是用RGB或RGBA表示

图像保存

图像将像素信息按照 一定格式,一定顺序(即编码) 存在硬盘上的 二进制文件 中

保存图像需要以下必要信息:

1. 文件名和路径

2. 文件格式

3. 压缩参数(jpeg图像的压缩质量等)

图像读取

将而二进制文件还原为 像素排布

图像编码

目的:压缩 (有损压缩,无损压缩)减小数据大小

有损压缩: 解压缩后的数据与压缩前的数据不一致.在压缩的过程中要丢失一些人眼和人耳所不敏感的图像或音频信息,而且丢失的信息不可恢复。

无损压缩: 压缩前和解压缩后的数据完全一致。优化数据的排列等。

补充:【端到端指的是直接输入原始数据,让模型自己去学习特征,最后输出结果

非端到端呢,简单来说,就是我们的输入数据首先经过人工处理,在喂给模型去训练】

常见编码:PNG 无损压缩,BMG 无损压缩,JPEG 有损压缩

PNG

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,)

BMP

-- 文件头:文件类型、文件大小、位图数据的起始位置

-- 位图信息头:图像尺寸、位深图、压缩方式

-- 调色板: 存储位深小于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图片全过程

# 以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('<H', f.read(2))
print("通道:", channels)
color_bit = struct.unpack('<H', f.read(2))  # 2字节解码,低位字节在前
print("位深:", color_bit)
#字节头大小: (40,)
#宽度: (512,)
#高度: (512,)
#通道: (1,)
#位深: (24,)# 读取像素
f.seek(offset)
data = f.read()
# print(data[0], data[1], data[2])
print("总像素值数量为:", len(data))
print("像素点个数为:", len(data) // (color_bit[0] // 8))
print("长(512)*宽(512)= ", 512 * 512)
#总像素值数量为: 786432
#像素点个数为: 262144
#长(512)*宽(512)=  262144# 解码数据
# 一个像素占用的字节:24位深,一个像素三个数字表示rgb通道数值,用三个字节表示;8位深用1个字节表示(灰度图像);1位深用1个比特来存储(二值图像)
# 因此,计算方式为:int(位深/8)
pixel_bit = int(color_bit[0] / 8)
print("一个像素占用%d字节" % pixel_bit)
row_bit = pixel_bit * width[0]
print("一行占用%d字节" % row_bit)
#一个像素占用3字节
#一行占用1536字节# 建立一个空矩阵用于存储像素
import numpy as np
img = np.zeros((height[0], width[0], 3), dtype=np.uint8)
# 依次填充像素值
for i in range(height[0]):for j in range(width[0]):index = i * height[0] * 3 + j * 3img[i, j, 2] = data[index]img[i, j, 1] = data[index + 1]img[i, j, 0] = data[index + 2]
# 展示结果
import matplotlib.pyplot as plt
plt.imshow(img, origin='lower')
plt.show()

JPEG

-- joint photographic experts group

-- 有损压缩格式

-- DCT和量化实现

-- 具体步骤:

1. 预处理:rgb->YCbCr

2. DCT变换:

- 图像划分成8*8的patch

- 每个patch做DCT变换

3. 量化:

- 量化频域信号

- 舍弃高频信号

4. 编码:

- 熵编码技术对DCT信号编码

- 保留主分量,舍去噪声分量

- 常见的两种实现方式:

* baseline jpeg:常规方式,编码顺序为从左至右从上至下

* progressive jpeg:内容从模糊到清晰,将图像分为多个扫描,每个扫描中先编码大致轮廓,然后在后续扫描中添加细节

图像读取和保存的第三方库

PIL

安装:pip install pillow

读写使用

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')

opencv

安装:pip install python-opencv

读取使用:默认读取bgr需转化为rgb

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
质量10kb(第一张)和90kb对比

两者区别

cv2直接读取到图像的内容,pil读取图像的区块

cv2支持的图像格式更多,保存图像时能够控制图像质量,需要空间转换

pil适合简单的图像查看应用场景,opencv适合处理计算机视觉任务。

assignment

PNG2JPG

#方法一:使用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

相关文章:

图像的读取与保存

图像是由一个个像素点组成&#xff0c;像素点就是颜色点&#xff0c;而颜色最简单的方式就是用RGB或RGBA表示图像保存图像将像素信息按照 一定格式&#xff0c;一定顺序&#xff08;即编码&#xff09; 存在硬盘上的 二进制文件 中保存图像需要以下必要信息&#xff1a;1. 文件…...

【蓝桥杯集训·每日一题】AcWing 4074. 铁路与公路

文章目录一、题目1、原题链接2、题目描述二、解题报告1、思路分析2、时间复杂度3、代码详解三、知识风暴Floyd 算法Spfa 算法一、题目 1、原题链接 4074. 铁路与公路 2、题目描述 某国家有 n 个城市&#xff08;编号 1∼n&#xff09;和 m 条双向铁路。 每条铁路连接两个不同的…...

网络:TCP与UDP相关知识(详细)

目录&#xff1a;1、UDP 和 TCP 的特点与区别2、UDP 、TCP 首部格式3、TCP 的三次握手和四次挥手4、TCP 的三次握手&#xff08;为什么三次&#xff1f;&#xff09;5、TCP 的四次挥手&#xff08;为什么四次&#xff1f;&#xff09;6、TCP 长连接和短连接的区别7、TCP粘包、拆…...

不好!有敌情,遭到XSS攻击【网络安全篇】

XSS&#xff1a;当一个目标的站点&#xff0c;被我们用户去访问&#xff0c;在渲染HTMl的过程中&#xff0c;出现了没有预期到的脚本指令&#xff0c;然后就会执行攻击者用各种方法注入并执行的恶意脚本&#xff0c;这个时候就会产生XSS。 涉及方&#xff1a; 用户&#xff0…...

Mysql中Explain详解及索引的最佳实践

Mysql中Explain详解及索引的最佳实践1.Explan工具的介绍1.1 Explan 分析示例1.2 Explain中的列1.2.1 id1.2.2 select_type1.2.3 table1.2.4 partitions1.2.5 type1.2.6 possible_keys1.2.7 key1.2.8 key_len1.2.9 ref1.2.10 rows1.2.11 filtered1.2.12 Extra1.Explan工具的介绍…...

JavaScript 内的 this 指向

在 javascript 语言中, 有一个奇奇怪怪的 “关键字” 叫做 this为什么说它是 奇奇怪怪 呢, 是因为你写出 100 个 this, 可能有 100 个解释, 完全不挨边&#xff0c;但是, 在你的学习过程中, 搞清楚了 this 这个玩意, 那么会对你的开发生涯有很大帮助的&#xff0c;接下来咱们就…...

Java多种方法实现等待所有子线程完成再继续执行

简介 在现实世界中&#xff0c;我们常常需要等待其它任务完成&#xff0c;才能继续执行下一步。Java实现等待子线程完成再继续执行的方式很多。我们来一一查看一下。 Thread的join方法 该方法是Thread提供的方法&#xff0c;调用join()时&#xff0c;会阻塞主线程&#xff0…...

制造企业数字化工厂建设步骤的建议

随着工业4.0、中国制造2025的深度推进&#xff0c;越来越多的制造企业开始迈入智能制造的领域&#xff0c;那数字工厂要从何入手呢&#xff1f; 数字工厂规划的核心&#xff0c;也正是信息域和物理域这两个维度&#xff0c;那就从这两个维度来进行分析&#xff0c;看如何进行数…...

网上鲜花交易平台,可运行

文章目录项目介绍一、项目功能介绍1、用户模块主要功能包括&#xff1a;2、商家模块主要功能包括&#xff1a;3、管理员模块主要功能包括&#xff1a;二、部分页面展示1、用户模块部分功能页面展示2、商家模块部分功能页面展示3、管理员模块部分功能页面展示三、部分源码四、底…...

【实战】用 Custom Hook + TS泛型实现 useArray

文章目录一、题目二、答案&#xff08;非标准&#xff09;三、关键知识点1.Custom Hook关键点案例useMountuseDebounce2.TS 泛型关键点一、题目 完善自定义 Hook —— useArray &#xff0c;使其能够完成 tryUseArray 组件中测试的功能&#xff1a; 入参&#xff1a;数组返回…...

【LeetCode】剑指 Offer(18)

目录 题目&#xff1a;剑指 Offer 35. 复杂链表的复制 - 力扣&#xff08;Leetcode&#xff09; 题目的接口&#xff1a; 解题思路&#xff1a; 代码&#xff1a; 过啦&#xff01;&#xff01;&#xff01; 写在最后&#xff1a; 题目&#xff1a;剑指 Offer 35. 复杂链…...

Kubernetes节点运行时从Docker切换到Containerd

由于k8s将于1.24版本弃用dockershim&#xff0c;所以最近在升级前把本地的k8s切换到了Containerd运行时&#xff0c;目前我的k8s版本是1.22.5&#xff0c;一个master&#xff0c;二个Node的配置&#xff0c;以下做为一个操作记录日志整理&#xff0c;其它可以参考官网文档。 在…...

【编程基础之Python】12、Python中的语句

【编程基础之Python】12、Python中的语句Python中的语句赋值语句条件语句循环语句for循环while循环continue语句break语句continue与break的区别函数语句pass语句异常处理语句结论Python中的语句 Python是一种高级编程语言&#xff0c;具有简单易学的语法&#xff0c;适用于各…...

android h5餐饮管理系统myeclipse开发mysql数据库编程服务端java计算机程序设计

一、源码特点 android h5餐饮管理系统是一套完善的WEBandroid设计系统&#xff0c;对理解JSP java&#xff0c;安卓app编程开发语言有帮助&#xff08;系统采用web服务端APP端 综合模式进行设计开发&#xff09;&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要…...

容易混淆的嵌入式(Embedded)术语

因为做嵌入式开发工作虽然跳不出电子行业&#xff0c;但还是能接触到跨度较大的不同行当&#xff0c;身处不同的圈子。诸如医疗&#xff0c;银行&#xff0c;车载&#xff0c;工业&#xff1b;亦或者手机&#xff0c;PC&#xff0c;专用芯片&#xff1b;甚至可能横跨系统开发、…...

Nodejs 中 JSON 和 YAML 互相转换

JSON 转换成 YAML 1. 安装 js-yaml 库: npm install js-yaml2. 在程序中引入依赖库 const yaml require(js-yaml);3. 创建一个 js 对象, 代表 json 数据 const jsonData {name: John,age: 30,city: New York };4. 使用 yaml.dump() 把 js 对象转换成 YAML, 返回 YAML 字符…...

C++入门教程||C++ 修饰符类型||C++ 存储类

C 修饰符类型 C 允许在 char、int 和 double 数据类型前放置修饰符。修饰符用于改变基本类型的含义&#xff0c;所以它更能满足各种情境的需求。 下面列出了数据类型修饰符&#xff1a; signedunsignedlongshort 修饰符 signed、unsigned、long 和 short 可应用于整型&#…...

Android开发面试:Java知识答案精解

目录 Java 集合 集合概述 HashMap ConcurrentHashMap 泛型 反射 注解 IO流 异常、深浅拷贝与Java8新特性 Java异常 深浅拷贝 Java8新特性 并发 线程 线程池 锁 volatile JVM 内存区域 内存模型 类加载机制 垃圾回收机制 如何判断对象已死 Java 集合 …...

Windows上一款特别好用的画图软件

安装 废话不多说&#xff0c;打开windows的应用商店&#xff0c;搜索draw.io&#xff0c;点击获取即可。 画图 draw.io的布局左边是各种图形组件&#xff0c;中间是画布&#xff0c;右边是属性设置&#xff0c;文件扩展名是.drawio。 点击左边列表中的图形可以将它添加到画…...

html--学习

javascrapt交互&#xff0c;网页控制JavaScript&#xff1a;改变 HTML 图像本例会动态地改变 HTML <image> 的来源&#xff08;src&#xff09;&#xff1a;点亮灯泡<script>function changeImage() {elementdocument.getElementById(myimage) #内存变量&#xff0…...

【Python】 -- 趣味代码 - 小恐龙游戏

文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...

springboot 百货中心供应链管理系统小程序

一、前言 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;百货中心供应链管理系统被用户普遍使用&#xff0c;为方…...

逻辑回归:给不确定性划界的分类大师

想象你是一名医生。面对患者的检查报告&#xff08;肿瘤大小、血液指标&#xff09;&#xff0c;你需要做出一个**决定性判断**&#xff1a;恶性还是良性&#xff1f;这种“非黑即白”的抉择&#xff0c;正是**逻辑回归&#xff08;Logistic Regression&#xff09;** 的战场&a…...

前端导出带有合并单元格的列表

// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...

基于Uniapp开发HarmonyOS 5.0旅游应用技术实践

一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架&#xff0c;支持"一次开发&#xff0c;多端部署"&#xff0c;可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务&#xff0c;为旅游应用带来&#xf…...

[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?

论文网址&#xff1a;pdf 英文是纯手打的&#xff01;论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误&#xff0c;若有发现欢迎评论指正&#xff01;文章偏向于笔记&#xff0c;谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...

五年级数学知识边界总结思考-下册

目录 一、背景二、过程1.观察物体小学五年级下册“观察物体”知识点详解&#xff1a;由来、作用与意义**一、知识点核心内容****二、知识点的由来&#xff1a;从生活实践到数学抽象****三、知识的作用&#xff1a;解决实际问题的工具****四、学习的意义&#xff1a;培养核心素养…...

ffmpeg(四):滤镜命令

FFmpeg 的滤镜命令是用于音视频处理中的强大工具&#xff0c;可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下&#xff1a; ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜&#xff1a; ffmpeg…...

【单片机期末】单片机系统设计

主要内容&#xff1a;系统状态机&#xff0c;系统时基&#xff0c;系统需求分析&#xff0c;系统构建&#xff0c;系统状态流图 一、题目要求 二、绘制系统状态流图 题目&#xff1a;根据上述描述绘制系统状态流图&#xff0c;注明状态转移条件及方向。 三、利用定时器产生时…...

三体问题详解

从物理学角度&#xff0c;三体问题之所以不稳定&#xff0c;是因为三个天体在万有引力作用下相互作用&#xff0c;形成一个非线性耦合系统。我们可以从牛顿经典力学出发&#xff0c;列出具体的运动方程&#xff0c;并说明为何这个系统本质上是混沌的&#xff0c;无法得到一般解…...