Browse Source

Add histogram equalisation

Also made some floating-point math more explicit
tags/v1.8.0
Xerbo 4 years ago
parent
commit
e5dddaeb11
5 changed files with 48 additions and 17 deletions
  1. +5
    -4
      README.md
  2. +1
    -1
      dsp.c
  3. +2
    -2
      fcolor.c
  4. +29
    -3
      image.c
  5. +11
    -7
      main.c

+ 5
- 4
README.md View File

@@ -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 <file>
@@ -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



+ 1
- 1
dsp.c View File

@@ -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;


+ 2
- 2
fcolor.c View File

@@ -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;


+ 29
- 3
image.c View File

@@ -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;



+ 11
- 7
main.c View File

@@ -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){


Loading…
Cancel
Save