如何在Python中显示RGB565大端或16位灰度大端格式的原始图像?
解决Python中显示Big-Endian格式原始图像的问题
你遇到的核心问题是文件存储的是Big-Endian字节序,但numpy.fromfile默认使用系统原生字节序(通常是Little-Endian),所以读取后的数据字节序不对,导致显示异常。下面分两种格式给出具体的解决方法:
1. 处理16位灰度Big-Endian图像
针对这种情况,有两种简单的修正方式:
方式一:读取时直接指定Big-Endian dtype
在np.fromfile中直接使用大端字节序的 dtype,这样读取出来的数据就是正确的:
import cv2 import numpy as np fd = open('your_image_path', 'rb') rows = 360 cols = 640 # 使用>i2表示Big-Endian的16位有符号整数,也可以用>u2表示无符号(根据你的图像数据类型选择) f = np.fromfile(fd, dtype=np.dtype('>i2'), count=rows*cols) im = f.reshape((rows, cols)) fd.close() # OpenCV可以直接显示16位灰度图 cv2.imshow('16-bit Grayscale Big-Endian', im) cv2.waitKey(0) cv2.destroyAllWindows()
方式二:读取后转换字节序
如果已经用默认dtype读取了数据,可以通过byteswap()方法转换为大端:
import cv2 import numpy as np fd = open('your_image_path', 'rb') rows = 360 cols = 640 f = np.fromfile(fd, dtype=np.int16, count=rows*cols) # 转换字节序为Big-Endian f = f.byteswap().newbyteorder() im = f.reshape((rows, cols)) fd.close() cv2.imshow('16-bit Grayscale Big-Endian', im) cv2.waitKey(0) cv2.destroyAllWindows()
2. 处理RGB565 Big-Endian图像
RGB565是将R(5位)、G(6位)、B(5位)打包成16位的格式,Big-Endian下,每个像素的高8位是R[4:0] + G[5:3],低8位是G[2:0] + B[4:0]。我们需要把这些分量提取出来,转换为8位的RGB图像才能正常显示:
import cv2 import numpy as np fd = open('your_image_path', 'rb') rows = 360 cols = 640 # 读取Big-Endian的16位无符号整数(RGB565一般是无符号) f = np.fromfile(fd, dtype=np.dtype('>u2'), count=rows*cols) im_16bit = f.reshape((rows, cols)) fd.close() # 提取R、G、B分量 # 右移11位获取5位R,然后扩展到8位(乘以8,因为5位最大值31,31*8=248,接近255) r = ((im_16bit >> 11) & 0x1F) * 8 # 右移5位后取低6位获取G,扩展到8位(乘以4,6位最大值63,63*4=252) g = ((im_16bit >> 5) & 0x3F) * 4 # 取低5位获取B,扩展到8位(乘以8) b = (im_16bit & 0x1F) * 8 # 合并为3通道8位RGB图像 im_rgb = np.stack([r, g, b], axis=-1).astype(np.uint8) # OpenCV默认是BGR格式,所以需要转换一下 im_bgr = cv2.cvtColor(im_rgb, cv2.COLOR_RGB2BGR) cv2.imshow('RGB565 Big-Endian', im_bgr) cv2.waitKey(0) cv2.destroyAllWindows()
注意事项
- 如果你的图像是无符号类型,记得用
u2而不是i2,避免出现负数导致的显示问题。 - RGB565的分量扩展方式是为了把低位数的分量映射到8位范围,你也可以用
((x / max_value) * 255).astype(np.uint8)的方式,结果差异不大。
内容的提问来源于stack exchange,提问作者TechHeb
相关产品推荐
相关产品推荐

