@@ -1,17 +1,18 @@ | |||
INCLUDES=-I. | |||
CFLAGS= -O4 $(INCLUDES) | |||
CFLAGS= -O3 $(INCLUDES) | |||
OBJS= main.o image.o dsp.o filter.o | |||
OBJS= main.o image.o dsp.o filter.o reg.o fcolor.o | |||
atpdec: $(OBJS) | |||
$(CC) -o $@ $(OBJS) -lm -lsndfile -lpng | |||
main.o: main.c cmap.h | |||
main.o: main.c | |||
dsp.o: dsp.c filtercoeff.h filter.h | |||
filter.o: filter.c filter.h | |||
image.o: image.c satcal.h | |||
fcolor.o : fcolor.c | |||
clean: | |||
rm -f *.o atpdec |
@@ -22,10 +22,10 @@ and synchro pulses. | |||
3. Calibrated channel B image | |||
4. Temperature compensed I.R image | |||
5. False color image | |||
6. pixel distribution statistique (usefull for false color cmap debugging). | |||
6. pixel distribution statistique (usefull for false color parameter debugging). | |||
Input soundfiles must be mono signal sampled at 11025 Hz. | |||
Atpdec use libsnd to read soundfile, so any sound file format supported by libsnd | |||
Atpdec use libsndfile to read soundfile, so any sound file format supported by libsndfile | |||
could be read.(Only tested with .wav file). | |||
COMPILATION | |||
@@ -40,4 +40,46 @@ If they are not on standard path, edit the include path in the Makefile. | |||
USAGE | |||
see atpdec.1 man page. | |||
atpdec [options] soundfiles ... | |||
OPTIONS | |||
-i [r|a|b|c|t|d] | |||
Toggle raw (r) , channel A (a) , channel B (b) , false color (c) , | |||
temperature (t) or pixel distrubution (d) output. | |||
Default : "ac" | |||
-d directory | |||
Optional images destination directory. | |||
Default : soundfile directory. | |||
-s n | |||
Satellite ident : n=0 :NOOA-15 n=1 :NOAA-17 | |||
Used for Temperature compensation. | |||
Default : NOAA17 | |||
-c conf_file | |||
Use configuration file for false color generation. | |||
Default : Internal parameters. | |||
-p 8|16 | |||
Output 16bits grayscale image for channel A|B and raw images. | |||
Default : 8bits images. | |||
OUTPUT | |||
Generated image are in png format, 16 or 8bits greyscale for raw and channel A|B images, | |||
24bits RVB for false color. | |||
Image names are soundfilename-x.png, where x is : | |||
-r for raw images | |||
-satellite instrument number (1,2,3A,3B,4,5) for channel A|B images | |||
-c for false colors. | |||
-d for pixel distribution stats. | |||
EXAMPLE | |||
atpdec -d image -i ac *.wav | |||
Will process all .wav files in the current directory, generate only channel A and false color images and put them in the image directory. | |||
@@ -1,80 +0,0 @@ | |||
.TH ATPDEC 1 "Atpdec ATP satellite image decoder" | |||
.SH NAME | |||
atpdec | |||
.SH OVERVIEW | |||
atpdec is a decoder for NOAA POES weather satellite images. | |||
It takes soundfiles recorded from a dedicated receiver and convert them into .png images. | |||
.SH SYNOPSIS | |||
.B atpdec | |||
.I "[options]" soundfiles ... | |||
.SH OPTIONS | |||
.TP | |||
.br | |||
.B \-c file.png | |||
Use a private colormap for false color generation. Default : Internal colormap. | |||
.TP | |||
.br | |||
.B \-i [r|a|b|c|t|d] | |||
Toggle raw (r) , channel A (a) , channel B (b) , false color (c) , temperatue (t) or pixel distrubution (d) output. | |||
Default : "ac" | |||
.TP | |||
.br | |||
.B \-d directory | |||
Optional images destination directory. Default : soundfile directory. | |||
.TP | |||
.br | |||
.B \-p | |||
Output 16bits grayscale image for channel A|B and raw images. Default : 8bits images. | |||
.TP | |||
.br | |||
.B \-s n | |||
Satellite ident : n=0 :NOOA-15 n=1 :NOAA-17 (used by Temperature compensation step).Default : NOAA17 | |||
Generated image are in png format, 16 or 8bits greyscale for raw and channel A|B images, | |||
24bits RVB for false color. | |||
Image names are soundfilename-x.png, where x is : | |||
-r for raw images | |||
-satellite instrument number (1,2,3A,3B,4,5) for channel A|B images | |||
-c for false colors. | |||
-d for pixel distribution stats. | |||
.SH DESCRIPTION | |||
Atpdec is a open source program that decode images transmitted by POES | |||
NOAA weather satellite serie. | |||
These satellites transmit continuously, among other things, medium resolution | |||
images of the earth on 137Mhz. | |||
These transmitions could be easely received with | |||
an inexpensive antenna and dedicated receiver. | |||
Output from such a receiver, is an audio signal that could be recorded | |||
into a soundfile with any soundcard. | |||
Atpdec will convert these sounfiles into .png images. | |||
For each soundfile up to 6 images could be generated : | |||
1) Raw image : contains the 2 transmitted channel images + telemetry and synchro pulses. | |||
Raw image is not calibrated, so it could be too dark or too light depending of | |||
the recording level. | |||
2) Calibrated channel A image | |||
3) Calibrated channel B image | |||
4) Temperature compensed I.R image | |||
5) False color image | |||
6) Pixel distribution statistique image (for cmap debugging only). | |||
Input soundfiles must be mono signal sampled at 11025 Hz. | |||
Atpdec use libsnd to read soundfile, so any sound file format supported by libsnd | |||
could be read. | |||
.SH EXAMPLE | |||
atpdec -d image -i ac *.wav | |||
.br | |||
Will process all .wav files in the current directory, generate only channel A and false color images and put them in the image directory. | |||
.SH AUTHOR | |||
Thierry Leconte (2003) |
@@ -20,8 +20,11 @@ | |||
* | |||
*/ | |||
#include <math.h> | |||
#include <filter.h> | |||
#include <filtercoeff.h> | |||
#ifndef M_PI | |||
#define M_PI 3.14159265358979323846 /* for OS that don't know it */ | |||
#endif | |||
#include "filter.h" | |||
#include "filtercoeff.h" | |||
#define Fe 11025 | |||
#define PixelLine 2080 | |||
@@ -3,7 +3,7 @@ | |||
typedef struct { | |||
double h,s,v; | |||
float h,s,v; | |||
} hsvpix_t; | |||
static void HSVtoRGB( float *r, float *g, float *b, hsvpix_t pix ) | |||
@@ -48,8 +48,8 @@ static void HSVtoRGB( float *r, float *g, float *b, hsvpix_t pix ) | |||
} | |||
static struct { | |||
double Vthresold; | |||
double Tthresold; | |||
float Vthresold; | |||
float Tthresold; | |||
hsvpix_t CloudTop; | |||
hsvpix_t CloudBot; | |||
hsvpix_t SeaTop; | |||
@@ -57,8 +57,8 @@ hsvpix_t SeaBot; | |||
hsvpix_t GroundTop; | |||
hsvpix_t GroundBot; | |||
} fcinfo= { | |||
28.0, | |||
180.0, | |||
30.0, | |||
170.0, | |||
{0,0.0,0.3},{0,0.0,1.0}, | |||
{240.0,0.9,0.5},{220.0,0.8,0.8}, | |||
{90.0,0.8,0.3},{50.0,0.8,1.0} | |||
@@ -19,7 +19,7 @@ | |||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
* | |||
*/ | |||
#include <filter.h> | |||
#include "filter.h" | |||
float fir( float *buff, const float *coeff, const int len) | |||
{ | |||
@@ -34,7 +34,7 @@ static void rgcomp(double x[16], rgparam *rgpr) | |||
{ | |||
/* 0.106,0.215,0.324,0.434,0.542,0.652,0.78,0.87 ,0.0 */ | |||
const double y[9] = { 31.1,63.0,95.0,127.2,158.9,191.1,228.6,255.0, 0.0 }; | |||
extern void polyreg(int m,int n,double x[],double y[],double c[]); | |||
extern void polyreg(const int m,const int n,const double x[],const double y[],double c[]); | |||
polyreg(REGORDER,9,x,y,rgpr->cf); | |||
} | |||
@@ -21,14 +21,21 @@ | |||
*/ | |||
#include <stdio.h> | |||
#include <unistd.h> | |||
#include <string.h> | |||
#ifdef WIN32 | |||
#include "w32util.h" | |||
#else | |||
#include <libgen.h> | |||
#endif | |||
#include <string.h> | |||
#include <sndfile.h> | |||
#include <png.h> | |||
extern getpixelrow(float *pixelv); | |||
#define CHA_OFFSET 86 | |||
#define CHB_OFFSET 1126 | |||
#define CH_WIDTH 909 | |||
#define IMG_WIDTH 2080 | |||
static SNDFILE *inwav; | |||
static int initsnd(char *filename) | |||
@@ -65,7 +72,7 @@ png_text text_ptr[]={ | |||
{ PNG_TEXT_COMPRESSION_NONE, "Channel", NULL ,0 }, | |||
{ PNG_TEXT_COMPRESSION_NONE, "Description", "NOAA POES satellite Image" ,25 } | |||
}; | |||
static int ImageOut(char *filename,const char* chid,float **prow,int nrow,int depth,int width,int offset) | |||
static int ImageOut(char *filename,char* chid,float **prow,int nrow,int depth,int width,int offset) | |||
{ | |||
FILE *pngfile; | |||
png_infop info_ptr; | |||
@@ -106,7 +113,7 @@ png_write_info(png_ptr,info_ptr); | |||
for(n=0;n<nrow;n++) { | |||
float *pixelv; | |||
png_byte pixel[2*2080]; | |||
png_byte pixel[2*IMG_WIDTH]; | |||
int i; | |||
pixelv=prow[n]; | |||
@@ -155,7 +162,7 @@ info_ptr = png_create_info_struct(png_ptr); | |||
return(1); | |||
} | |||
png_set_IHDR(png_ptr, info_ptr, 909, nrow, | |||
png_set_IHDR(png_ptr, info_ptr, CH_WIDTH, nrow, | |||
8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, | |||
PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); | |||
@@ -175,16 +182,16 @@ png_write_info(png_ptr,info_ptr); | |||
for(n=0;n<nrow;n++) { | |||
float *pixelv; | |||
png_color pixel[909]; | |||
png_color pixel[CH_WIDTH]; | |||
int i; | |||
pixelv=prow[n]; | |||
for(i=0;i<909;i++) { | |||
for(i=0;i<CH_WIDTH;i++) { | |||
double v,t; | |||
float r,g,b; | |||
v=pixelv[i+85]; | |||
t=pixelv[i+1125]; | |||
v=pixelv[i+CHA_OFFSET]; | |||
t=pixelv[i+CHB_OFFSET]; | |||
falsecolor(v,t,&r,&g,&b); | |||
pixel[i].red=( unsigned int)(255.0*r); | |||
pixel[i].green=( unsigned int)(255.0*g); | |||
@@ -218,8 +225,8 @@ for(n=0;n<nrow;n++) { | |||
pixelv=prow[n]; | |||
for(i=0;i<909;i++) { | |||
y=(int)(pixelv[i+85]); | |||
x=(int)(pixelv[i+1125]); | |||
y=(int)(pixelv[i+CHA_OFFSET]); | |||
x=(int)(pixelv[i+CHB_OFFSET]); | |||
distrib[y][x]+=1; | |||
if(distrib[y][x]> max) max=distrib[y][x]; | |||
} | |||
@@ -256,7 +263,7 @@ char name[1024]; | |||
char pngdirname[1024]=""; | |||
char imgopt[20]="ac"; | |||
float *prow[3000]; | |||
const char *chid[6]={ "1","2","3A","4","5","3B"}; | |||
char *chid[6]={ "1","2","3A","4","5","3B"}; | |||
int depth=8; | |||
int n,nrow; | |||
int ch; | |||
@@ -321,36 +328,36 @@ sf_close(inwav); | |||
/* raw image */ | |||
if(strchr(imgopt,(int)'r')!=NULL){ | |||
sprintf(pngfilename,"%s/%s-r.png",pngdirname,name); | |||
ImageOut(pngfilename,"raw",prow,nrow,depth,2080,0); | |||
ImageOut(pngfilename,"raw",prow,nrow,depth,IMG_WIDTH,0); | |||
} | |||
/* Channel A */ | |||
if(((strchr(imgopt,(int)'a')!=NULL) || (strchr(imgopt,(int)'c')!=NULL) || (strchr(imgopt,(int)'d')!=NULL))) { | |||
ch=Calibrate(prow,nrow,85); | |||
ch=Calibrate(prow,nrow,CHA_OFFSET); | |||
if(ch>0) { | |||
a=1; | |||
if(strchr(imgopt,(int)'a')!=NULL) { | |||
sprintf(pngfilename,"%s/%s-%s.png",pngdirname,name,chid[ch]); | |||
ImageOut(pngfilename,chid[ch],prow,nrow,depth,954,85); | |||
ImageOut(pngfilename,chid[ch],prow,nrow,depth,CH_WIDTH,CHA_OFFSET); | |||
} | |||
} | |||
} | |||
/* Channel B */ | |||
if((strchr(imgopt,(int)'b')!=NULL) || (strchr(imgopt,(int)'c')!=NULL) || (strchr(imgopt,(int)'t')!=NULL)) { | |||
ch=Calibrate(prow,nrow,1125); | |||
ch=Calibrate(prow,nrow,CHB_OFFSET); | |||
if(ch>0) { | |||
if(strchr(imgopt,(int)'b')!=NULL) { | |||
sprintf(pngfilename,"%s/%s-%s.png",pngdirname,name,chid[ch]); | |||
ImageOut(pngfilename,chid[ch],prow,nrow,depth,954,1125); | |||
ImageOut(pngfilename,chid[ch],prow,nrow,depth,CH_WIDTH,CHB_OFFSET); | |||
} | |||
} | |||
if(ch>2) { | |||
b=1; | |||
Temperature(prow,nrow,ch,1125); | |||
Temperature(prow,nrow,ch,CHB_OFFSET); | |||
if(strchr(imgopt,(int)'t')!=NULL) { | |||
sprintf(pngfilename,"%s/%s-t.png",pngdirname,name); | |||
ImageOut(pngfilename,"Temperature", prow,nrow,depth,954,1125); | |||
ImageOut(pngfilename,"Temperature", prow,nrow,depth,CH_WIDTH,CHB_OFFSET); | |||
} | |||
} | |||
} | |||
@@ -17,7 +17,7 @@ | |||
static void FactPiv(int N, double A[DMAX][DMAX], double B[], double Cf[]); | |||
void polyreg(int M, int N, double X[], double Y[], double C[]) | |||
void polyreg(const int M, const int N, const double X[], const double Y[], double C[]) | |||
{ | |||
int R, K, J; /* Loop counters */ | |||
double A[DMAX][DMAX]; /* A */ | |||