Skip to content

Commit

Permalink
added Infinite-ISP_v1.0 binary files and scripts
Browse files Browse the repository at this point in the history
  • Loading branch information
taimur-10xe committed Sep 28, 2023
1 parent cbc22c7 commit b32abcc
Show file tree
Hide file tree
Showing 5 changed files with 682 additions and 0 deletions.
Binary file added binaries/Infinite-ISP_v1.0-1080p.bin
Binary file not shown.
Binary file added binaries/Infinite-ISP_v1.0-360p.bin
Binary file not shown.
164 changes: 164 additions & 0 deletions scripts/isp_output_bin_to_isp_output_png.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
import numpy as np
import matplotlib.image as mpimg
import matplotlib.pyplot as plt
from datetime import datetime


filepath = "./"
filename = 'RTL_ImageTest_2048x1536_10bit_GRBG_1920x1080.bin'
with open(filepath + filename, 'rb') as f:
arr = np.fromfile(f, dtype=np.uint8)
f.close()

h, w, Format, CONV_STD = 1080, 1920, "BGR", 2

SupportedFormats = {
"BGR" : 1,
"YUV444": 2,
"YUV422": 3
}

def yuv_to_rgb(yuv_img):
"""
YUV-to-RGB Colorspace conversion 8bit
"""

# make nx3 2d matrix of image
mat_2d = yuv_img.reshape(
(yuv_img.shape[0] * yuv_img.shape[1], 3)
)

# convert to 3xn for matrix multiplication
mat2d_t = mat_2d.transpose()

# subract the offsets
mat2d_t = mat2d_t - np.array([[16, 128, 128]]).transpose()

if CONV_STD == 1:
# for BT. 709
yuv2rgb_mat = np.array([[74, 0, 114], [74, -13, -34], [74, 135, 0]])
else:
# for BT.601/407
# conversion metrix with 8bit integer co-efficients - m=8
yuv2rgb_mat = np.array([[64, 87, 0], [64, -44, -20], [61, 0, 105]])

# convert to RGB
rgb_2d = np.matmul(yuv2rgb_mat, mat2d_t)
rgb_2d = rgb_2d >> 6

# reshape the image back
rgb2d_t = rgb_2d.transpose()
yuv_img = rgb2d_t.reshape(yuv_img.shape).astype(np.float32)

# clip the resultant img as it can have neg rgb values for small Y'
yuv_img = np.float32(np.clip(yuv_img, 0, 255))

# convert the image to [0-255]
yuv_img = np.uint8(yuv_img)
return yuv_img

def reconstruct_yuv_from_422_custom(yuv_422_custom, width, height):
"""
Reconstruct a YUV from YUV 422 format
"""
# Create an empty 3D YUV image (height, width, channels)
yuv_img = np.zeros((height, width, 3), dtype=np.uint8)
# Rearrange the flattened 4:2:2 YUV data back to 3D YUV format
yuv_img[:, 0::2, 0] = yuv_422_custom[0::4].reshape(height, -1)
yuv_img[:, 0::2, 1] = yuv_422_custom[1::4].reshape(height, -1)
yuv_img[:, 1::2, 0] = yuv_422_custom[2::4].reshape(height, -1)
yuv_img[:, 0::2, 2] = yuv_422_custom[3::4].reshape(height, -1)
# Replicate the U and V (chroma) channels to the odd columns
yuv_img[:, 1::2, 1] = yuv_img[:, 0::2, 1]
yuv_img[:, 1::2, 2] = yuv_img[:, 0::2, 2]
return yuv_img

def reconstruct_yuv_from_444_custom(yuv_444_custom, width, height):
"""
Reconstruct a YUV from YUV 444 format
"""
# Create an empty 3D YUV image (height, width, channels)
yuv_img = np.zeros((height, width, 3), dtype=np.uint8)
# Rearrange the flattened 4:4:4 YUV data back to 3D YUV format
yuv_img[:, 0::1, 0] = yuv_444_custom[0::3].reshape(height, -1)
yuv_img[:, 0::1, 1] = yuv_444_custom[1::3].reshape(height, -1)
yuv_img[:, 0::1, 2] = yuv_444_custom[2::3].reshape(height, -1)
return yuv_img

def get_image_from_yuv_format_conversion(yuv_img, height, width, yuv_custom_format):
"""
Convert YUV image into RGB based on its format & Conversion Standard
"""

# Reconstruct the 3D YUV image from the custom given format YUV data
if yuv_custom_format == "422":
yuv_img = reconstruct_yuv_from_422_custom(yuv_img, width, height)
else:
yuv_img = reconstruct_yuv_from_444_custom(yuv_img, width, height)

return yuv_img

def reconstrct_yuv422_for_rtl(arr, height, width):
"""Reconstruct a YUV from YUV 422 format."""

# Create an empty 3D YUV image (height, width, channels)
rtl_img = np.zeros((height * width * 2,), dtype=np.uint16)

# select y, u and v channels from the binary input array
arr_y = arr[2::3]
arr_c = arr[1::3]

