mirror of
https://github.com/openmv/openmv.git
synced 2025-11-04 14:49:50 +08:00
ports/alif: Add gamma correction to PAG7936 video.
Gamma correction massively improves the PAG7936 image quality by increasing the image brightness. Brightness and contrast adjustment support is also exposed for future automatic control.
This commit is contained in:
parent
4745e2999e
commit
0307402a57
@ -559,6 +559,10 @@ static inline v128_t vdebayer_to_cr(vrgb_pixels_t pixels) {
|
||||
return pixels.r;
|
||||
}
|
||||
|
||||
// FIXME: This needs to be placed in the DTCM. .bss is in the DTCM on Alif. But, this is not portable.
|
||||
// Move this to a proper DTCM section for other platforms.
|
||||
static uint8_t gamma_lut[256];
|
||||
|
||||
// In the case of vectors larger than 32-bits the pattern is repeated for every 32-bits.
|
||||
//
|
||||
// pixels.r = MSB [0, R1, 0, R0] LSB pixels where each pixel is 8-bits.
|
||||
@ -569,6 +573,9 @@ static inline v128_t vdebayer_to_cr(vrgb_pixels_t pixels) {
|
||||
static inline vrgb_pixels_t vdebayer_apply_rb_gain(vrgb_pixels_t pixels, uint32_t red_gain, uint32_t blue_gain) {
|
||||
pixels.r = vusat_s16_narrow_u8_lo(pixels.r, vmul_n_u32(pixels.r, red_gain), 5);
|
||||
pixels.b = vusat_s16_narrow_u8_lo(pixels.b, vmul_n_u32(pixels.b, blue_gain), 5);
|
||||
pixels.r = vldr_u8_gather(gamma_lut, pixels.r);
|
||||
pixels.g = vldr_u8_gather(gamma_lut, pixels.g);
|
||||
pixels.b = vldr_u8_gather(gamma_lut, pixels.b);
|
||||
return pixels;
|
||||
}
|
||||
|
||||
@ -2291,13 +2298,19 @@ static void vdebayer_rggb_to_rgb565_awb_quarter(image_t *src, image_t *dst, uint
|
||||
// GRAYSCALE: src->data == dst->data
|
||||
// RGB565: src->data == dst->data + image_size(src)
|
||||
// YUV422: Not supported
|
||||
void imlib_debayer_image_awb(image_t *dst, image_t *src, bool fast, uint32_t r_out, uint32_t g_out, uint32_t b_out) {
|
||||
void imlib_debayer_image_awb(image_t *dst, image_t *src, bool fast, uint32_t r_out, uint32_t g_out, uint32_t b_out,
|
||||
float brightness, float contrast, float gamma) {
|
||||
uint32_t red_gain = IM_DIV(g_out * 32, r_out);
|
||||
red_gain = IM_MIN(red_gain, 128U);
|
||||
|
||||
uint32_t blue_gain = IM_DIV(g_out * 32, b_out);
|
||||
blue_gain = IM_MIN(blue_gain, 128U);
|
||||
|
||||
for (int i = 0; i < 256; i++) {
|
||||
int v = fast_roundf(((fast_powf(i * (1.0f / 255.0f), gamma) * contrast) + brightness) * 255.0f);
|
||||
gamma_lut[i] = IM_CLAMP(v, 0, 255);
|
||||
}
|
||||
|
||||
if (fast) {
|
||||
switch (src->pixfmt) {
|
||||
case PIXFORMAT_BAYER_BGGR: {
|
||||
|
||||
@ -1207,7 +1207,8 @@ pixformat_t imlib_bayer_shift(pixformat_t pixfmt, int x, int y, bool transpose);
|
||||
void imlib_debayer_ycbcr(image_t *src, rectangle_t *roi, int8_t *Y0, int8_t *CB, int8_t *CR);
|
||||
void imlib_debayer_line(int x_start, int x_end, int y_row, void *dst_row_ptr, pixformat_t pixfmt, image_t *src);
|
||||
void imlib_debayer_image(image_t *dst, image_t *src);
|
||||
void imlib_debayer_image_awb(image_t *dst, image_t *src, bool fast, uint32_t r_out, uint32_t g_out, uint32_t b_out);
|
||||
void imlib_debayer_image_awb(image_t *dst, image_t *src, bool fast, uint32_t r_out, uint32_t g_out, uint32_t b_out,
|
||||
float brightness, float contrast, float gamma);
|
||||
|
||||
// YUV Image Processing
|
||||
pixformat_t imlib_yuv_shift(pixformat_t pixfmt, int x);
|
||||
|
||||
@ -1514,6 +1514,19 @@ static inline v128_t vldr_u8_pred(const uint8_t *p, v128_predicate_t pred) {
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline v128_t vldr_u8_gather(const uint8_t *p, v128_t offsets) {
|
||||
#if (__ARM_ARCH >= 8)
|
||||
return (v128_t) vldrbq_gather_offset(p, offsets.u8);
|
||||
#else
|
||||
v128_t v0;
|
||||
v0.u8[0] = *(p + offsets.u8[0]);
|
||||
v0.u8[1] = *(p + offsets.u8[1]);
|
||||
v0.u8[2] = *(p + offsets.u8[2]);
|
||||
v0.u8[3] = *(p + offsets.u8[3]);
|
||||
return v0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline v128_t vldr_u8_widen_u32_gather_pred(const uint8_t *p,
|
||||
v128_t offsets,
|
||||
v128_predicate_t pred) {
|
||||
|
||||
@ -404,7 +404,7 @@ int alif_csi_snapshot(omv_csi_t *csi, image_t *dst_image, uint32_t flags) {
|
||||
}
|
||||
|
||||
// Debayer frame.
|
||||
imlib_debayer_image_awb(dst_image, &src_image, false, r_stat, g_stat, b_stat);
|
||||
imlib_debayer_image_awb(dst_image, &src_image, false, r_stat, g_stat, b_stat, 0.0f, 1.0f, 0.5f);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user