Issue
I'm trying to read and save a 12bit Raw file using Python and openCV. The code I'm using saves an image but the saved image is garbled / distorted.
The image is from a FLIR Oryx Camera 23MP (5320x4600) 12Bit with BayerRG12P pixelformat, which should be RG GB bayer pattern.
import cv2
import numpy as np
width = 5320
height = 4600
with open("aaa12packed.Raw", "rb") as rawimg:
img = np.fromfile(rawimg, np.dtype('u1'), width * height).reshape(height, width)
colimg = cv2.cvtColor(img, cv2.COLOR_BAYER_GR2RGB)
cv2.imwrite("test.jpeg", colimg)
I uploaded two raw files that I'm using to test the debayer/demoisaic. You can download them using the link below:
"RG12P.Raw" (this is the 12bit regular) and "RG12packed.Raw" (this is the 12bit packed)
** My end goal is to use openCV to process folders containing RAW image sequences and process/convert them to another high resolution format like DPX 10bit or equivalent.
I'm very new to this - any help is appreciated.
EDIT#1: Adding screenshot with information from FLIR manual about the 12bits formats used.
Link to 12 bit channel image formats (packed and regular)
Solution
We may reuse my answer from the following post.
OpenCV doesn't support DPX 10bit image format.
You may use Tiff format or 16 bits PNG, but you may need to scale the pixels by 16 (placing the 12 bits in the upper part of the 16 bits).
Code sample:
import cv2
import numpy as np
width = 5320
height = 4600
with open("RG12P.Raw", "rb") as rawimg:
# Read the packed 12bits as bytes - each 3 bytes applies 2 pixels
data = np.fromfile(rawimg, np.uint8, width * height * 3//2)
data = data.astype(np.uint16) # Cast the data to uint16 type.
result = np.zeros(data.size*2//3, np.uint16) # Initialize matrix for storing the pixels.
# 12 bits packing: ######## ######## ########
# | 8bits| | 4 | 4 | 8 |
# | lsb | |msb|lsb | msb |
# <-----------><----------->
# 12 bits 12 bits
result[0::2] = ((data[1::3] & 15) << 8) | data[0::3]
result[1::2] = (data[1::3] >> 4) | (data[2::3] << 4)
bayer_im = np.reshape(result, (height, width))
# Apply Demosacing (COLOR_BAYER_BG2BGR gives the best result out of the 4 combinations).
bgr = cv2.cvtColor(bayer_im, cv2.COLOR_BAYER_BG2BGR) # The result is BGR format with 16 bits per pixel and 12 bits range [0, 2^12-1].
# Show image for testing (multiply by 16 because imshow requires full uint16 range [0, 2^16-1]).
cv2.imshow('bgr', cv2.resize(bgr*16, [width//10, height//10]))
cv2.waitKey()
cv2.destroyAllWindows()
# Convert to uint8 before saving as JPEG (not part of the conversion).
colimg = np.round(bgr.astype(float) * (255/4095))
cv2.imwrite("test.jpeg", colimg)
Answered By - Rotem
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.