【Python】读取显示pgm图像文件

文章目录

  • 零. 前言
  • 一. pgm基本概念
  • 二. pgm基本信息读取
  • 三. pgm图像渲染
  • 四. 代码优化

零. 前言

这学期要学多媒体信息隐藏对抗,发现其中的图像数据集文件都是pgm文件形式的。虽然是图像文件,但是却不能直接通过图像查看器来打开,上网一搜:”如何打开pgm文件?“多半是使用第三方软件photoshop之类的。

都是能写代码的人了,难道为了看几张图片还要下一个几G软件吗?

至此,我就开始考虑如何使用python读取pgm(Portable Gray Map)文件并显示出来。

一. pgm基本概念

如果使用记事本的方式打开,可以看到如下格式(以P2为例):

P2
width height
max_gray_value
pixel1 pixel2 pixel3 ... pixelN
...

例如下面的P5:

在这里插入图片描述

下面我们逐行解析一下:

  • 首行:Magic Number(魔数)是portable像素图片文件中的一个标识符,用于指示文件的类型和格式。以下是文件中可能出现的几种魔数及其含义:
    1. P1:表示这是一个ASCII格式的黑白二值图像。在这种格式下,像素的灰度值只能是0或1。
    2. P2:表示这是一个ASCII格式的灰度图像。在这种格式下,像素的灰度值可以是0到最大灰度值之间的任何整数。
    3. P3:表示这是一个ASCII格式的彩色图像。在这种格式下,每个像素包含三个分量(红、绿、蓝)的灰度值。
    4. P4:表示这是一个二进制格式的黑白二值图像。在这种格式下,像素的灰度值只能是0或1。
    5. P5:表示这是一个二进制格式的灰度图像。在这种格式下,像素的灰度值可以是0到最大灰度值之间的任何整数。
    6. P6:表示这是一个二进制格式的彩色图像。在这种格式下,每个像素包含三个分量(红、绿、蓝)的灰度值。

基于此,我们可以得到如下表格:

魔数类型编码方式文件后缀
P1单色图ASSIIPBM
P2灰度图ASSIIPGM
P3像素图ASSIIPPM
P4单色图二进制PBM
P5灰度图二进制PGM
P6像素图二进制PPM
  • 第二行:widthheight 表示图像的宽度和高度。

  • 第三行:

    • 如果是P1、P4:不存在颜色分量的最大值,即没有表示。
    • 如果是P2、P5:max_gray_value 表示灰度值的最大值(通常是255)。
    • 如果是P3、P6:max_color_value 表示颜色分量的最大值(通常是255)。
  • 后续:pixel1, pixel2, … pixelN 是图像的像素值。

    ​ 像素值可以是二进制或ASCII格式,如上图所示,如果无法解析成ASCII形式的字符,则表示这个pgm文件是二进制表示的pixels。

二. pgm基本信息读取

针对不同编码方式表示的像素,我们具有不同的读取与解析方案read_binary_pgm以及read_ascii_pgm。

代码如下:

def read_binary_pgm(file_path):with open(file_path, 'rb') as f:# 读取头部信息magic_number = f.readline().decode().strip()width, height = map(int, f.readline().decode().strip().split())max_gray_value = int(f.readline().decode().strip())# 读取像素值pixels = list(f.read())return (width, height, max_gray_value, pixels)def read_ascii_pgm(file_path):with open(file_path, 'r') as f:# 读取头部信息header = f.readline().strip()width, height = map(int, f.readline().strip().split())max_gray_value = int(f.readline().strip())# 读取像素值pixels = [int(line) for line in f.readlines() if line.strip()]return (width, height, max_gray_value, pixels)file_path = '../pgmfiles/1.pgm' # 注意修改你的读取路径# width, height, max_gray_value, pixels = read_ascii_pgm(file_path)
width, height, max_gray_value, pixels = read_binary_pgm(file_path)print(f"Width: {width}, Height: {height}")
print(f"Max Gray Value: {max_gray_value}")
print(f"Number of Pixels: {len(pixels)}")

这个小demo可以获取到这个pgm的基本信息:

三. pgm图像渲染

但是如何通过这些数据来渲染成图像呢?我们可以先将像素值转换为NumPy数组,并通过matplotlib将其显示为图像。

首先在上述代码顶部导包,并且在尾部追加图像显示代码即可:

import numpy as np
import matplotlib.pyplot as plt# ...上述read代码...# 将像素列表转换为NumPy数组
pixels_array = np.array(pixels).reshape(height, width)# 显示图像
plt.imshow(pixels_array, cmap='gray', vmin=0, vmax=max_gray_value)
plt.show()

运行后,图像渲染如下:
在这里插入图片描述

四. 代码优化

最后,优化一下代码,根据首行的魔数来兼容P2和P5两种情况,实现函数read_pgm。

import numpy as np
import matplotlib.pyplot as pltfile_type = None  # 全局的文件类型变量def read_pgm(file_path):global file_typewith open(file_path, 'rb') as f:magic_number = f.readline().decode().strip()file_type = magic_number  # 更新全局的文件类型变量width, height = map(int, f.readline().decode().strip().split())max_gray_value = int(f.readline().decode().strip())if magic_number == 'P5':# 二进制格式pixels = list(f.read())elif magic_number == 'P2':# ASCII格式pixels = [int(line) for line in f.readlines() if line.strip()]else:raise ValueError("Unsupported file type.")return (width, height, max_gray_value, pixels)def render_image(pixels, width, height, max_gray_value):# 将像素列表转换为NumPy数组pixels_array = np.array(pixels).reshape(height, width)# 显示图像plt.imshow(pixels_array, cmap='gray', vmin=0, vmax=max_gray_value)plt.show()file_path = '../pgmfiles/1.pgm'width, height, max_gray_value, pixels = read_pgm(file_path)print(f"Width: {width}, Height: {height}")
print(f"Max Gray Value: {max_gray_value}")
print(f"Number of Pixels: {len(pixels)}")# 显示图像
render_image(pixels, width, height, max_gray_value)# 根据全局的文件类型变量进行其他操作
if file_type == 'P5':print("This is a binary format PGM file.")
elif file_type == 'P2':print("This is an ASCII format PGM file.")