# Rearrange the channels to construct 3D YUV image
rtl_img[0::2] = arr_y
rtl_img[1::2] = arr_c

return rtl_img

stride = np.floor(np.floor(np.floor((w*3 + 255) /256)) * 256).astype(np.uint16)
arr = np.reshape(arr, (h, stride))

#Remove the extra zeros
arr_trun = arr[:,0:w*3]


#flatten the shape
arr_flat = arr_trun.flatten()
arr_flat_u16 = arr_flat.astype(np.uint16)
arr_corrected = np.zeros(arr_flat_u16.shape, dtype=np.uint16)


# reversing the order since the file that came from FPGA is BGR/YUV BGR/YUV BGR/YUV ...
arr_corrected[0::3] = arr_flat[2::3]
arr_corrected[1::3] = arr_flat[1::3]
arr_corrected[2::3] = arr_flat[0::3]
print('shape of final saved array ', arr_corrected.shape)
print(arr_corrected.dtype)

arr_corrected.tofile(filepath + "FPGA" + filename[3:])

#For displaying the saved image

if(SupportedFormats[Format] == SupportedFormats["BGR"]):
R_flat = arr_corrected[0::3]
G_flat = arr_corrected[1::3]
B_flat = arr_corrected[2::3]
R = R_flat.reshape(h,w)
G = G_flat.reshape(h,w)
B = B_flat.reshape(h,w)
img = np.zeros((h, w, 3), dtype=np.uint8)
img[:,:,0] = R
img[:,:,1] = G
img[:,:,2] = B

if(SupportedFormats[Format] == SupportedFormats["YUV444"]):
YUV_img = get_image_from_yuv_format_conversion(arr_flat, h, w, "444")
img = yuv_to_rgb(YUV_img)

if(SupportedFormats[Format] == SupportedFormats["YUV422"]):
YUV422_img = reconstrct_yuv422_for_rtl(arr_corrected, h, w)
YUV_img = get_image_from_yuv_format_conversion(YUV422_img, h, w, "422")
img = yuv_to_rgb(YUV_img)

plt.imshow(img)
plt.imsave(filepath + 'FPGA' + filename[3:-4] + '.png', img.astype(np.uint8))
plt.show()
82 changes: 82 additions & 0 deletions scripts/sensor_bin_to_sensor_raw.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# -*- coding: utf-8 -*-
"""
Created on Tue Feb 21 16:07:11 2023
@author: user3
"""
import numpy as np
import cv2
import matplotlib.image as mpimg
import matplotlib.pyplot as plt

# Supported Sensors

SENSOR = "AR1335"

SupportedSensors = {
"AR1335": 1,
"OV5647": 2
}

# reading the dumped binary file
filename = 'ImageTest_2048x1536_10bit_GRBG_1920x1080.bin'
with open(filename, 'rb') as f:
# read the contents of the file into a new array
arr = np.fromfile(f, dtype=np.uint8)

if(SupportedSensors[SENSOR] == SupportedSensors["AR1335"]):
h, w = 1536, 2048

if(SupportedSensors[SENSOR] == SupportedSensors["OV5647"]):
h, w = 1944, 2592

h = np.array (h, dtype = np.uint16)
w = np.array (w, dtype = np.uint16)

# Images are stored in the form of rows where the size of each row in bytes
# should be a multiple of 256, each such row size is called 'stride'
stride = np.floor(np.floor(np.floor((w+2)/3) *4 +256 - 1) /256) * 256
stride = stride.astype (np.uint16)
print (stride)

# reshaping the input based on stride
arr = np.reshape(arr, (h, stride))
print (arr.shape)

raw = np.zeros ((h,w),dtype=np.uint16)
for i in range (0, h):
k = 0
for j in range (0, stride, 4):
# data is stored in reversed order in form of 4 bytes for 3 pixels
# so fliping it to get the correct data
temp = np.flip(arr [i,j:j+4])
binary_str = ''.join(format(b, '08b') for b in temp)
binary_num_3 = int((binary_str[2:12]), 2)
binary_num_2 = int((binary_str[12:22]), 2)
binary_num_1 = int((binary_str[22:32]), 2)
# stride > no of cols, so discarding extra data
if (k > (w-1)):
break
raw[i,k] = np.uint16(binary_num_1)
if (k +1 > (w-1)):
break
raw[i,k+1] = np.uint16(binary_num_2)
if (k + 2 > (w-1)):
break
raw[i,k+2] = np.uint16(binary_num_3)
k = k+3

img = raw.copy()
img = img.astype(np.uint16)

# dumping a .raw file for inf_isp
filename = filename[:-4]
extension = ".raw"
with open('{}{}'.format(filename,extension),'wb') as f:
img.tofile(f)


# dumping a numpy array
img_norm = np.interp(img, (img.min(), img.max()), (0,1023 )).astype(np.uint8)
plt.imshow(img_norm,cmap='gray').write_png('./' + filename + '.png')
plt.show()
Loading

0 comments on commit b32abcc

Please sign in to comment.