最近看到了几篇博客,自己又比较无聊,所以做了一系列OpenCV储存和读取不同格式和不同数据类型的对比实验,具体来说,对比的是tiff
和png
两种文件类型和float32
和uint16_t
两种数据类型对于数据的影响。
Python3.7.3
和opencv-python(4.1.0.25)
uint16_t
数据友好,对float数据不友好(显示不正常,需要手动映射到8位数据来可视化)。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()
当生成的随机数据值域处于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的数值。
当生成的随机数据值域处于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的数值。
不溢出的前提下,
float
在保存前和保存后显示的时候,凡是大于255,都会显示为白色,uint16_t
会显示为0-255之间,应该是0-65535之间的映射。
保存后再读取,数值都是正确的。
不溢出的前提下,
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深度图像保存方法的部分代码。