为何Matlab与OpenCV的imread读取同图返回像素值不同?
问题原因分析
- Matlab的
imread针对PGM这类带有实际位深信息的图像,会自动将原始位深的像素值映射到存储格式的满量程范围:你的图像实际是10位(最大值为2^10-1=1023),但存储为16位uint16格式,Matlab会把原始10位值左移6位(乘以2^6=64),让数值占满16位的有效区间(0~65535),既保留了像素的相对亮度比例,又充分利用了16位的存储位宽。 - OpenCV的
cv2.imread(file, cv2.IMREAD_UNCHANGED)则是直接读取文件中存储的原始二进制数值,也就是保留了10位的原始像素值(0~1023),没有做位扩展处理,所以两者的数值刚好差了64倍。
Python中读取到与Matlab一致像素值的方法
有两种简单的实现方式:
方法一:OpenCV读取后手动位扩展
既然知道图像的实际位深是10位,直接对读取到的uint16数组做左移6位操作即可:
import cv2 # 读取原始图像 image = cv2.imread("your_image.pgm", cv2.IMREAD_UNCHANGED) # 左移6位对齐Matlab结果 matlab_like_image = image << 6
注:因为10位最大值1023左移6位后是65472,小于uint16的最大值65535,不会出现数值溢出问题。
方法二:使用PIL库读取
PIL的图像读取逻辑和Matlab一致,会自动完成位深到存储格式的满量程映射,直接转成numpy数组就能得到和Matlab相同的结果:
from PIL import Image import numpy as np # 读取图像并转成numpy数组 image = Image.open("your_image.pgm") matlab_like_image = np.array(image)
内容的提问来源于stack exchange,提问作者bboo
相关产品推荐
相关产品推荐

