uint16数据的读取以及转换为uint8数据显示

  Kinect相机产生的深度数据为uint16数据,16位无符号整型,图片显示一般为uint8数据,本文介绍如何正确读取Kinect深度数据以及将其转化为uint8数据进行显示。
读取uint16位数据

import cv2
path = 'uint16_img.png'
img = cv2.imread(path, cv2.IMREAD_UNCHANGED)
print(img.dtype)
print(img)

>>>
uint16
[[2369 2368 2368 ... 1469 1466 1464]
 [2373 2372 2370 ... 1469 1467 1464]
 [2376 2375 2374 ... 1469 1466 1463]
 ...
 [1610 1612 1614 ... 1816 1813 1810]
 [1609 1611 1613 ... 1816 1813 1810]
 [1607 1610 1613 ... 1816 1813 1810]]

将uint16位数据转化为uint8数据的灰度图
1、直接使用np.uint8()进行转换。

import cv2
import numpy as np
path = 'uint16_img.png'
uint16_img = cv2.imread(path, cv2.IMREAD_UNCHANGED)
uint8_img = np.uint8(uint16_img)

2、把图片等比例缩放到0-255之间再转换为uint8数据。

import cv2
import numpy as np
path = 'uint16_img.png'
uint16_img = cv2.imread(path, cv2.IMREAD_UNCHANGED)
uint16_img -= uint16_img.min()
uint16_img = uint16_img / (uint16_img.max()-uint16_img.min())
uint16_img *= 255
uint8_img = np.uint8(uint16_img)

  第一种直接转换为uint8数据的方法会对数据造成一定的影响。np.uint8()会强制将大于255的数据转化为0-255之间,本来就在0-255之间的数据则如实保存。转换方法为减去256或256的倍数,得到一个在0-255范围内的结果。第二种方法由于先对数据进行了合理的缩放,因此不存在数据信息会被影响的问题。下面举一个实例:

import cv2
import numpy as np
a = np.array([[200, 300, 400],
   	 		 [120, 230, 360],
    		 [240, 310, 120]])
a1 = np.uint8(a)
a2 = a.copy()
a2 -= a2.min()
a2 = a2 / (a2.max()-a2.min())
a2 *= 255
a2 = np.uint8(a2)
print(a1)
print(a1.dtype)
print(a2)
print(a2.dtype)

>>>
[[200  44 144]
 [120 230 104]
 [240  54 120]]
uint8
[[ 72 163 255]
 [  0 100 218]
 [109 173   0]]
uint8

将uint16位数据保存为图片
  正常使用imwrite()函数保存即可,得到的图片中的数据仍然为uint16数据类型。

import cv2
cv2.imwrite('uint16_img', uint16_img)

你可能感兴趣的:(Kinect,python,numpy)