diff --git a/README.md b/README.md index 93dbe05..7b9cba8 100644 --- a/README.md +++ b/README.md @@ -65,9 +65,9 @@ Satellite number For temperature calibration Default: "19" --e [c|t] +-e [c|t|h] Enhancements -Contrast (c) or Crop Telemetry (t) +Contrast calibration (c), Histogram equalise (h), Crop Telemetry (t) Defaults: "ct" -c @@ -77,7 +77,7 @@ Default: Internal defaults ## Output -Generated images are outputted in PNG, 8 bit greyscale for raw and channel A|B images, 24 bit RGB for false color. +Generated images are outputted in PNG, 8 bit greyscale for raw and channel A|B images, palleted images for temperature and GVI false color, 24 bit RGB for false color. Image names are `audiofile-x.png`, where `x` is: @@ -87,10 +87,11 @@ Image names are `audiofile-x.png`, where `x` is: - `t` for temperature calibrated images - `l` for layered images -Currently there are 2 available enchancements: +Currently there are 3 available enhancements: - `c` for contrast equalise, on by default - `t` for crop telemetry, on by default, only has effects on raw images + - `h` for histogram equalise, make the darkest color black and the brightest white ## Example diff --git a/dsp.c b/dsp.c index 2924578..90412bb 100755 --- a/dsp.c +++ b/dsp.c @@ -213,7 +213,7 @@ int getpixelrow(float *pixelv) { static float pixels[PixelLine + SyncFilterLen]; static int npv; static int synced = 0; - static double max = 0; + static double max = 0.0; double corr, ecorr, lcorr; int res; diff --git a/fcolor.c b/fcolor.c index ba00dca..358963f 100644 --- a/fcolor.c +++ b/fcolor.c @@ -83,7 +83,7 @@ rgba composite(rgba top, rgba bottom){ void falsecolor(float vis, float temp, float *r, float *g, float *b){ rgba buffer; - fcinfo.Land.a = 0; fcinfo.Sea.a = 0; + fcinfo.Land.a = 0.0f; fcinfo.Sea.a = 0.0f; // Calculate intensity of sea and land fcinfo.Sea.a = CLIP(vis, 0, 20)/fcinfo.Seaintensity + fcinfo.Seaoffset; @@ -91,7 +91,7 @@ void falsecolor(float vis, float temp, float *r, float *g, float *b){ // Composite land on top of sea buffer = composite(fcinfo.Land, fcinfo.Sea); - buffer.a = 1; + buffer.a = 1.0f; // Composite clouds on top fcinfo.Cloud.a = CLIP(temp-fcinfo.Cloudthreshold, 0, fcinfo.Cloudintensity)/fcinfo.Cloudintensity; diff --git a/image.c b/image.c index 9122c63..fd7d0c9 100644 --- a/image.c +++ b/image.c @@ -56,6 +56,33 @@ static double tele[16]; static double Cs; static int nbtele; +void histogramEqualise(float **prow, int nrow, int offset, int width){ + // Plot histogram + int histogram[256] = { 0 }; + for(int y = 0; y < nrow; y++) + for(int x = 0; x < width; x++) + histogram[(int)floor(prow[y][x+offset])]++; + + // Find min/max points + int min = -1, max = -1; + for(int i = 5; i < 250; i++){ + if(histogram[i]/width/(nrow/255.0) > 1.0){ + if(min == -1) min = i; + max = i; + } + } + + //printf("Min Value: %i, Max Value %i\n", min, max); + + // Spread values to avoid overshoot + min -= 5; max += 5; + + // Stretch the brightness into the new range + for(int y = 0; y < nrow; y++) + for(int x = 0; x < width; x++) + prow[y][x+offset] = (prow[y][x+offset]-min) / (max-min) * 255; +} + // Brightness equalise, including telemetry void equalise(float **prow, int nrow, int offset, int width, int telestart, rgparam regr[30]){ offset -= SYNC_WIDTH+SPC_WIDTH; @@ -100,7 +127,7 @@ void equalise(float **prow, int nrow, int offset, int width, int telestart, rgpa // Get telemetry data for thermal calibration/equalization int calibrate(float **prow, int nrow, int offset, int width, int contrastEqualise) { - double teleline[3000]; + double teleline[3000] = { 0.0 }; double wedge[16]; rgparam regr[30]; int n, k; @@ -112,7 +139,6 @@ int calibrate(float **prow, int nrow, int offset, int width, int contrastEqualis float *pixelv = prow[n]; // Average the center 40px - teleline[n] = 0.0; for (int i = 3; i < 43; i++) teleline[n] += pixelv[i + offset + width]; teleline[n] /= 40.0; } @@ -127,7 +153,7 @@ int calibrate(float **prow, int nrow, int offset, int width, int contrastEqualis * difference in brightness, this will always be in the center of * the frame and can thus be used to find the start of the frame */ - float max = 0; + double max = 0.0; for (n = nrow / 3 - 64; n < 2 * nrow / 3 - 64; n++) { float df; diff --git a/main.c b/main.c index c949a8a..a03a448 100644 --- a/main.c +++ b/main.c @@ -177,9 +177,9 @@ static int ImageOut(char *filename, char *chid, float **prow, int nrow, int widt }else if(effects == 3){ // Layered image, overlay clouds in channel B over channel A float cloud = CLIP(pixelv[i+CHB_OFFSET]-141, 0, 255)/114; - pixel[i] = MCOMPOSITE(255, cloud, pixelv[i+CHA_OFFSET], 1); + pixel[i] = MCOMPOSITE(240, cloud, pixelv[i+CHA_OFFSET], 1); }else{ - pixel[i] = pixelv[i + offset + f]; + pixel[i] = CLIP(pixelv[i + offset + f], 0, 255); } } @@ -228,6 +228,7 @@ static void distrib(char *filename, float **prow, int nrow) { } extern int calibrate(float **prow, int nrow, int offset, int width, int contrastEqualise); +extern void histogramEqualise(float **prow, int nrow, int offset, int width); extern void temperature(float **prow, int nrow, int ch, int offset); extern int Ngvi(float **prow, int nrow); extern void readfcconf(char *file); @@ -243,6 +244,7 @@ static void usage(void) { " -e [c|t] Enhancements\n" " c: Contrast equalise\n" " t: Crop telemetry\n" + " h: Histogram equalise\n" " -i [r|a|b|c|t] Output image type\n" " r: Raw\n" " a: Channel A\n" @@ -350,7 +352,6 @@ int main(int argc, char **argv) { if (getpixelrow(prow[nrow]) == 0) break; - printf("Row: %d\r", nrow); fflush(stdout); } @@ -358,9 +359,6 @@ int main(int argc, char **argv) { sf_close(inwav); - // Layered & false color images both need brightness equalization - int contrastEqualise = CONTAINS(enchancements, 'c') || CONTAINS(imgopt, 'l') || CONTAINS(imgopt, 'c'); - chA = calibrate(prow, nrow, CHA_OFFSET, CH_WIDTH, 0); chB = calibrate(prow, nrow, CHB_OFFSET, CH_WIDTH, 0); printf("Channel A: %s (%s)\n", ch.id[chA], ch.name[chA]); @@ -374,9 +372,15 @@ int main(int argc, char **argv) { } // Run the contrast equalise here because the temperature calibration requires raw data - if(contrastEqualise) + // Also layered & false color images both need brightness equalization + if(CONTAINS(enchancements, 'c') || CONTAINS(enchancements, 'h') || CONTAINS(imgopt, 'l') || CONTAINS(imgopt, 'c')) calibrate(prow, nrow, CHA_OFFSET, CH_WIDTH+TELE_WIDTH+SYNC_WIDTH+SPC_WIDTH+CH_WIDTH, 1); + if(CONTAINS(enchancements, 'h')){ + histogramEqualise(prow, nrow, CHA_OFFSET, CH_WIDTH); + histogramEqualise(prow, nrow, CHB_OFFSET, CH_WIDTH); + } + // Layered if (CONTAINS(imgopt, 'l')){ if(chA == 1){