我正在创建一个图像,以便:
image = np.empty(shape=(height, width, 1), dtype = np.uint16)
之后,我将图像转换为BGR模型:
image = cv2.cvtColor(image, cv2.COLOR_GRAY2BGR)
我现在想在dtype = np.uint8
中转换图像,以便将该图像与cv2.threshold()
功能一起使用。我的意思是,我想将图像转换为CV_8UC1
.
cv2.convertScaleAbs
来解决此问题。请参阅文档。
查看下面的命令终端演示:
>>> img = np.empty((100,100,1),dtype = np.uint16)
>>> image = cv2.cvtColor(img,cv2.COLOR_GRAY2BGR)
>>> cvuint8 = cv2.convertScaleAbs(image)
>>> cvuint8.dtype
dtype('uint8')
希望对您有所帮助!!
我建议你使用这个:
outputImg8U = cv2.convertScaleAbs(inputImg16U, alpha=(255.0/65535.0))
这将输出一个uint8图像并分配0-255之间的值,相对于0-65535之间的先前值
exemple :
pixel with value == 65535 will output with value 255
pixel with value == 1300 will output with value 5 etc...
我假设您想将 uint16 范围0..65535
重新缩放为 uint8 范围0..255
。换句话说,视觉图像看起来是一样的,只是颜色深度较低。
np_uint16 = np.arange(2 ** 16, dtype=np.uint16).reshape(256, 256)
np_uint8 = (np_int16 // 256).astype(np.uint8)
生成映射:
[0..255] => 0 (256 values)
[256..511] => 1 (256 values)
...
[65280..65535] => 255 (256 values)
为什么另外两个答案不正确:
接受的一个
img = np.empty((100,100,1), dtype = np.uint16)
image = cv2.cvtColor(img,cv2.COLOR_GRAY2BGR)
cvuint8 = cv2.convertScaleAbs(image)
^ 将创建一个未初始化的 uint16 数组,然后将其转换为 uint8,取 abs() 和裁剪值>255 到 255。生成的映射:
[0..254] => [0..254]
[255..65535] => 255
下一个:
outputImg8U = cv2.convertScaleAbs(inputImg16U, alpha=(255.0/65535.0))
^ 产生稍微错误的映射:
[0..128] => 0 (129 values)
[129..385] => 1 (257 values)
...
[65407..65535] => 255 (129 values)
因此2,..,254
垃圾箱以0
和255
的费用获得一个额外的价值。用convertScaleAbs
获得精确的映射有点棘手,因为它使用四舍五入:
np_int16 = np.arange(2 ** 16, dtype=np.uint16).reshape(256, 256)
np_uint8 = cv2.convertScaleAbs(np_int16, alpha = 1./256., beta=-.49999)
ps:如果你关心性能,OpenCV one比我的Mac上的Numpy快~50%。