finish Grey World White Balance
This commit is contained in:
12
sim/Makefile
12
sim/Makefile
@@ -32,6 +32,9 @@ VERILATOR_COVERAGE = $(VERILATOR_ROOT)/bin/verilator_coverage
|
||||
endif
|
||||
|
||||
VERILATOR_FLAGS =
|
||||
# Specify top module
|
||||
TOP_MODULE = isp
|
||||
VERILATOR_FLAGS += --top-module $(TOP_MODULE)
|
||||
# Generate SystemC in executable form
|
||||
VERILATOR_FLAGS += -sc --exe
|
||||
# Generate makefile dependencies (not shown as complicates the Makefile)
|
||||
@@ -52,12 +55,11 @@ VERILATOR_FLAGS += --threads 14
|
||||
#VERILATOR_FLAGS += --debug
|
||||
# Add this trace to get a backtrace in gdb
|
||||
#VERILATOR_FLAGS += --gdbbt
|
||||
# Specify top module
|
||||
TOP_MODULE = isp
|
||||
VERILATOR_FLAGS += -top $(TOP_MODULE)
|
||||
# Input files for Verilator
|
||||
VERILATOR_INPUT = ../isp.sv *.cpp ../Demosaic/Demosaic2.sv ../Crop/*.sv ../Color/*.sv ../RAM/*.sv
|
||||
|
||||
# Input files for Verilator
|
||||
SOURCES := $(wildcard ../isp.sv *.cpp ../Demosaic/Demosaic2.sv ../Crop/*.sv ../Color/*.sv)
|
||||
EXCLUDES := $(wildcard ../Color/WhiteBalance.sv ../Color/GammaCorrection.sv)
|
||||
VERILATOR_INPUT := $(filter-out $(EXCLUDES), $(SOURCES))
|
||||
# Check if SC exists via a verilator call (empty if not)
|
||||
SYSTEMC_EXISTS := $(shell $(VERILATOR) --get-supported SYSTEMC)
|
||||
|
||||
|
||||
272
sim/sc_main.cpp
272
sim/sc_main.cpp
@@ -23,10 +23,11 @@
|
||||
|
||||
static const uint16_t IN_WIDTH = 1936;
|
||||
static const uint16_t IN_HEIGHT = 1088;
|
||||
#define IN_SIZE (IN_WIDTH * IN_HEIGHT)
|
||||
static const uint32_t IN_SIZE = (IN_WIDTH * IN_HEIGHT);
|
||||
static const uint16_t OUT_WIDTH = 1920;
|
||||
static const uint16_t OUT_HEIGHT = 1080;
|
||||
#define OUT_SIZE (OUT_WIDTH * OUT_HEIGHT)
|
||||
static const uint32_t OUT_SIZE = (OUT_WIDTH * OUT_HEIGHT);
|
||||
static const uint32_t FLAMES = 2;
|
||||
|
||||
// color gain for correcting color
|
||||
struct color_gain {
|
||||
@@ -42,6 +43,8 @@ static const double white_radio = 0.1;
|
||||
using namespace sc_core;
|
||||
using namespace sc_dt;
|
||||
|
||||
bool picProcess(uint32_t* image, uint16_t number);
|
||||
|
||||
SC_MODULE(TB_ISP) {
|
||||
sc_in_clk clk;
|
||||
sc_in<bool> reset;
|
||||
@@ -69,9 +72,10 @@ SC_MODULE(TB_ISP) {
|
||||
}
|
||||
|
||||
void send_Data(void) {
|
||||
uint16_t pos_x = 0, pos_y = 0;
|
||||
uint16_t pos_x = 0, pos_y = 0, cnt_flame = 0;
|
||||
bool is_finish = false;
|
||||
while (true) {
|
||||
if (in_ready.read() && pos_y < IN_HEIGHT - 2) {
|
||||
if (in_ready.read() && !is_finish) {
|
||||
out_en.write(1);
|
||||
|
||||
printf("x=%4d, y=%4d, data=0x%04x\t", pos_x, pos_y,
|
||||
@@ -85,13 +89,18 @@ SC_MODULE(TB_ISP) {
|
||||
out_data[1].write(image[(pos_y + 1) * IN_WIDTH + pos_x]);
|
||||
out_data[2].write(image[(pos_y + 2) * IN_WIDTH + pos_x]);
|
||||
|
||||
// wait(1);
|
||||
// out_en.write(0);
|
||||
|
||||
if (++pos_x >= IN_WIDTH) {
|
||||
pos_x++;
|
||||
if (pos_x >= IN_WIDTH) {
|
||||
pos_x = 0;
|
||||
pos_y++;
|
||||
}
|
||||
if (pos_y >= IN_HEIGHT - 2) {
|
||||
pos_y = 0;
|
||||
cnt_flame++;
|
||||
}
|
||||
if (cnt_flame >= FLAMES) {
|
||||
is_finish = true;
|
||||
}
|
||||
} else {
|
||||
out_en.write(0);
|
||||
}
|
||||
@@ -102,11 +111,11 @@ SC_MODULE(TB_ISP) {
|
||||
|
||||
void read_Data(void) {
|
||||
is_done.write(0);
|
||||
uint16_t pos_x = 0, pos_y = 0;
|
||||
uint32_t last_data = 0;
|
||||
uint32_t cnt = 0;
|
||||
uint16_t pos_x = 0, pos_y = 0, cnt_flame = 0;
|
||||
uint32_t last_data = 0, cnt = 0;
|
||||
bool is_finish = false;
|
||||
while (true) {
|
||||
if (im_en.read()) {
|
||||
if (im_en.read() && !is_finish) {
|
||||
out_ready.write(false);
|
||||
out_receceive.write(true);
|
||||
|
||||
@@ -116,13 +125,21 @@ SC_MODULE(TB_ISP) {
|
||||
pos_x = 0;
|
||||
pos_y++;
|
||||
}
|
||||
if (pos_y >= OUT_HEIGHT) {
|
||||
pos_y = 0;
|
||||
picProcess(out.get(), cnt_flame);
|
||||
cnt_flame++;
|
||||
}
|
||||
if (cnt_flame >= FLAMES) {
|
||||
is_finish = true;
|
||||
}
|
||||
} else {
|
||||
out_ready.write(true);
|
||||
out_receceive.write(false);
|
||||
}
|
||||
|
||||
// when data didn't change some time, it end
|
||||
if (last_data == im_data.read()) {
|
||||
if (last_data == im_data.read() && is_finish) {
|
||||
cnt++;
|
||||
if (cnt >= 100000L) {
|
||||
is_done.write(1);
|
||||
@@ -138,13 +155,111 @@ SC_MODULE(TB_ISP) {
|
||||
}
|
||||
};
|
||||
|
||||
bool picProcess(uint32_t* image, uint16_t number) {
|
||||
uint8_t* data =
|
||||
new uint8_t[OUT_WIDTH * OUT_HEIGHT * 3]; // RGB24格式像素数据
|
||||
|
||||
// software algorthms analyze
|
||||
uint32_t red_total = 0, green_total = 0, blue_total = 0;
|
||||
uint8_t red_max = 0, green_max = 0, blue_max = 0;
|
||||
for (int32_t y = 0; y < OUT_HEIGHT; ++y) {
|
||||
for (int32_t x = 0; x < OUT_WIDTH; ++x) {
|
||||
int32_t index = (y * OUT_WIDTH + x) * 3;
|
||||
|
||||
uint8_t red = (image[y * OUT_WIDTH + x] & 0x00ff0000) >> 16;
|
||||
uint8_t green = (image[y * OUT_WIDTH + x] & 0x0000ff00) >> 8;
|
||||
uint8_t blue = (image[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);
|
||||
|
||||
// Calculate white balance data
|
||||
// red_max = std::max(red_max, red);
|
||||
// green_max = std::max(green_max, green);
|
||||
// blue_max = std::max(blue_max, blue);
|
||||
// red_total += red;
|
||||
// green_total += green;
|
||||
// blue_total += blue;
|
||||
|
||||
// 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<uchar>(red + (red - L * 255) * alpha);
|
||||
// green =
|
||||
// static_cast<uchar>(green + (green - L * 255) *
|
||||
// alpha);
|
||||
// blue = static_cast<uchar>(blue + (blue - L * 255) *
|
||||
// alpha);
|
||||
// } else {
|
||||
// alpha = saturation_inc;
|
||||
// red = static_cast<uchar>(L * 255 +
|
||||
// (red - L * 255) * (1 + alpha));
|
||||
// green = static_cast<uchar>(L * 255 +
|
||||
// (green - L * 255) * (1 +
|
||||
// alpha));
|
||||
// blue = static_cast<uchar>(L * 255 +
|
||||
// (blue - L * 255) * (1 +
|
||||
// alpha));
|
||||
// }
|
||||
// }
|
||||
|
||||
// save data
|
||||
data[index + 0] = red; // R
|
||||
data[index + 1] = green; // G
|
||||
data[index + 2] = blue; // B
|
||||
}
|
||||
}
|
||||
|
||||
// Adjust White Balance : Grey World Color Correction
|
||||
// double K = static_cast<double>(red_total + green_total + blue_total) /
|
||||
// (3 * OUT_SIZE);
|
||||
// white_gain.red = static_cast<double>(K * OUT_SIZE) / red_total;
|
||||
// white_gain.green = static_cast<double>(K * OUT_SIZE) / green_total;
|
||||
// white_gain.blue = static_cast<double>(K * OUT_SIZE) / blue_total;
|
||||
// printf("Gain: red = %f, green = %f, blue = %f", white_gain.red,
|
||||
// white_gain.green, white_gain.blue);
|
||||
// for (int32_t y = 0; y < OUT_HEIGHT; ++y) {
|
||||
// for (int32_t x = 0; x < OUT_WIDTH; ++x) {
|
||||
// int32_t index = (y * OUT_WIDTH + x) * 3;
|
||||
|
||||
// data[index + 0] =
|
||||
// static_cast<uint8_t>(white_gain.red * data[index + 0]);
|
||||
// data[index + 1] =
|
||||
// static_cast<uint8_t>(white_gain.green * data[index + 1]);
|
||||
// data[index + 2] =
|
||||
// static_cast<uint8_t>(white_gain.blue * data[index + 2]);
|
||||
// }
|
||||
// }
|
||||
|
||||
// save to bmp
|
||||
std::cout << "Ready to save raw RGB image" << std::endl;
|
||||
char file_name[64] = {0};
|
||||
snprintf(file_name, sizeof(file_name), "pic_%d.bmp", number);
|
||||
write_bmp(file_name, data, OUT_WIDTH, OUT_HEIGHT);
|
||||
delete[] data;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int sc_main(int argc, char* argv[]) {
|
||||
std::cout << "Get into sc_main" << std::endl;
|
||||
// Open image
|
||||
std::ifstream in_image;
|
||||
std::ofstream out_image;
|
||||
in_image.open("./transform/test.bin", std::ios::in | std::ios::binary);
|
||||
// out_image.open("./transform/out.bin", std::ios::out | std::ios::binary);
|
||||
if (!in_image.is_open()) {
|
||||
std::cout << "Open image fail" << std::endl;
|
||||
exit(0);
|
||||
@@ -218,6 +333,10 @@ int sc_main(int argc, char* argv[]) {
|
||||
sc_signal<uint32_t> gamma_inverse;
|
||||
sc_signal<uint32_t> gamma_table[256];
|
||||
|
||||
sc_signal<uint32_t> white_gain[3];
|
||||
sc_signal<uint32_t> flame_rate;
|
||||
sc_signal<bool> white_enable;
|
||||
|
||||
sc_signal<bool> saturation_enable;
|
||||
sc_signal<uint32_t> saturation_increase;
|
||||
|
||||
@@ -250,6 +369,12 @@ int sc_main(int argc, char* argv[]) {
|
||||
isp->gamma_enable(gamma_enable);
|
||||
// isp->gamma_inverse(gamma_inverse);
|
||||
|
||||
isp->white_enable(white_enable);
|
||||
isp->flame_rate(flame_rate);
|
||||
isp->white_gain[0](white_gain[0]);
|
||||
isp->white_gain[1](white_gain[1]);
|
||||
isp->white_gain[2](white_gain[2]);
|
||||
|
||||
isp->saturation_enable(saturation_enable);
|
||||
isp->saturation_inc(saturation_increase);
|
||||
|
||||
@@ -266,6 +391,12 @@ int sc_main(int argc, char* argv[]) {
|
||||
gamma_table[i] = (uint32_t)(255 * pow(i / 255.0, 1.0 / gamma_value));
|
||||
}
|
||||
|
||||
white_enable = true;
|
||||
flame_rate = 0;
|
||||
white_gain[0] = 255;
|
||||
white_gain[1] = 255;
|
||||
white_gain[2] = 255;
|
||||
|
||||
saturation_enable = true;
|
||||
saturation_increase =
|
||||
(int32_t)((saturation_inc >= 0) ? (saturation_inc * std::pow(2, 8))
|
||||
@@ -333,117 +464,6 @@ int sc_main(int argc, char* argv[]) {
|
||||
tfp = nullptr;
|
||||
}
|
||||
|
||||
uint8_t* data =
|
||||
new uint8_t[OUT_WIDTH * OUT_HEIGHT * 3]; // RGB24格式像素数据
|
||||
|
||||
// software algorthms analyze
|
||||
uint32_t red_total = 0, green_total = 0, blue_total = 0;
|
||||
uint8_t red_max = 0, green_max = 0, blue_max = 0;
|
||||
for (int32_t y = 0; y < OUT_HEIGHT; ++y) {
|
||||
for (int32_t x = 0; x < OUT_WIDTH; ++x) {
|
||||
int32_t index = (y * OUT_WIDTH + x) * 3;
|
||||
|
||||
uint8_t red = (tb_isp.out[y * OUT_WIDTH + x] & 0x00ff0000) >> 16;
|
||||
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);
|
||||
|
||||
// Calculate white balance data
|
||||
red_max = std::max(red_max, red);
|
||||
green_max = std::max(green_max, green);
|
||||
blue_max = std::max(blue_max, blue);
|
||||
red_total += red;
|
||||
green_total += green;
|
||||
blue_total += blue;
|
||||
|
||||
// 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<uchar>(red + (red - L * 255) * alpha);
|
||||
// green =
|
||||
// static_cast<uchar>(green + (green - L * 255) *
|
||||
// alpha);
|
||||
// blue = static_cast<uchar>(blue + (blue - L * 255) *
|
||||
// alpha);
|
||||
// } else {
|
||||
// alpha = saturation_inc;
|
||||
// red = static_cast<uchar>(L * 255 +
|
||||
// (red - L * 255) * (1 + alpha));
|
||||
// green = static_cast<uchar>(L * 255 +
|
||||
// (green - L * 255) * (1 +
|
||||
// alpha));
|
||||
// blue = static_cast<uchar>(L * 255 +
|
||||
// (blue - L * 255) * (1 +
|
||||
// alpha));
|
||||
// }
|
||||
// }
|
||||
|
||||
data[index + 0] = red; // R
|
||||
data[index + 1] = green; // G
|
||||
data[index + 2] = blue; // B
|
||||
}
|
||||
}
|
||||
|
||||
// Adjust White Balance : Grey World Color Correction
|
||||
double K = static_cast<double>(red_total + green_total + blue_total) / (3 * OUT_SIZE);
|
||||
white_gain.red = static_cast<double>(K * OUT_SIZE) / red_total;
|
||||
white_gain.green = static_cast<double>(K * OUT_SIZE) / green_total;
|
||||
white_gain.blue = static_cast<double>(K * OUT_SIZE) / blue_total;
|
||||
printf("Gain: red = %f, green = %f, blue = %f", white_gain.red,
|
||||
white_gain.green, white_gain.blue);
|
||||
for (int32_t y = 0; y < OUT_HEIGHT; ++y) {
|
||||
for (int32_t x = 0; x < OUT_WIDTH; ++x) {
|
||||
int32_t index = (y * OUT_WIDTH + x) * 3;
|
||||
|
||||
data[index + 0] =
|
||||
static_cast<uint8_t>(white_gain.red * data[index + 0]);
|
||||
data[index + 1] =
|
||||
static_cast<uint8_t>(white_gain.green * data[index + 1]);
|
||||
data[index + 2] =
|
||||
static_cast<uint8_t>(white_gain.blue * data[index + 2]);
|
||||
}
|
||||
}
|
||||
|
||||
// save to bin
|
||||
std::cout << "Ready to save raw RGB image" << std::endl;
|
||||
// for (int32_t y = 0; y < OUT_HEIGHT; ++y) {
|
||||
// for (int32_t x = 0; x < OUT_WIDTH; ++x) {
|
||||
// int32_t index = (y * OUT_WIDTH + x) * 3;
|
||||
|
||||
// uint8_t red = data[index + 0];
|
||||
// uint8_t green = data[index + 1];
|
||||
// uint8_t blue = data[index + 2];
|
||||
|
||||
// out_image.write((const char*)&red, sizeof(red));
|
||||
// out_image.write((const char*)&green, sizeof(green));
|
||||
// out_image.write((const char*)&blue, sizeof(blue));
|
||||
|
||||
// printf("x=%4d, y=%4d, red=0x%02x, green=0x%02x, blue=0x%02x\n",
|
||||
// x,
|
||||
// y, red, green, blue);
|
||||
// }
|
||||
// }
|
||||
|
||||
// save to bmp
|
||||
write_bmp("test.bmp", data, OUT_WIDTH, OUT_HEIGHT);
|
||||
delete[] data;
|
||||
|
||||
// Return good completion status
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user