@@ -39,7 +39,7 @@ To manually set the output filename | |||||
Decode all WAV files in the current directory and put them in `images` | Decode all WAV files in the current directory and put them in `images` | ||||
```sh | ```sh | ||||
./aptdec -d images *.wav | |||||
mkdir images && ./aptdec -d images *.wav | |||||
``` | ``` | ||||
Apply a denoise filter (see [Post-Processing Effects](#post-processing-effects) for a full list of post-processing effects) | Apply a denoise filter (see [Post-Processing Effects](#post-processing-effects) for a full list of post-processing effects) | ||||
@@ -90,6 +90,7 @@ Apply a falsecolor palette | |||||
- `d`: Denoise | - `d`: Denoise | ||||
- `p`: Precipitation overlay | - `p`: Precipitation overlay | ||||
- `f`: Flip image (for southbound passes) | - `f`: Flip image (for southbound passes) | ||||
- `c`: Crop noise from ends of image | |||||
## Realtime decoding | ## Realtime decoding | ||||
@@ -116,4 +117,4 @@ Environmental Satellite Receiving Stations](https://noaasis.noaa.gov/NOAASIS/pub | |||||
## License | ## License | ||||
See `LICENSE` | |||||
See `LICENSE` |
@@ -32,7 +32,7 @@ typedef struct { | |||||
typedef struct { | typedef struct { | ||||
float *prow[MAX_HEIGHT]; // Row buffers | float *prow[MAX_HEIGHT]; // Row buffers | ||||
int nrow; // Number of rows | int nrow; // Number of rows | ||||
int zenith; | |||||
int zenith; // Row in image where satellite reaches peak elevation | |||||
int chA, chB; // ID of each channel | int chA, chB; // ID of each channel | ||||
char name[256]; // Stripped filename | char name[256]; // Stripped filename | ||||
char *palette; // Filename of palette | char *palette; // Filename of palette | ||||
@@ -64,5 +64,6 @@ enum effects { | |||||
Denoise='d', | Denoise='d', | ||||
Precipitation_Overlay='p', | Precipitation_Overlay='p', | ||||
Flip_Image='f', | Flip_Image='f', | ||||
Linear_Equalise='l' | |||||
}; | |||||
Linear_Equalise='l', | |||||
Crop_Noise='c' | |||||
}; |
@@ -318,6 +318,54 @@ void flipImage(image_t *img, int width, int offset){ | |||||
} | } | ||||
} | } | ||||
// Calculate crop to reomve noise from the start and end of an image | |||||
void cropNoise(image_t *img){ | |||||
#define NOISE_THRESH 150.0 | |||||
// Average value of minute marker | |||||
float spc_rows[MAX_HEIGHT] = { 0.0 }; | |||||
int startCrop = 0; int endCrop = img->nrow; | |||||
for(int y = 0; y < img->nrow; y++) { | |||||
for(int x = 0; x < SPC_WIDTH; x++) { | |||||
spc_rows[y] += img->prow[y][x + (CHB_OFFSET - SPC_WIDTH)]; | |||||
} | |||||
spc_rows[y] /= SPC_WIDTH; | |||||
// Skip minute markings | |||||
if(spc_rows[y] < 10) { | |||||
spc_rows[y] = spc_rows[y-1]; | |||||
} | |||||
} | |||||
// 3 row average | |||||
for(int y = 0; y < img->nrow; y++){ | |||||
spc_rows[y] = (spc_rows[y+1] + spc_rows[y+2] + spc_rows[y+3])/3; | |||||
//img.prow[y][0] = spc_rows[y]; | |||||
} | |||||
// Find ends | |||||
for(int y = 0; y < img->nrow-1; y++) { | |||||
if(spc_rows[y] > NOISE_THRESH){ | |||||
endCrop = y; | |||||
} | |||||
} | |||||
for(int y = img->nrow; y > 0; y--) { | |||||
if(spc_rows[y] > NOISE_THRESH) { | |||||
startCrop = y; | |||||
} | |||||
} | |||||
//printf("Crop rows: %i -> %i\n", startCrop, endCrop); | |||||
// Remove the noisy rows at start | |||||
for(int y = 0; y < img->nrow-startCrop; y++) { | |||||
memmove(img->prow[y], img->prow[y+startCrop], sizeof(float)*2150); | |||||
} | |||||
// Ignore the noisy rows at the end | |||||
img->nrow = (endCrop - startCrop); | |||||
} | |||||
// --- Temperature Calibration --- // | // --- Temperature Calibration --- // | ||||
#include "satcal.h" | #include "satcal.h" | ||||
@@ -49,6 +49,7 @@ extern void temperature(options_t *opts, image_t *img, int offset, int width); | |||||
extern void denoise(float **prow, int nrow, int offset, int width); | extern void denoise(float **prow, int nrow, int offset, int width); | ||||
extern void distrib(options_t *opts, image_t *img, char chid); | extern void distrib(options_t *opts, image_t *img, char chid); | ||||
extern void flipImage(image_t *img, int width, int offset); | extern void flipImage(image_t *img, int width, int offset); | ||||
extern void cropNoise(image_t *img); | |||||
// Palettes | // Palettes | ||||
extern char GviPalette[256*3]; | extern char GviPalette[256*3]; | ||||
@@ -144,7 +145,7 @@ static int processAudio(char *filename, options_t *opts){ | |||||
char path[256], extension[32]; | char path[256], extension[32]; | ||||
strcpy(path, filename); | strcpy(path, filename); | ||||
strcpy(path, dirname(path)); | strcpy(path, dirname(path)); | ||||
sscanf(basename(filename), "%[^.].%s", img.name, extension); | |||||
sscanf(basename(filename), "%255[^.].%31s", img.name, extension); | |||||
if(opts->realtime){ | if(opts->realtime){ | ||||
// Set output filename to current time when in realtime mode | // Set output filename to current time when in realtime mode | ||||
@@ -205,6 +206,11 @@ static int processAudio(char *filename, options_t *opts){ | |||||
printf("Channel A: %s (%s)\n", ch.id[img.chA], ch.name[img.chA]); | printf("Channel A: %s (%s)\n", ch.id[img.chA], ch.name[img.chA]); | ||||
printf("Channel B: %s (%s)\n", ch.id[img.chB], ch.name[img.chB]); | printf("Channel B: %s (%s)\n", ch.id[img.chB], ch.name[img.chB]); | ||||
// Crop noise from start and end of image | |||||
if(CONTAINS(opts->effects, Crop_Noise)){ | |||||
cropNoise(&img); | |||||
} | |||||
// Denoise | // Denoise | ||||
if(CONTAINS(opts->effects, Denoise)){ | if(CONTAINS(opts->effects, Denoise)){ | ||||
denoise(img.prow, img.nrow, CHA_OFFSET, CH_WIDTH); | denoise(img.prow, img.nrow, CHA_OFFSET, CH_WIDTH); | ||||
@@ -318,7 +324,7 @@ static void usage(void) { | |||||
fprintf(stderr, | fprintf(stderr, | ||||
"Aptdec [options] audio files ...\n" | "Aptdec [options] audio files ...\n" | ||||
"Options:\n" | "Options:\n" | ||||
" -i [r|a|b|t|m|p] Output image\n" | |||||
" -i [r|a|b|t|m|p] Output image\n" | |||||
" r: Raw\n" | " r: Raw\n" | ||||
" a: Channel A\n" | " a: Channel A\n" | ||||
" b: Channel B\n" | " b: Channel B\n" | ||||
@@ -332,11 +338,12 @@ static void usage(void) { | |||||
" p: Precipitation\n" | " p: Precipitation\n" | ||||
" f: Flip image\n" | " f: Flip image\n" | ||||
" l: Linear equalise\n" | " l: Linear equalise\n" | ||||
" -o <path> Output filename\n" | |||||
" c: Crop noise\n" | |||||
" -o <path> Output filename\n" | |||||
" -d <path> Image destination directory.\n" | " -d <path> Image destination directory.\n" | ||||
" -s [15-19] Satellite number\n" | " -s [15-19] Satellite number\n" | ||||
" -m <path> Map file\n" | " -m <path> Map file\n" | ||||
" -p <path> Path to palette\n" | |||||
" -p <path> Path to palette\n" | |||||
" -r Realtime decode\n" | " -r Realtime decode\n" | ||||
" -g Gamma adjustment (1.0 = off)\n" | " -g Gamma adjustment (1.0 = off)\n" | ||||
"\nRefer to the README for more infomation\n"); | "\nRefer to the README for more infomation\n"); | ||||
@@ -350,12 +350,13 @@ int ImageOut(options_t *opts, image_t *img, int offset, int width, char *desc, c | |||||
case Denoise: break; | case Denoise: break; | ||||
case Histogram_Equalise: break; | case Histogram_Equalise: break; | ||||
case Linear_Equalise: break; | case Linear_Equalise: break; | ||||
case Crop_Noise: break; | |||||
default: | default: | ||||
fprintf(stderr, "NOTICE: Unrecognised effect, \"%c\"\n", opts->effects[i]); | fprintf(stderr, "NOTICE: Unrecognised effect, \"%c\"\n", opts->effects[i]); | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
if(opts->map != NULL && opts->map[0] != '\0'){ | if(opts->map != NULL && opts->map[0] != '\0'){ | ||||
greyscale = 0; | greyscale = 0; | ||||
} | } | ||||