【问题标题】:Saving 16-bit image in opencv with cmap (cv::ColorMap only supports source images of type CV_8UC1 or CV_8UC3 in function 'operator()')使用 cmap 在 opencv 中保存 16 位图像(cv::ColorMap 仅支持函数 'operator()' 中的 CV_8UC1 或 CV_8UC3 类型的源图像)
【发布时间】:2020-05-09 10:32:04
【问题描述】:

我正在尝试使用 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

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

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

它会抛出以下错误:

错误:OpenCV(4.1.0) /io/opencv/modules/imgproc/src/colormap.cpp:684: 错误:(-5:Bad argument) cv::ColorMap 只支持源图像 在函数 'operator()' 中键入 CV_8UC1 或 CV_8UC3

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

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

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

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

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

【问题讨论】:

  • 使用 arr8 = (arr16/256).astype(np.uint8) 代替 arr8 = arr16.astype(np.uint8)。您需要将图像从[0 ... 65535] 正确缩放到[0 ... 255]。应用颜色图,显示和保存(作为 8 位图像!)然后也可以在 OpenCV 中使用。
  • 感谢@HansHirse,它有效。有什么方法可以用 cmap 保存 16 位图像吗?
  • 恐怕不仅仅使用 OpenCV。您需要编写自己的转换 16 位灰度 --> 16 位 RGB 和颜色图。 (这并不难,但你必须自己编写代码。)
  • 噪音是由于从浮点数直接转换为 8bit 造成的。您应该先重新缩放,然后再应用转换。

标签: python numpy opencv matplotlib


【解决方案1】:

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

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

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

我们在规范化管道中内部转换为 32 位浮点数,然后应用通常限制为 255 个值的颜色图调色板,但您可以使用更多值创建自己的调色板。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-18
    • 2017-09-03
    • 2013-02-26
    • 2011-02-23
    • 2017-08-27
    • 1970-01-01
    相关资源
    最近更新 更多