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)
CodePudding user response:
I'm not sure of the difference between the two files you shared, but here is a fairly speedy technique to read and unpack the 12-bit samples. I am not really sure what you actually want so I have put plenty of debug code and comments so you can see what I am doing then you can fine-tune.
Don't be put off by the length of the code, there are only really 4 lines which I have numbered in comments:
#!/usr/bin/env python3
# Demosaicing Bayer Raw image
import cv2
import numpy as np
filename = 'RG12P.Raw'
# Set width and height
w, h = 5320, 4600
# Read entire file and reshape as rows of 3 bytes
bayer = np.fromfile(filename, dtype=np.uint8).reshape((-1,3)) # LINE 1
print(f'DEBUG: bayer.shape={bayer.shape}')
for i in 0,1,2:
print(f'DEBUG: bayer[{i}]={bayer[i]}')
# Make each 3-byte row into a single np.uint32 containing 2 samples of 12-bits each
bayer32 = np.dot(bayer.astype(np.uint32), [1,256,65536]) # LINE 2
print(f'DEBUG: bayer32.shape={bayer32.shape}')
for i in 0,1,2:
print(f'DEBUG: bayer32[{i}]={bayer32[i]}')
# Extract high and low samples from pairs
his = bayer32 >> 12 # LINE 3
los = bayer32 & 0xfff # LINE 4
print(f'DEBUG: his.shape={his.shape}')
for i in 0,1,2:
print(f'DEBUG: his[{i}]={his[i]}')
print(f'DEBUG: los.shape={los.shape}')
for i in 0,1,2:
print(f'DEBUG: los[{i}]={los[i]}')
# Stack into 3 channel
#BGR16 = np.dstack((B,G,R)).astype(np.uint16)
# Save result as 16-bit PNG
#cv2.imwrite('result.png', BGR16)
Sample Output
DEBUG: bayer.shape=(12236000, 3)
DEBUG: bayer[0]=[119 209 36]
DEBUG: bayer[1]=[249 17 29]
DEBUG: bayer[2]=[ 49 114 35]
DEBUG: bayer32.shape=(12236000,)
DEBUG: bayer32[0]=2412919
DEBUG: bayer32[1]=1905145
DEBUG: bayer32[2]=2322993
DEBUG: his.shape=(12236000,)
DEBUG: his[0]=589
DEBUG: his[1]=465
DEBUG: his[2]=567
DEBUG: los.shape=(12236000,)
DEBUG: los[0]=375
DEBUG: los[1]=505
DEBUG: los[2]=561