公司网站建设需求,深圳网上创建公司,凡科做网站需要备案吗,重庆社区官网文章目录 零. 前言一. pgm基本概念二. pgm基本信息读取三. pgm图像渲染四. 代码优化 零. 前言
这学期要学多媒体信息隐藏对抗#xff0c;发现其中的图像数据集文件都是pgm文件形式的。虽然是图像文件#xff0c;但是却不能直接通过图像查看器来打开#xff0c;上网一搜发现其中的图像数据集文件都是pgm文件形式的。虽然是图像文件但是却不能直接通过图像查看器来打开上网一搜”如何打开pgm文件“多半是使用第三方软件photoshop之类的。
都是能写代码的人了难道为了看几张图片还要下一个几G软件吗
至此我就开始考虑如何使用python读取pgmPortable Gray Map文件并显示出来。
一. pgm基本概念
如果使用记事本的方式打开可以看到如下格式(以P2为例)
P2
width height
max_gray_value
pixel1 pixel2 pixel3 ... pixelN
...例如下面的P5 下面我们逐行解析一下
首行Magic Number魔数是portable像素图片文件中的一个标识符用于指示文件的类型和格式。以下是文件中可能出现的几种魔数及其含义 P1表示这是一个ASCII格式的黑白二值图像。在这种格式下像素的灰度值只能是0或1。P2表示这是一个ASCII格式的灰度图像。在这种格式下像素的灰度值可以是0到最大灰度值之间的任何整数。P3表示这是一个ASCII格式的彩色图像。在这种格式下每个像素包含三个分量红、绿、蓝的灰度值。P4表示这是一个二进制格式的黑白二值图像。在这种格式下像素的灰度值只能是0或1。P5表示这是一个二进制格式的灰度图像。在这种格式下像素的灰度值可以是0到最大灰度值之间的任何整数。P6表示这是一个二进制格式的彩色图像。在这种格式下每个像素包含三个分量红、绿、蓝的灰度值。
基于此我们可以得到如下表格
魔数类型编码方式文件后缀P1单色图ASSIIPBMP2灰度图ASSIIPGMP3像素图ASSIIPPMP4单色图二进制PBMP5灰度图二进制PGMP6像素图二进制PPM 第二行width 和 height 表示图像的宽度和高度。 第三行 如果是P1、P4不存在颜色分量的最大值即没有表示。如果是P2、P5max_gray_value 表示灰度值的最大值通常是255。如果是P3、P6max_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(fWidth: {width}, Height: {height})
print(fMax Gray Value: {max_gray_value})
print(fNumber 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, cmapgray, vmin0, vmaxmax_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, cmapgray, vmin0, vmaxmax_gray_value)plt.show()file_path ../pgmfiles/1.pgmwidth, height, max_gray_value, pixels read_pgm(file_path)print(fWidth: {width}, Height: {height})
print(fMax Gray Value: {max_gray_value})
print(fNumber 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.ppmxxx.pbm 文件。
再完善一点可以封装成一个小型的ppm/pgm/pbm图像显示器.exe。
不过那个就不在笔者的考虑范围内了。