From 7833c3a7b5810b693d9d0ecdbbfe911b943da179 Mon Sep 17 00:00:00 2001 From: SikongJueluo Date: Sat, 29 Jun 2024 21:31:58 +0800 Subject: [PATCH] just make a little part of saturation correction --- Color/SaturationCorrection.v | 97 ++++++++++++++++++++++++++++++++++++ Demosaic/Demosaic2.v | 16 +++--- sim/sc_main.cpp | 38 +++++++++++++- 3 files changed, 142 insertions(+), 9 deletions(-) create mode 100644 Color/SaturationCorrection.v diff --git a/Color/SaturationCorrection.v b/Color/SaturationCorrection.v new file mode 100644 index 0000000..26992ff --- /dev/null +++ b/Color/SaturationCorrection.v @@ -0,0 +1,97 @@ +`timescale 1ns / 1ps + +module SaturationCorrection #( + parameter reg [4:0] COLOR_DEPTH = 8 +) ( + input wire clk, + input wire reset, + + input wire in_en, + input wire [COLOR_DEPTH - 1 : 0] in_data[3], + output wire out_ready, + output wire out_receive, + + output reg out_en, + output reg [COLOR_DEPTH - 1 : 0] out_data[3], + input wire in_ready, + input wire in_receive, + + input wire enable, + input wire [8:0] saturation_inc +); + reg [2:0] state, nextState; + localparam reg [2:0] READ_DATA = 0; + localparam reg [2:0] CALC_DATA = 1; + localparam reg [2:0] SEND_DATA = 2; + + reg [15:0] data_cal[3]; + + always @(posedge clk or posedge reset) begin + if (reset) state <= READ_DATA; + else state <= nextState; + end + + always @(*) begin + case (state) + READ_DATA: nextState = in_en ? CALC_DATA : READ_DATA; + CALC_DATA: nextState = SEND_DATA; + SEND_DATA: nextState = in_receive ? READ_DATA : SEND_DATA; + default: nextState = READ_DATA; + endcase + end + + assign out_ready = (!in_en && state == READ_DATA) ? 1 : 0; + assign out_receive = (in_en && state == READ_DATA) ? 1 : 0; + + assign max = data_cal[0] > data_cal[1]? + (data_cal[0] > data_cal[2] ? data_cal[0] : data_cal[2]): + (data_cal[1] > data_cal[2] ? data_cal[1] : data_cal[2]); + assign min = data_cal[0] < data_cal[1]? + (data_cal[0] < data_cal[2] ? data_cal[0] : data_cal[2]): + (data_cal[1] < data_cal[2] ? data_cal[1] : data_cal[2]); + assign delta = max - min; + assign value = max + min; + assign light = value >> 1; + assign saturation = (delta << 8) / max; + + + + + always @(posedge clk or posedge reset) begin + if (reset) begin + out_en <= 0; + out_data[0] <= 0; + out_data[1] <= 0; + out_data[2] <= 0; + + data_cal[0] <= 0; + data_cal[1] <= 0; + data_cal[2] <= 0; + end else begin + case (state) + READ_DATA: begin + if (in_en) begin + + end + end + + CALC_DATA: begin + if (enable) begin + + end + end + + SEND_DATA: begin + if (in_ready) begin + out_en <= 1; + + end else out_en <= 0; + end + + default: ; + endcase + end + end + + +endmodule diff --git a/Demosaic/Demosaic2.v b/Demosaic/Demosaic2.v index a91da53..3a35fc5 100644 --- a/Demosaic/Demosaic2.v +++ b/Demosaic/Demosaic2.v @@ -99,27 +99,27 @@ module Demosaic2 #( // 2 5 8 G R G R G R B G B G B G case (raw_type) 0: begin // Missing B, R on G - blue <= (data_cache[1] + data_cache[7]) / 2; - red <= (data_cache[3] + data_cache[5]) / 2; + blue <= (data_cache[1] + data_cache[7]) >> 1; + red <= (data_cache[3] + data_cache[5]) >> 1; green <= data_cache[4]; end 1: begin // Missing G, R on B - green <= (data_cache[1] + data_cache[3] + data_cache[5] + data_cache[7]) / 4; - red <= (data_cache[0] + data_cache[2] + data_cache[6] + data_cache[8]) / 4; + green <= (data_cache[1] + data_cache[3] + data_cache[5] + data_cache[7]) >> 2; + red <= (data_cache[0] + data_cache[2] + data_cache[6] + data_cache[8]) >> 2; blue <= data_cache[4]; end 2: begin // Missing G, B on R - green <= (data_cache[1] + data_cache[3] + data_cache[5] + data_cache[7]) / 4; - blue <= (data_cache[0] + data_cache[2] + data_cache[6] + data_cache[8]) / 4; + green <= (data_cache[1] + data_cache[3] + data_cache[5] + data_cache[7]) >> 2; + blue <= (data_cache[0] + data_cache[2] + data_cache[6] + data_cache[8]) >> 2; red <= data_cache[4]; end 3: begin // Missing B, R on G - red <= (data_cache[1] + data_cache[7]) / 2; - blue <= (data_cache[3] + data_cache[5]) / 2; + red <= (data_cache[1] + data_cache[7]) >> 1; + blue <= (data_cache[3] + data_cache[5]) >> 1; green <= data_cache[4]; end default: ; diff --git a/sim/sc_main.cpp b/sim/sc_main.cpp index ac763a5..d645fc0 100644 --- a/sim/sc_main.cpp +++ b/sim/sc_main.cpp @@ -33,9 +33,10 @@ struct color_gain { double red; double green; double blue; -} color_gain{1.3, 0.8, 1.3}; +} color_gain{1.1, 0.7, 1.3}; static const double gamma_value = 2.2; +static const double saturation_inc = -0.5; using namespace sc_core; using namespace sc_dt; @@ -253,6 +254,7 @@ int sc_main(int argc, char* argv[]) { gamma_enable = true; gamma_inverse = (uint32_t)((1.0 / gamma_value) * std::pow(2, 8)); for (int i = 0; i < 256; i++) { + // calculate gamma table isp->gamma_table[i](gamma_table[i]); gamma_table[i] = (uint32_t)(255 * pow(i / 255.0, 1.0 / gamma_value)); } @@ -338,10 +340,44 @@ int sc_main(int argc, char* argv[]) { uint8_t green = (tb_isp.out[y * OUT_WIDTH + x] & 0x0000ff00) >> 8; uint8_t blue = (tb_isp.out[y * OUT_WIDTH + x] & 0x000000ff); + // Adjust gamma line // red = 255 * std::pow(red / 255.0, 1 / gamma_value); // green = 255 * std::pow(green / 255.0, 1 / gamma_value); // blue = 255 * std::pow(blue / 255.0, 1 / gamma_value); + // Adjust white balance + + // Adjust vibrance + uint8_t max = std::max({red, green, blue}); + uint8_t min = std::min({red, green, blue}); + double delta = (max - min) / 255.0; + double value = (max + min) / 255.0; + if (delta != 0) { + double L = value / 2.0; + // double S = (L <= 0.5) ? delta / value : delta / (2 - value); + double S = delta / max; + double alpha = 0.0; + if (saturation_inc >= 0) { + if ((saturation_inc + S) >= 1) + alpha = S; + else + alpha = 1 - saturation_inc; + alpha = 1 / alpha - 1; + red = static_cast(red + (red - L * 255) * alpha); + green = + static_cast(green + (green - L * 255) * alpha); + blue = static_cast(blue + (blue - L * 255) * alpha); + } else { + alpha = saturation_inc; + red = static_cast(L * 255 + + (red - L * 255) * (1 + alpha)); + green = static_cast(L * 255 + + (green - L * 255) * (1 + alpha)); + blue = static_cast(L * 255 + + (blue - L * 255) * (1 + alpha)); + } + } + out_image.write((const char*)&red, sizeof(red)); out_image.write((const char*)&green, sizeof(green)); out_image.write((const char*)&blue, sizeof(blue));