black level correction
linear
shading correction
white balance
CCM
gamma
經過以上步驟可以從raw圖得到一個簡單的sRGB格式的圖檔
其中裡面的參數需要事先标定好。
import colour
from colour_demosaicing import demosaicing_CFA_Bayer_bilinear, demosaicing_CFA_Bayer_Malvar2004, \
demosaicing_CFA_Bayer_Menon2007
'''
1. 對raw圖降噪
2. 目前raw圖存在 比較大的 不合理 的噪聲,需要從根源分析原因和解決
'''
import os
import cv2
import numpy as np
import matplotlib.pyplot as plt
def show_raw(im, r, g, b):
fig = plt.figure()
ax1 = fig.add_subplot(221)
ax1.imshow(im)
ax2 = fig.add_subplot(222)
ax2.imshow(r)
ax3 = fig.add_subplot(223)
ax3.imshow(g)
ax4 = fig.add_subplot(224)
ax4.imshow(b, cmap='gray')
plt.show()
def read_raw(filename, height, width):
# filename = r'D:\MedData\raw圖像\20220511\raw\cap_frame_8977.raw'
file = np.fromfile(filename, dtype=np.int16)
print(len(file))
# BGGR
im = file.reshape([height, width])
return im
def raw_to_rgb(raw):
#
b = raw[0::2, 0::2]
g1 = raw[0::2, 1::2]
g2 = raw[1::2, 0::2]
r = raw[1::2, 1::2]
b = b // 4
r = r // 4
g = (g1 + g2) // 8
rgb = cv2.merge([r, g, b]).astype(np.uint8)
return rgb
def raw_to_rgb_file(filename, height=800, width=1280):
# filename = r'D:\MedData\raw圖像\20220511\raw\cap_frame_8977.raw'
raw = read_raw(filename, height, width)
raw = raw.astype(np.uint16)
rgb = raw_to_rgb(raw)
rgb2 = cv2.medianBlur(rgb, 3)
rgb3 = cv2.medianBlur(rgb, 5)
rgb4 = cv2.medianBlur(rgb, 7)
# plt.figure()
# plt.imshow(rgb)
# plt.show()
show_raw(rgb, rgb2, rgb3, rgb4)
cv2.imwrite(filename[:-4] + '_raw.jpg', rgb[..., ::-1])
# cv2.imwrite(filename[:-4] + '_raw3.jpg', rgb2[...,::-1])
# cv2.imwrite(filename[:-4] + '_raw5.jpg', rgb3[...,::-1])
def black_sub(filename):
raw_image = np.fromfile(filename, dtype=np.uint16)
print(len(raw_image))
raw_image = raw_image.reshape([height, width])
# raw_image =raw_image>>6
print('raw20x20 :\n', raw_image[20:30, 20:30])
# black level
black_level = 16
white_level = 1023
normalized_image = raw_image.astype(np.float32) - black_level
# if some values were smaller than black level
normalized_image[normalized_image < 0] = 0
normalized_image = normalized_image / (white_level - black_level)
print(normalized_image.min(), normalized_image.max())
plt.figure()
plt.imshow(normalized_image)
plt.show()
# demosciac
# rgb = demosaicing_CFA_Bayer_Menon2007(normalized_image, "BGGR")
rgb = demosaicing_CFA_Bayer_bilinear(normalized_image, "BGGR")
rgb_save = rgb * 255
rgb_save = np.clip(rgb_save, 0, 255)
rgb_save = rgb_save.astype(np.uint8)
cv2.imwrite(filename[:-4] + '_raw.png', rgb_save[..., ::-1])
return normalized_image
def convert_input(filename, show_im=0):
h = 800
w = 800
# filename = r'D:\MedData\mydata2\raw\cap_input_frame_0013.rgb'
data = np.fromfile(filename, dtype=np.uint8)
print(len(data))
# print(len(file))
b = data[0::4]
g = data[1::4]
r = data[2::4]
a = data[3::4]
# print(a.dtype, r.dtype, len(a), len(r))
a = np.array(a).reshape([h, w])
r = np.array(r).reshape([h, w])
g = np.array(g).reshape([h, w])
b = np.array(b).reshape([h, w])
# print(a[:10, :10], r[:10, :10], g[:10, :10], b[:10, :10])
rgb = cv2.merge([r, g, b])
if show_im:
plt.figure()
plt.imshow(rgb)
plt.title('rgb')
plt.show()
filepath = filename[:-4] + '_rgb.png'
cv2.imwrite(filepath, rgb[..., ::-1])
return data
def apply_tone_map(x):
# simple tone curve
return 3 * x ** 2 - 2 * x ** 3
if __name__ == "__main__":
height = 800
width = 800
dir = r'D:\dataset\calib\rawdata'
# dir = r'D:\dataset\calib\shading'
dir = r'D:\dataset\calib'
dir = r'D:\dataset\calib\seka'
dir = r'D:\dataset\tmpdata'
dir = r'D:\dataset\wang\ccm'
dir = r'D:\dataset\noise_img'
dir = r'D:\dataset\dang_yingxiangzhiliangceshi\rgb_IMG_vali'
files = os.listdir(dir)
for file in files:
if file.endswith('.raw'):
filename = os.path.join(dir, file)
normalized_image = black_sub(filename)
# if file.endswith('.rgb'):
# filename = os.path.join(dir, file)
# convert_input(filename, show_im=0)
# filename = r'C:\Users\rp\Downloads\RAWimage\A.raw'
# filename = r'D:\dataset\data_gain1_4_shading\cap_frame_06nl.raw'
# filename = r'D:\dataset\data_gain1_5_test\cap_frame_05.raw'
# filename = r'C:\Users\rp\Downloads\RAWimage\D65.raw'
run_pipe_shading = 1
if run_pipe_shading:
# shading biaoding light
# r_gain = np.loadtxt(r'D:\dataset\calib\shading\gains_mean_r.txt', dtype=np.float32)
# g_gain = np.loadtxt(r'D:\dataset\calib\shading\gains_mean_g.txt', dtype=np.float32)
# b_gain = np.loadtxt(r'D:\dataset\calib\shading\gains_mean_b.txt', dtype=np.float32)
r_gain = np.loadtxt(r'D:\dataset\wang\shading\gains_mean_r.txt', dtype=np.float32)
g_gain = np.loadtxt(r'D:\dataset\wang\shading\gains_mean_g.txt', dtype=np.float32)
b_gain = np.loadtxt(r'D:\dataset\wang\shading\gains_mean_b.txt', dtype=np.float32)
# valid_table
table_h = 40
table_w = 40
r_gain = cv2.resize(r_gain, (table_h, table_w), interpolation=cv2.INTER_LINEAR)
g_gain = cv2.resize(g_gain, (table_h, table_w), interpolation=cv2.INTER_LINEAR)
b_gain = cv2.resize(b_gain, (table_h, table_w), interpolation=cv2.INTER_LINEAR)
np.savetxt(r'D:\dataset\calib\shading\gains_mean_r40.txt', r_gain, fmt='%.4f')
np.savetxt(r'D:\dataset\calib\shading\gains_mean_g40.txt', g_gain, fmt='%.4f')
np.savetxt(r'D:\dataset\calib\shading\gains_mean_b40.txt', b_gain, fmt='%.4f')
r_gain = cv2.resize(r_gain, (height//2, width//2), interpolation=cv2.INTER_LINEAR)
g_gain = cv2.resize(g_gain, (height//2, width//2), interpolation=cv2.INTER_LINEAR)
b_gain = cv2.resize(b_gain, (height//2, width//2), interpolation=cv2.INTER_LINEAR)
normalized_image[0::2, 0::2] *= r_gain
normalized_image[1::2, 1::2] *= b_gain
normalized_image[0::2, 1::2] *= g_gain
normalized_image[1::2, 0::2] *= g_gain
rgb = demosaicing_CFA_Bayer_bilinear(normalized_image, "BGGR")
# brigtness_aline = 1
# if brigtness_aline:
# rgb *= 2.7
rgb_save = rgb * 255
rgb_save = np.clip(rgb_save, 0, 255)
rgb_save = rgb_save.astype(np.uint8)
cv2.imwrite(filename[:-4] + '_raw_shading.png', rgb_save[..., ::-1])
#################################################
run_pipe_wb = 1
if run_pipe_wb:
# raw降噪
ksz = 5
print(rgb.shape, rgb.dtype)
rgb = np.clip(rgb, 0, 1).astype(np.float32)
rgb1 = cv2.medianBlur(rgb, ksz)
rgb2 = cv2.bilateralFilter(rgb, ksz, 20, 10)
rgb3 = cv2.fastNlMeansDenoisingColored(rgb_save, None, 4, 5, 7, 20)
rgb3 = rgb3 / 255
rgb3 = rgb3.astype(np.float32)
rgb = rgb1
# # wb
wb_gain_light = np.array([2.02527024, 1., 1.1903776])
wb_gain_indoor = np.array([1.2, 1., 1.2])
wb_gain_d65 = np.array([0.84, 1. , 0.78792666])# 有點奇怪
wb_gain_d65 = np.array([2.0, 1., 1.5])
# wb_gain = wb_gain[1] / wb_gain
wb_gain = wb_gain_d65
rgb_wb = rgb * wb_gain.reshape([1, 1, 3])
rgb_save = rgb_wb * 255
rgb_save = np.clip(rgb_save, 0, 255)
rgb_save = rgb_save.astype(np.uint8)
cv2.imwrite(filename[:-4] + '_raw_wb.png', rgb_save[..., ::-1])
run_pipe_ccm = 1
if run_pipe_ccm:
# ccm
ccm_d65 = np.array([[1.5815986, - 0.10358352, 0.03942539],
[-0.67781997, 1.3813084, - 0.6855073],
[0.09622132, - 0.27772492, 1.6460818]])
ccm_light = np.array([[1.7929738, -0.26765725, -0.08204214],
[-0.7685349, 1.3916172, -0.40990552],
[-0.02443887, -0.12395988, 1.4919477]])
ccm_d65_2 = np.array([[ 1.6988674, -0.2256101 , -0.05143011],
[-0.53877664 , 1.9854064 , -0.8857581 ],
[-0.16009083 ,-0.7597964 ,1.9371881 ]])
ccm_d65_3 = np.array([[ 1.3820341, -0.22968723, -0.07441172],
[-0.2372965 , 1.6849331 , -0.5606966 ],
[-0.1447376 , -0.45524588 , 1.6351084 ]])
ccm = ccm_d65_3
h, w, c = rgb_wb.shape
rgb_ccm = np.reshape(rgb_wb, (-1, 3)) @ ccm
rgb_ccm = rgb_ccm.reshape([h, w, c])
rgb_save = rgb_ccm * 255
rgb_save = np.clip(rgb_save, 0, 255)
rgb_save = rgb_save.astype(np.uint8)
cv2.imwrite(filename[:-4] + '_raw_ccm3.png', rgb_save[..., ::-1])
# gamma
im_gamma = colour.cctf_encoding(rgb_ccm)
rgb_save = im_gamma * 255
rgb_save = np.clip(rgb_save, 0, 255)
rgb_save = rgb_save.astype(np.uint8)
cv2.imwrite(filename[:-4] + '_raw_gamma3.png', rgb_save[..., ::-1])
# tone mapping
im_tone = apply_tone_map(im_gamma)
rgb_save = im_tone * 255
rgb_save = np.clip(rgb_save, 0, 255)
rgb_save = rgb_save.astype(np.uint8)
cv2.imwrite(filename[:-4] + '_raw_tone3.png', rgb_save[..., ::-1])