使用 tiff/png 文件类型对 uint16 | 您所在的位置:网站首页 › png格式5k图 › 使用 tiff/png 文件类型对 uint16 |
最近看到了几篇博客,自己又比较无聊,所以做了一系列OpenCV储存和读取不同格式和不同数据类型的对比实验,具体来说,对比的是tiff和png两种文件类型和float32和uint16_t两种数据类型对于数据的影响。 实验环境Python3.7.3和opencv-python(4.1.0.25) 先说结论: imshow函数对uint16_t数据友好,对float数据不友好(显示不正常,需要手动映射到8位数据来可视化)。imwrite函数,对tiff格式友好(无数制转换和损失),对png格式基本上友好,也就是存取uint16_t完全OK。uint16_t类型,png格式,显示没问题,存储读取没问题,比较可靠。 代码:生成随机图片: import numpy as np import cv2 def fun1(im): im=np.asarray(im,np.float32) return im def fun2(im): im=np.asarray(im,np.uint16) return im if __name__ == '__main__': #set a depth map using np.random img=np.random.randint(0,65535,size=(600,600)) img1=fun1(img) cv2.imshow("float_saved",img1) cv2.imwrite('float_saved.png',img1) img2=fun2(img) cv2.imshow("uint_saved",img2) cv2.imwrite('uint_saved.png',img2) cv2.waitKey(500) for row in range(0,20): for column in range(0,20): if img[row][column] != .0: print("row:{}, column:{}, x:{}, y:{}, value_img:{}, value_img1:{}, value_img2:{}" .format(row,column,column,row,img[row][column],img1[row][column],img2[row][column]))用PIL加载图片的代码: import numpy as np import matplotlib.pyplot as plt from PIL import Image def load_image(filename): im=Image.open(filename) return im if __name__ == '__main__': im1=load_image('float_saved.png') im2=load_image('uint_saved.png') plt.subplot(121) plt.imshow(im1) plt.subplot(122) plt.imshow(im2) plt.show()用OpenCV加载图片的代码: import cv2 img1=cv2.imread("float_saved.png",-1) cv2.imshow("float_saved -1",img1) img2=cv2.imread("uint_saved.png",-1) cv2.imshow("uint_saved -1",img2) img3=cv2.imread("uint_saved.png") cv2.imshow("uint_saved 1",img3) img4=cv2.imread("float_saved.png",cv2.IMREAD_ANYCOLOR|cv2.IMREAD_ANYDEPTH) cv2.imshow("float_saved any|any",img4) img5=cv2.imread("uint_saved.png",cv2.IMREAD_ANYCOLOR|cv2.IMREAD_ANYDEPTH) cv2.imshow("uint_saved any|any",img5) for row in range(0,20): for column in range(0,20): if img[row][column] != .0: print("row:{}, column:{}, x:{}, y:{}, value_img1:{}, value_img2:{}, value_img3:{}, value_img4:{}, value_img5:{}" .format(row,column,column,row,img1[row][column],img2[row][column],img3[row][column],img4[row][column],img5[row][column])) cv2.waitKey() cv2.destroyAllWindows() 一些实验过程中的详细结果: 使用png图像格式储存数据的时候,最大深度应该是16位。当生成的随机数据值域处于0-255之间的时候。 显示:float显示正常,uint16_t显示正常,较黑,因为255比65535小很多吧。 数值:float数值正常,uint16_t数值正常。 当生成的随机数据值域处于0-65535之间的时候。 显示:float按照0-255显示,大于255显示为白色,uint16_t显示正常。 数值:float数值大于255的全为255,不正常,uint16_t数值正常。 当生成的随机数据值域处于65536-256*65535之间的时候。 显示:float按照0-255显示,大于255显示为白色,uint16_t被截断,相当于减去65535,显示正常。 数值:float数值大于255的全为255,不正常,uint16_t数值显示为截断之后的正常数值,其实是减去65535的数值。 使用tiff图像格式储存数据的时候,存储深度不限于16位,32位甚至64位。当生成的随机数据值域处于0-255之间的时候。 显示:float显示正常,uint16_t显示正常,较黑,因为255比65535小很多吧。 数值:float数值正常,uint16_t数值正常。 当生成的随机数据值域处于0-65535之间的时候。 显示:float按照0-255显示,大于255显示为白色,uint16_t显示正常。 数值:float数值正常,uint16_t数值正常。 当生成的随机数据值域处于65536-256*65535之间的时候。uint16_t被截断。 显示:float按照0-255显示,大于255显示为白色,uint16_t因为被截断后相当于0-65535,因此在这个范围内,算是显示正常。 数值:float数值正常,uint16_t数值显示为截断之后的正常数值,其实是减去65535的数值。 使用tiff格式不溢出的前提下, float在保存前和保存后显示的时候,凡是大于255,都会显示为白色,uint16_t会显示为0-255之间,应该是0-65535之间的映射。 保存后再读取,数值都是正确的。 使用png格式不溢出的前提下, float在保存前和保存后显示的时候,凡是大于255,都会显示为白色,uint16_t会显示为0-255之间,应该是0-65535之间的映射。 保存后再读取,float保存后会将大于255的数值均置为255,数值是错误的,uint16_t数值正常。 关于数值恢复经过保存为文件再读取数据,用png会导致float数据被约束到0-255,保存再读取真实数值丢失,用tiff则不会造成任何数据损失。 关于图像显示对于float数据,只要大于255都会显示位白色,对于uint16_t,imshow函数则会将16位数据从0-65535映射到0-255. 使用了dumyy:realsense深度图像保存方法的部分代码。 |
CopyRight 2018-2019 实验室设备网 版权所有 |