我正在创建一张图片:
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-65535之间的先前值,分配介于0-255之间的值。
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)
提示:如果您关心性能,OpenCV版本在我的Mac电脑上比Numpy快约50%。
cv2.normalize
怎么样? - Jeru Lukenormalize
会拉伸你的强度,从而在视觉上改变图像。如果这是目标 - 是的(即您有一个在最小-最大归一化数据集上训练的模型)。 - apatsekinnp.empty
是一个占位符,不需要任何注释。但是截断/环绕需要注意。 - Christoph Rackwitz