天天看点

ISP最简单步骤,计算得到一个sRGB色域图像

black level correction

linear

shading correction

white balance

CCM

gamma

经过以上步骤可以从raw图得到一个简单的sRGB格式的图片

其中里面的参数需要事先标定好。

ISP最简单步骤,计算得到一个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])