如何将图像从np.uint16转换为np.uint8?

oma*_*mar 23 python opencv numpy

我正在创建一个图像:

image = np.empty(shape=(height, width, 1), dtype = np.uint16)
Run Code Online (Sandbox Code Playgroud)

之后我将图像转换为BGR模型:

image = cv2.cvtColor(image, cv2.COLOR_GRAY2BGR)
Run Code Online (Sandbox Code Playgroud)

我现在要将图像转换为a dtype = np.uint8,以便将该图像与cv2.threshold()函数一起使用.我的意思是,我想将图像转换为CV_8UC1.

Abi*_*n K 27

您可以使用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')
Run Code Online (Sandbox Code Playgroud)

希望能帮助到你!!!


afi*_*iah 8

我建议你用这个:

outputImg8U = cv2.convertScaleAbs(inputImg16U, alpha=(255.0/65535.0))
Run Code Online (Sandbox Code Playgroud)

这将输出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...
Run Code Online (Sandbox Code Playgroud)


apa*_*kin 5

我假设您想将 uint16 range 重新调整0..65535为 uint8 range 0..255。换句话说,视觉图像看起来是一样的,只是颜色深度较低。

np_uint16 = np.arange(2 ** 16, dtype=np.uint16).reshape(256, 256)
np_uint8 = (np_int16 // 256).astype(np.uint8)
Run Code Online (Sandbox Code Playgroud)

产生映射:

[0..255] => 0 (256 values)
[256..511] => 1 (256 values)
... 
[65280..65535] => 255 (256 values)
Run Code Online (Sandbox Code Playgroud)

为什么另外两个答案不正确:

已接受一

img = np.empty((100,100,1), dtype = np.uint16)
image = cv2.cvtColor(img,cv2.COLOR_GRAY2BGR)
cvuint8 = cv2.convertScaleAbs(image)
Run Code Online (Sandbox Code Playgroud)

^ 将创建一个未初始化的 uint16 数组,然后使用 abs() 将其转换为 uint8 并将值 >255 剪裁到 255。生成的映射:

[0..254] => [0..254]
[255..65535] => 255
Run Code Online (Sandbox Code Playgroud)

下一个:

outputImg8U = cv2.convertScaleAbs(inputImg16U, alpha=(255.0/65535.0))
Run Code Online (Sandbox Code Playgroud)

^ 产生稍微错误的映射:

[0..128] => 0 (129 values)
[129..385] => 1 (257 values)
...
[65407..65535] => 255 (129 values)
Run Code Online (Sandbox Code Playgroud)

因此bins 可以以和为代价2,..,254获得一项额外价值。使用 获得精确映射有点棘手,因为它使用round half down0255convertScaleAbs

np_int16 = np.arange(2 ** 16, dtype=np.uint16).reshape(256, 256)
np_uint8 = cv2.convertScaleAbs(np_int16, alpha = 1./256., beta=-.49999)
Run Code Online (Sandbox Code Playgroud)

ps:如果你关心性能,OpenCV 比我的 Mac 上的 Numpy 快约 50%。