使用OpenCV保存16/32位PNG时int16类型被截断为uint8问题咨询
问题原因
- OpenCV的
cv2.imwrite接口对PNG格式的整数输入有严格的类型限制:仅原生支持*无符号8位整数(uint8)和无符号16位整数(uint16)*两种类型的数组写入为PNG文件,不支持有符号的int16类型。 - 当你传入int16类型的数组调用imwrite时,OpenCV会默认执行兼容逻辑:将数组值截断到uint8的取值范围[0,255],大于255的统一置为255,再以8位PNG格式写入,这就是你存完再读取只有0、100、255三个值的原因。
- 你后续改用uint16类型存储正常,是因为OpenCV检测到输入为uint16类型后,会自动以16位无符号位深写入PNG文件,而你的数值范围是0~1900,远小于uint16的最大值65535,不会出现截断,所以数值可以完整保留。
正确实现方案
- 读取原始图像
testImg = cv2.imread("testImg.png", -1)
- 转换类型时直接使用uint16,不要用int16
testImg = testImg.astype('uint16')
- 执行像素值缩放操作
testImg = testImg * 100
- 直接写入文件即可,读取时加
-1参数就能得到完整的uint16数组
cv2.imwrite("testImg16Bit.png", testImg) testImg16Bit = cv2.imread("testImg16Bit.png", -1)
注意事项
- 如果你的业务逻辑中需要使用有符号整数做运算,可以在读取到uint16数据后再转成int16/int32做处理,处理完成需要写入文件时,再转回uint16即可。
- 转uint16前要确认所有像素值都是非负的,否则负数会出现溢出,得到异常数值。
内容的提问来源于stack exchange,提问作者blackbug
相关产品推荐
相关产品推荐