基于此,其实也可以继续优化兼容其他4种文件,比如xx.ppm,xxx.pbm 文件。

再完善一点可以封装成一个小型的ppm/pgm/pbm图像显示器.exe。

不过那个就不在笔者的考虑范围内了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/126050.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

大模型 Decoder 的生成策略

本文将介绍以下内容: IntroductionGreedy Searchbeam searchSamplingTop-K SamplingTop-p (nucleus) sampling总结 一、Introduction 1、简介 近年来,由于在数百万个网页数据上训练的大型基于 Transformer 的语言模型的兴起,开放式语言生…

怎么利用互联网赚钱,网上赚钱的7种方法

互联网的兴起改变了我们的生活方式,不仅让我们的世界更为便捷,也为我们提供了赚钱的机会。越来越多的人开始通过互联网实现财富梦想。你是否曾想过,如何利用互联网来赚钱呢?今天,我将为大家分享七种赚钱方法&#xff0…

Leetcode hot 100之双指针(快慢指针、滑动窗口)

目录 数组 有序的平方仍有序 删除/覆盖元素 移动零:交换slow和fast 滑动窗口:最短的连续子串(r可行解->l--最短解) 最小长度的子数组 求和:sort、l i 1, r len - 1 三数之和abctarget 四数之和abcdtarg…

汽车类、TPS7B8225QDGNRQ1、TPS7B8233EPWPRQ1、TPS7B8601QKVURQ1 40V、低压降 (LDO) 线性稳压器

一、TPS7B82-Q1 汽车类 300mA、高压、超低 IQ 低压降稳压器 (介绍)在汽车电池连接应用中,低静态电流 (IQ) 对于省电和延长电池寿命而言至关重要。对于始终开启的系统,必须要实现超低 IQ。 TPS7B82-Q1 是一款旨在在 3V 至 40V&…

【C++】运算符重载 ⑧ ( 左移运算符重载 | 友元函数 / 成员函数 实现运算符重载 | 类对象 使用 左移运算符 )

文章目录 一、左移运算符重载1、友元函数 / 成员函数 实现运算符重载2、类对象 使用 左移运算符3、左移运算符 << 重载 二、完整代码示例 一、左移运算符重载 1、友元函数 / 成员函数 实现运算符重载 运算符重载 的正规写法一般都是 使用 成员函数 的形式 实现的 ; 加法…

Llama2-Chinese项目:8-TRL资料整理

TRL&#xff08;Transformer Reinforcement Learning&#xff09;是一个使用强化学习来训练Transformer语言模型和Stable Diffusion模型的Python类库工具集&#xff0c;听上去很抽象&#xff0c;但如果说主要是做SFT&#xff08;Supervised Fine-tuning&#xff09;、RM&#x…

Python脚本实现xss攻击

实验环境&#xff1a;zd靶场、vscode 知识点 requests.session() 首先我们需要先利用python requests模块进行登录&#xff0c;然后利用开启session记录&#xff0c;保持之后的操作处于同一会话当中 requests.session()用于创建一个会话(session)的实例对象。使用requests库…

【JavaEE】多线程进阶(一)饿汉模式和懒汉模式

多线程进阶&#xff08;一&#xff09; 文章目录 多线程进阶&#xff08;一&#xff09;单例模式饿汉模式懒汉模式 本篇主要引入多线程进阶的单例模式&#xff0c;为后面的大冰山做铺垫 代码案例介绍 单例模式 非常经典的设计模式 啥是设计模式 设计模式好比象棋中的 “棋谱”…

Python无废话-办公自动化Excel格式美化

设置字体 在使用openpyxl 处理excel 设置格式&#xff0c;需要导入Font类&#xff0c;设置Font初始化参数&#xff0c;常见参数如下&#xff1a; 关键字参数 数据类型 描述 name 字符串 字体名称&#xff0c;如Calibri或Times New Roman size 整型 大小点数 bold …

做外贸独立站选Shopify还是WordPress?

现在确实会有很多新人想做独立站&#xff0c;毕竟跨境电商平台内卷严重&#xff0c;平台规则限制不断升级&#xff0c;脱离平台“绑架”布局独立站&#xff0c;才能获得更多流量、订单、塑造品牌价值。然而&#xff0c;在选择建立外贸独立站的过程中&#xff0c;选择适合的建站…

TinyWebServer整体流程

从main主函数开始&#xff1a; 一、定义MySQL数据库的账号、密码和用到的数据库名称。 二、调用Config获得服务器初始化属性 在这一步确定触发模式端口等信息。 三、创建服务器实例对象 设置根目录、开辟存放http连接对象的空间&#xff0c;开辟定时器空间。 四、利用Confi…

《视觉 SLAM 十四讲》V2 第 5 讲 相机与图像

文章目录 相机 内参 && 外参5.1.2 畸变模型单目相机的成像过程5.1.3 双目相机模型5.1.4 RGB-D 相机模型 实践5.3.1 OpenCV 基础操作 【Code】OpenCV版本查看 5.3.2 图像去畸变 【Code】5.4.1 双目视觉 视差图 点云 【Code】5.4.2 RGB-D 点云 拼合成 地图【Code】 习题题…