python - 使用 cmap 在 opencv 中保存 16 位图像(cv::ColorMap 仅支持函数 'operator()' 中 CV_8UC1 或 CV_8UC3 类型的源图像)

标签 python numpy opencv matplotlib

我正在尝试使用 cmap 在 opencv 中保存/显示 16 位 numpy 数组(如图像),但它不起作用。另一方面,它在 matplotlib 中运行顺利。

我的深度学习模型给出了一个 numpy 数组 arr (<class 'numpy.ndarray'>)。您可以通过 here 获取.

# np array predicted from a depth model
>>> arr16 = np.load('pred_depth_scale.npy')
>>> arr16.dtype, arr16.shape
(dtype('uint16'), (466, 492))
>>> cv2.imshow('img', arr16)
# shows image in grayscale

uint16_cv2_imshow

我想将其转换为其他颜色图:

>>> arr16 = cv2.applyColorMap(arr16, cv2.COLORMAP_COOL)

它抛出以下错误:

error: OpenCV(4.1.0) /io/opencv/modules/imgproc/src/colormap.cpp:684: error: (-5:Bad argument) cv::ColorMap only supports source images of type CV_8UC1 or CV_8UC3 in function 'operator()'

现在,如果我将图像转换为 uint8 ,图像包含噪声。

>>> arr8 = arr16.astype(np.uint8)
>>> arr8 = cv2.applyColorMap(arr8, cv2.COLORMAP_COOL)
>>> cv2.imshow('img', arr8)

uint8_cv2_imshow

另一方面,使用 matplotlib,cmap工作正常,如下:

>>> plt.imshow(arr16, cmap='magma')

uint16_plt_imshow

我的问题是:如何使用 cmap 在 opencv 中保存/显示 16 位图像?

最佳答案

绘图时 8 位图像中的噪声是由于缩放不当造成的。它可以通过以下方式从 16 位([0 ... 65535] 到 8 位 [0 ... 255])缩放(谢谢评论中的@HansHirse):

arr8 = (arr16/256).astype(np.uint8).

matplotlib 在显示图像之前在内部将图像转换为 32 位 float ,并且颜色图限制为 8 位(根据 github issue ):

We internally convert to 32bit floats in the normalization pipeline, then apply the colormap palettes which are typically limited to 255 values, but you can create your own palettes with more values.

关于python - 使用 cmap 在 opencv 中保存 16 位图像(cv::ColorMap 仅支持函数 'operator()' 中 CV_8UC1 或 CV_8UC3 类型的源图像),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59873709/

相关文章:

python - 获取 np.linalg.svd 的奇异值作为矩阵

python - 如何将 numpy 矩阵转换为 bool 矩阵?

opencv - 来自pynput的Mouse.position无法正常工作[python2,opencv,mac,jupyter]

python - cv2.solve无法返回最小二乘解

python - 如何阻止 's' 在我的循环中重复出现两次?

python - 在 Firefox 中继续使用 selenium 之前等待类存在

python - 在路径中使用变量的目录中创建文件夹(Python 3.6)

Python pickle 似乎在类内部中断,但在命令行脚本中却没有

python - 树莓派:校准相机和图像不失真

c - OpenCV:调整图像大小