【问题标题】:OpenCV BGR image to 16 bit gray scaleOpenCV BGR 图像转 16 位灰度
【发布时间】:2020-09-30 13:21:49
【问题描述】:

在 OpenCV 中,当我将 JPG 图像(每通道 8 位)转换为灰度时,使用 cv.cvtColor(img, cv.COLOR_BGR2GRAY) 或直接将其读取为灰度:cv.imread(path + 'image.JPG', cv.IMREAD_GRAYSCALE),灰度图像只有 8 位图像。

有没有办法获得 16 位灰度图像?

我知道我可以对灰度图像的值进行平方并得到 16 位,但我想要一个真正的 16 位颜色信息(不是放大的 8 位)。

【问题讨论】:

  • 您是否尝试在图像上应用np.uint16()
  • @JenilDave,我尝试在颜色转换之前添加img = np.uint16(img),灰度输出仍然只有8位颜色信息。
  • 不确定您真正希望的是什么,因为从 BGR 到灰度的转换无论如何都是相当随意/粗略的,因此恕我直言,从一开始就没有太多的准确性。其他人可能有不同的想法,我很高兴得到纠正,如果有人有更好的想法,请去说。
  • 您可以将图像缩放到您需要的范围(例如,而不是 0...255 到 65535 by pixel/255*65535),但您不会从中获得任何更好的数据信息...跨度>

标签: python opencv


【解决方案1】:

您可以创建自定义函数,将 uint16 中的 BGR 转换为 uint16 中的 GRAYSCALE。例如如下:

def bgr2gray(img):
   weights = [0.11, 0.59, 0.3]
   return np.uint16(np.dot(img, weight))

其中权重是用于从 RGB/BGR 转换为灰度的标准权重 (https://www.tutorialspoint.com/dip/grayscale_to_rgb_conversion.htm#:~:text=Since%20its%20an%20RGB%20image,Its%20done%20in%20this%20way.&text=If%20you%20have%20an%20color,into%20grayscale%20using%20average%20method.)。

然后,您可以将此函数应用于之前转换为 uint16 的 BGR 图像。但是,这通常不会为您提供比将 8 位 BGR 图像转换为 8 位灰度图像更多的信息。如果原始 BGR 图像是 16 位的,情况会有所不同。

要从 uint8 转换为 uint16,应使用以下公式:

img16 = np.uint16(img8)*256

【讨论】:

  • 我正在尝试其他方式,但实际上我最终做了和你一样的事情,就像你即将发布它作为答案:) 这种方法确实有效,尽管权重需要 255 倍“更重”为了将其扩展到 16 位。
【解决方案2】:

您可以将 8 位/像素灰度图像转换为每像素 16 位,但您必须注意,16 bpp 图像不会比原始图像传输更多信息。

如果您想保持原始动态 (0->255),请执行以下操作:

img16 = np.uint16(img8)

如果您想扩展动态(对需要超过 8 bpp 预置的进一步处理有意义),请执行以下操作:

cv.convertScaleAbs(img8,img16,alpha=(65535/255))

【讨论】:

  • 我已经设法做了类似的事情(只是通过平方值)。问题是我有点“需要”额外的信息。如果没有额外的信息,(就我而言)从 8 位到 16 位是没有意义的。不过,谢谢!
  • 在这种情况下没有什么神奇的,文件中传输的信息(8bpp)就是你所拥有的!
  • @DatHa 请注意,如果您将值平方而不是遵循 Jean-Marc 的线性建议,那么您将引入非线性或对比度变化。
【解决方案3】:

在将 BGR 系数应用到图像之前将其缩放 256:

import numpy as np
import cv2

# Create a small BGR image with unique pixel values

test_img = np.array([[(b, g, r)
                      for b in range(0, 256, 8)
                      for g in range(2, 256, 8)
                      for r in range(4, 256, 8)]], dtype=np.uint8)


coefficients = np.uint16(256 * np.array((.114, .587, .299)))
test_img.dot(coefficients)

这确实保留了其他信息:

>>> len(np.unique(cv2.cvtColor(test_img, cv2.COLOR_BGR2GRAY)))
249

>>> len(np.unique(test_img.dot(coefficients)))
7034

【讨论】:

    猜你喜欢
    • 2012-06-13
    • 1970-01-01
    • 1970-01-01
    • 2015-08-11
    • 1970-01-01
    • 2015-06-29
    • 1970-01-01
    • 1970-01-01
    • 2020-05-15
    相关资源
    最近更新 更多