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