简体   繁体   English

OpenCV BGR 图像到 16 位灰度

[英]OpenCV BGR image to 16 bit gray scale

In OpenCV when I convert JPG image (8 bit per channel) to gray scale, either using cv.cvtColor(img, cv.COLOR_BGR2GRAY) or simply reading it as a grayscale immediately: cv.imread(path + 'image.JPG', cv.IMREAD_GRAYSCALE) , the grayscale image is only an 8 bit image.在 OpenCV 中,当我将 JPG 图像(每通道 8 位)转换为灰度时,可以使用cv.cvtColor(img, cv.COLOR_BGR2GRAY)或直接将其作为灰度读取: cv.imread(path + 'image.JPG', cv.IMREAD_GRAYSCALE) ,灰度图像只是一个 8 位图像。

Is there a way of getting a 16 bit gray scale image?有没有办法获得 16 位灰度图像?

I know I can square the values of the grayscale image and get 16 bits that way, but I want a true 16 bit of colour information (not 8 bits scaled up).我知道我可以对灰度图像的值进行平方并以这种方式获得 16 位,但我想要真正的 16 位颜色信息(不是 8 位放大)。

What you could do is create your custom function to convert BGR in uint16 to a GRAYSCALE in uint16.您可以做的是创建自定义函数,将 uint16 中的 BGR 转换为 uint16 中的 GRAYSCALE。 Fore example as follows:例如如下:

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

Where the weights are the standard weights used to convert from RGB/BGR to grayscale ( 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. ).其中权重是用于从 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。 )。

Then you would apply this function to the BGR image that you previously converted to uint16.然后,您可以将此函数应用于您之前转换为 uint16 的 BGR 图像。 However, this should in general not give you more information than converting the 8-bit BGR image to a 8-bit grayscale image.但是,与将 8 位 BGR 图像转换为 8 位灰度图像相比,这通常不会为您提供更多信息。 It would be different if the original BGR image was 16-bit.如果原始 BGR 图像是 16 位,则情况会有所不同。

To convert from uint8 to uint16, you should use the following formula:要将 uint8 转换为 uint16,您应该使用以下公式:

img16 = np.uint16(img8)*256

You can convert you 8 bit/pixel gray image to a 16 bits per pixel but you have to note that the 16 bpp image will not transport more information than the original one.您可以将 8 位/像素灰度图像转换为每像素 16 位,但您必须注意,16 bpp 图像不会传输比原始图像更多的信息。

If you want to keep the original dynamic (0->255) do:如果要保持原始动态 (0->255),请执行以下操作:

img16 = np.uint16(img8)

If you want to extend the dynamic (make sense for further processing that require more than 8 bpp prevision ) do:如果您想扩展动态(对于需要超过 8 bpp prevision 的进一步处理有意义),请执行以下操作:

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

Scale the BGR coefficients by 256 before applying them to the image:在将 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)

This does preserve additional information:这确实保留了附加信息:

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM