简体   繁体   中英

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.

Is there a way of getting a 16 bit gray scale image?

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).

What you could do is create your custom function to convert BGR in uint16 to a GRAYSCALE in uint16. 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. ).

Then you would apply this function to the BGR image that you previously converted to uint16. However, this should in general not give you more information than converting the 8-bit BGR image to a 8-bit grayscale image. It would be different if the original BGR image was 16-bit.

To convert from uint8 to uint16, you should use the following formula:

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.

If you want to keep the original dynamic (0->255) do:

img16 = np.uint16(img8)

If you want to extend the dynamic (make sense for further processing that require more than 8 bpp prevision ) do:

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

Scale the BGR coefficients by 256 before applying them to the image:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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