28#include "fmi_image_arith.h"
29#include "fmi_image_filter.h"
30#include "fmi_image_filter_morpho.h"
31#include "fmi_image_filter_line.h"
32#include "fmi_image_histogram.h"
33#include "fmi_image_filter_speck.h"
34#include "fmi_meteosat.h"
35#include "fmi_radar_image.h"
36#include "rave_alloc.h"
39float fmi_radar_sweep_angles[FMI_RADAR_SWEEP_COUNT]={0.5, 1.5, 2.5, 3.5, 4.5, 6.0, 8.0, 11.0, 20.0, 45.0};
40float fmi_radar_bin_depth = 0.0;
43int dbz_rgb[RGBCOUNT][4]={
63 fmi_radar_bin_depth = source->bin_depth;
66int abs_dbz_to_byte(Dbz dbz){
74int rel_dbz_to_byte(Dbz dbz){
82int abs_dbz_to_int(Dbz dbz){
86int rel_dbz_to_int(Dbz dbz){
92int byte_to_abs_dbz(Byte
byte){
96int byte_to_rel_dbz(Byte
byte){
100float radians_to_degree(
float radians){
return (radians*360.0/(2.0*PI));}
101float degrees_to_radian(
float degrees){
return (degrees*2.0*PI/360.0);}
103int bin_to_metre(
int bin){
104 return ((1+2*bin) * fmi_radar_bin_depth/2);
108int metre_to_bin(
int metre){
109 return(metre/fmi_radar_bin_depth);
112int bin_to_altitude(
int sweep_bin,
float sweep_angle){
114 const float b=bin_to_metre(sweep_bin);
115 const float a=EARTH_RADIUS43;
117 return (
int)sqrt(b*b+a*a-2.0*a*b*cos(PI/2.0+degrees_to_radian(sweep_angle)))-EARTH_RADIUS43;
120int altitude_to_bin(
int altitude,
float sweep_angle){
121 const float c=EARTH_RADIUS43+altitude;
122 const float a=EARTH_RADIUS43;
123 const float gamma=degrees_to_radian(sweep_angle)+PI/2.0;
124 const float beta=PI-gamma-asin(a*sin(gamma)/c);
127 return (sin(beta)*c/sin(gamma)/fmi_radar_bin_depth);
130int ground_to_bin(
int g_metre,
float sweep_angle){
133 beta=(float)g_metre/(
float)EARTH_RADIUS43;
134 gamma=PI-degrees_to_radian(sweep_angle)-PI/2.0-beta;
138 return (
int)(sin(beta)/sin(gamma)*(float)EARTH_RADIUS43/fmi_radar_bin_depth);
142int bin_to_ground(
int bin,
float sweep_angle){
144 const float m=bin_to_metre(bin);
145 const float chi=degrees_to_radian(sweep_angle);
148 return (EARTH_RADIUS43*atan(x/(y+(
float)EARTH_RADIUS43)));
152int bin_to_bin(
int sweep_bin,
float sweep_angle,
float target_sweep_angle){
153 return ground_to_bin( bin_to_ground(sweep_bin,sweep_angle), target_sweep_angle);
156void xy_to_polar(
int i,
int j,
int *theta,
int *radius){
160 *radius=(int)sqrt((
double)i*i+j*j);
161 *theta=180*atan2(i,-j)/3.14;
169 int channels = volume->channels;
171 Byte b,b_upper,b_lower;
173 const Byte PSEUDOCAPPI_MARKER=1;
176 int h,h_upper,h_lower;
179 bin = (
int *)RAVE_MALLOC(
sizeof(
int) * volume->sweep_count);
193 setup_context(volume);
195 canonize_image(&volume[1],cappi);
196 for (i=0;i<cappi->width;i++){
201 for (k=0;k<volume->channels;k++){
202 bin[k]=ground_to_bin(i*fmi_radar_bin_depth,volume[k+1].elevation_angle);
203 if (bin[k]>=volume->width)
204 bin[k]=volume->width-1;
205 h=bin_to_altitude(bin[k],volume[k+1].elevation_angle);
206 if ((h<=height)&&(h>=h_lower)){
210 if ((h>=height)&&(h<=h_upper)){
217 fprintf(stderr,
"lower(%d)=%dm [%d]\t upper(%d)=%dm [%d]\n",lower,h_lower,bin[lower],upper,h_upper,bin[upper]);
222 for (j=0;j<cappi->height;j++){
223 b=get_pixel(volume,bin[lower],j,lower);
224 b=b&~PSEUDOCAPPI_MARKER;
225 put_pixel(cappi,i,j,0,b);
227 }
else if (lower==-1) {
229 for (j=0;j<cappi->height;j++){
230 b=get_pixel(volume,bin[upper],j,upper);
231 b=b&~PSEUDOCAPPI_MARKER;
233 put_pixel(cappi,i,j,0,b);
237 mix=(255*(height-h_lower))/(h_upper-h_lower);
238 if (mix>255) mix=255;
240 for (j=0;j<cappi->height;j++) {
241 b_lower=get_pixel(volume,bin[lower],j,lower);
242 b_upper=get_pixel(volume,bin[upper],j,upper);
243 b=(mix*b_upper+(255-mix)*b_lower)/255;
244 b=b | PSEUDOCAPPI_MARKER;
246 put_pixel(cappi,i,j,0,b);
250 split_to_channels(volume,channels);
254void dump_sweep_info(
void){
258 for (j=0;j<FMI_RADAR_SWEEP_COUNT;j++){
260 printf(
"\t%3.1f\t",fmi_radar_sweep_angles[j]);
263 for (i=0;i<250000;i+=100){
265 for (j=0;j<FMI_RADAR_SWEEP_COUNT;j++){
266 beta=fmi_radar_sweep_angles[j];
268 b=ground_to_bin(i,beta);
269 b=MIN(b,FMI_RADAR_BIN_COUNT);
271 alt=bin_to_altitude(b,beta);
279 fprintf(stderr,
"plot ");
280 for (j=0;j<FMI_RADAR_SWEEP_COUNT;j++)
281 fprintf(stderr,
"\\\n'sweep.dat' using 1:%d title \"%.1f�\",",2*j+3,fmi_radar_sweep_angles[j]);
282 fprintf(stderr,
"\b \n");
289 register int i, j, k;
292 n = (
int*) RAVE_MALLOC(trace->height*
sizeof(
int));
294 for (k = 0; k < trace->channels; k++) {
295 for (j = 0; j < trace->height; j++) {
297 for (i = 0; i < trace->width; i++) {
298 if (get_pixel(trace, i, j, k) > 0)
304 for (j = 0; j < trace->height; j++) {
305 m = (n[(j - 1) % trace->height] + 2 * n[j] + n[(j + 1) % trace->height])
308 for (i = 0; i < trace->width; i++) {
310 c = get_pixel(trace, i, j, k) * m / trace->width;
312 put_pixel(trace, i, j, k, c);
319void enhance_horz255(
FmiImage *trace,Byte row_statistic[]){
323 for (j=0;j<trace->height;j++){
325 for (i=0;i<trace->width;i++){
326 c=get_pixel(trace,i,j,0)*s/255;
327 put_pixel(trace,i,j,0,c);
339void detect_horz_segments(
FmiImage *source,
FmiImage *trace,
int max_width,
int min_length){
345 init_new_image(&horz);
346 init_new_image(&vert);
348 canonize_image(source,trace);
349 canonize_image(source,&horz);
350 canonize_image(source,&vert);
355 vert_seg_lengths(source,&vert);
356 semisigmoid_image_inv(&vert,max_width);
357 translate_intensity(&vert,255,0);
358 threshold_image(&vert,trace,32);
359 threshold_image(&vert,&vert,96);
361 if (FMI_DEBUG(5)) write_image(
"debug_horz_segments_vert",&vert,PGM_RAW);
364 horz_seg_lengths(&vert,&horz);
366 sigmoid_image(&horz,min_length,1);
369 multiply_image255_sigmoid(trace,&horz,trace);
373 if (FMI_DEBUG(5)) write_image(
"debug_horz_segments",trace,PGM_RAW);
379void detect_emitters(
FmiImage *source,
FmiImage *trace,
int min_elevation,
int min_length){
381 canonize_image(source,trace);
388 detect_vert_maxima(source,trace);
390 threshold_image(trace,trace,min_elevation);
391 if (FMI_DEBUG(5)) write_image(
"debug_emitter_1_vert_max",trace,PGM_RAW);
394 horz_seg_lengths(trace,trace);
395 threshold_image(trace,trace,min_length-1);
396 semisigmoid_image(trace,min_length);
398 if (FMI_DEBUG(4)) write_image(
"debug_emitter",trace,PGM_RAW);
402void detect_emitters2(
FmiImage *source,
FmiImage *trace,
int min_intensity,
int min_length,
int max_width){
410 init_new_image(&candidate);
411 init_new_image(&mask);
412 init_new_image(&mask2);
413 init_new_image(&temp);
415 canonize_image(source,&temp);
416 canonize_image(source,trace);
417 canonize_image(source,&candidate);
419 initialize_vert_stripe(&mask,source->height);
420 initialize_vert_stripe(&mask2,source->height);
436 detect_emitters(source,&temp,min_intensity/2,min_length/2);
438 image_average_horz(&temp,&mask);
439 pipeline_process(&mask ,&mask2,0,1,histogram_max);
440 pipeline_process(&mask2,&mask ,0,1,histogram_mean);
442 sigmoid_image(&mask,16,2);
443 if (FMI_DEBUG(5)) write_image(
"debug_emitter2_3_stripe",&mask,PGM_RAW);
463 threshold_image(source,&temp,min_intensity);
464 detect_horz_segments(&temp,&candidate,max_width,min_length);
465 threshold_image(&candidate,trace,16);
469 if (FMI_DEBUG(5)) write_image(
"debug_emitter2_6_raw",trace,PGM_RAW);
473 multiply_image255_flex(trace,&mask,trace);
474 semisigmoid_image(trace,32);
476 reset_image(&candidate);
481 if (FMI_DEBUG(4)) write_image(
"debug_emitter2",trace,PGM_RAW);
487void smooth_signal(Byte signal[],
int length){
490 signal2=(Byte*)RAVE_MALLOC(
sizeof(Byte)*length);
491 for (i=0;i<length;i++)
492 signal2[i]=(signal[(i-1)%length] + 2*signal[i] +signal[(i+1)%length])/4;
493 for (i=0;i<length;i++)
494 signal[i]=MAX(signal[i],signal2[i]);
498void detect_emitters2old(
FmiImage *source,
FmiImage *trace,
int min_intensity,
int min_length,
int max_width){
508 row_nonzero=(Byte*)RAVE_MALLOC(
sizeof(Byte)*source->height);
509 row_avg=(Byte*)RAVE_MALLOC(
sizeof(Byte)*source->height);
510 row_pow=(Byte*)RAVE_MALLOC(
sizeof(Byte)*source->height);
512 init_new_image(&candidate);
513 init_new_image(&temp);
515 canonize_image(source,&temp);
516 canonize_image(source,trace);
517 canonize_image(source,&candidate);
521 detect_vert_maxima2(source,&temp);
522 threshold_image(&temp,&temp,2);
523 if (FMI_DEBUG(4)) write_image(
"debug_emitter_seg1",&temp,PGM_RAW);
525 horz_seg_lengths(&temp,&temp);
526 sigmoid_image(&temp,min_length,1);
527 threshold_image(&temp,&temp,126);
528 if (FMI_DEBUG(5)) write_image(
"debug_emitter_seg2",&temp,PGM_RAW);
529 row_statistics(&temp,row_nonzero,row_avg,row_pow);
530 for (i=0;i<trace->height;i++){
532 j=128+pseudo_sigmoid(1,((
int)row_nonzero[i])-16);
538 smooth_signal(row_nonzero,trace->height);
540 fp=fopen(
"row_stats.txt",
"w");
541 for (j=0;j<temp.height;j++){
542 fprintf(fp,
"%d\t%d\t%d\n",row_nonzero[j],row_avg[j],row_pow[j]);
543 put_pixel(&temp,row_nonzero[j],j,0,255);
544 put_pixel(&temp,row_avg[j],j,0,254);
545 put_pixel(&temp,sqrt(row_pow[j]),j,0,253);
549 if (FMI_DEBUG(4)) write_image(
"debug_emitter_horz_spread",&temp,PGM_RAW);
552 copy_image(source,trace);
553 threshold_image(trace,trace,min_intensity);
555 vert_seg_lengths(trace,&temp);
556 translate_intensity(&temp,0,255);
557 sigmoid_image(&temp,max_width,-1);
558 threshold_image(&temp,&temp,64);
559 if (FMI_DEBUG(4)) write_image(
"debug_emitter_vert_run",&temp,PGM_RAW);
561 horz_seg_lengths(&temp,&candidate);
562 sigmoid_image(&candidate,min_length,2);
563 threshold_image(&candidate,&candidate,64);
564 if (FMI_DEBUG(4)) write_image(
"debug_emitter_horz_run",&candidate,PGM_RAW);
566 pipeline_process(&candidate,&temp,5,1,histogram_max);
567 pipeline_process(&temp,trace,3,1,histogram_mean);
568 if (FMI_DEBUG(4)) write_image(
"debug_emitter_trace",trace,PGM_RAW);
571 enhance_horz255(trace,row_nonzero);
572 semisigmoid_image(trace,32);
574 if (FMI_DEBUG(4)) write_image(
"debug_emitter_trace_enh",trace,PGM_RAW);
577 reset_image(&candidate);
581 RAVE_FREE(row_nonzero);
588void detect_sun(
FmiImage *source,
FmiImage *trace,
int min_intensity,
int max_width,
int min_total_length){
590 const int closing_dist=4;
591 const int min_seg_length=4;
593 canonize_image(source,trace);
597 threshold_image(source,trace,min_intensity);
598 morph_closing(trace,trace,closing_dist,0);
599 detect_horz_segments(trace,trace,max_width,min_seg_length);
601 horz_seg_lengths(trace,trace);
603 sigmoid_image(trace,min_total_length,4);
611 if (FMI_DEBUG(4)) write_image(
"debug_sun",trace,PGM_RAW);
616void detect_sun2(
FmiImage *source,
FmiImage *trace,
int min_intensity,
int max_width,
int min_total_length,
int azimuth,
int elevation){
617 register int j,mj=source->height/2;
619 const int closing_dist=4;
624 init_new_image(&mask);
626 canonize_image(source,trace);
628 if ((elevation<-2)||(elevation>20)) {
634 threshold_image(source,trace,min_intensity);
635 morph_closing(trace,trace,closing_dist,0);
636 if (FMI_DEBUG(5)) write_image(
"debug_sun1",trace,PGM_RAW);
637 detect_horz_segments(trace,trace,max_width,min_total_length);
638 if (FMI_DEBUG(5)) write_image(
"debug_sun2",trace,PGM_RAW);
642 initialize_vert_stripe(&mask,source->height);
643 for (j=0;j<source->height;j++){
644 put_pixel_direct(&mask,(j+mj+azimuth)%source->height,pseudo_gauss_int(max_width,j-mj));
647 if (FMI_DEBUG(5)) write_image(
"debug_sun3",&mask,PGM_RAW);
649 multiply_image255_flex(trace,&mask,trace);
651 RAVE_FREE(mask.array);
653 if (FMI_DEBUG(4)) write_image(
"debug_sun",trace,PGM_RAW);
662void detect_ships(
FmiImage *source,
FmiImage *prob,
int min_intensity,
int max_area){
676 max_radius=sqrt(max_area)/2;
678 init_new_image(&temp1);
679 init_new_image(&temp2);
680 init_new_image(&specks);
681 init_new_image(&
virtual);
682 init_new_image(&lines);
684 canonize_image(source,&temp1);
685 fmi_debug(2,
"--------------");
686 if (FMI_DEBUG(2)) image_info(&temp1);
687 fmi_debug(2,
"==============");
689 canonize_image(source,&temp2);
692 canonize_image(source,&specks);
693 canonize_image(source,&
virtual);
694 canonize_image(source,&lines);
704 fmi_debug(2,
"remove ships2");
707 pipeline_process(source,&temp1,max_radius+2,max_radius+2,histogram_mean);
708 subtract_image(source,&temp1,&specks);
709 threshold_image(&specks,&specks,min_intensity);
710 if (FMI_DEBUG(5)) write_image(
"debug_ship_speck1",&specks,PGM_RAW);
713 propagate_right(&specks,&specks,&specks,-16,put_pixel);
714 propagate_left(&specks,&specks,&specks,0,put_pixel_min);
715 threshold_image(&specks,&specks,min_intensity/2);
716 if (FMI_DEBUG(4)) write_image(
"debug_ship_speck2",&specks,PGM_RAW);
719 iir_up(&specks,&temp1,975);
720 iir_down(&specks,&temp2,975);
721 max_image(&temp1,&temp2,&
virtual);
722 if (FMI_DEBUG(4)) write_image(
"debug_ship_virtual",&
virtual,PGM_RAW);
727 detect_vert_edges(source,&temp1);
728 threshold_image(&temp1,&temp1,8);
730 propagate_up(NULL,&temp1,&temp2,1*8,put_pixel);
731 propagate_down(&temp2,&temp2,&lines,0,put_pixel);
732 threshold_image(&lines,&lines,2*8);
733 if (FMI_DEBUG(3)) write_image(
"debug_ship_edges",&lines,PGM_RAW);
736 pipeline_process(source,&temp2,1,0,histogram_max);
737 pipeline_process(&temp2,&temp1,1,0,histogram_min);
738 if (FMI_DEBUG(4)) write_image(
"debug_ship_edges2",&temp1,PGM_RAW);
739 propagate_right(NULL,&temp1,&temp2,1,put_pixel);
740 propagate_left(&temp2,&temp2,&temp1,0,put_pixel);
741 if (FMI_DEBUG(4)) write_image(
"debug_ship_edges3",&temp1,PGM_RAW);
744 subtract_image(&lines,&temp1,&lines);
745 pipeline_process(&lines,&temp1,0,1,histogram_max);
746 pipeline_process(&temp1,&lines,0,2,histogram_mean);
747 if (FMI_DEBUG(4)) write_image(
"debug_ship_edges4",&lines,PGM_RAW);
750 min_image(&lines,&
virtual,&lines);
751 if (FMI_DEBUG(3)) write_image(
"debug_ship_edges5",&lines,PGM_RAW);
754 max_image(&specks,&lines,prob);
756 pipeline_process(prob,&temp1,1,2,histogram_mean);
757 average_images(prob,&temp1,prob);
758 multiply_image_scalar255(prob,768);
762 fmi_debug(2,
"remove ships2: reset temp1");
763 fmi_debug(2,
"--------------");
764 if (FMI_DEBUG(2)) image_info(&temp1);
765 fmi_debug(2,
"==============");
767 fmi_debug(2,
"remove ships2: reset temp2");
769 fmi_debug(2,
"remove ships2: reset specks1");
770 reset_image(&specks);
771 reset_image(&
virtual);
776void detect_doppler_anomaly(
FmiImage *source,
FmiImage *target,
int width,
int height,
int threshold){
779 histogram_threshold=128;
780 pipeline_process(source,target,width,height,histogram_variance_rot);
781 sigmoid_image(target,threshold,threshold/16);
783 if (FMI_DEBUG(4)) write_image(
"debug_doppler",target,PGM_RAW);
789void detect_ground_echo_minnetgrad(
FmiImage *source,
int ppi_count,
790 FmiImage *prob,
int gradT,
int altT)
797 const int gradD = ABS(gradT);
798 const int image_height = source[0].height;
799 const int image_width = source[0].width;
812 FmiImage debug_grad_raw, debug_grad;
817 altitude = (
float *) RAVE_MALLOC(source->width *
sizeof(
float));
818 bin = (
int *) RAVE_MALLOC(source->width *
sizeof(
int));
820 init_new_image(&debug_grad_raw);
821 init_new_image(&debug_grad);
822 init_new_image(&median0);
824 setup_context(source);
826 fmi_debug(2,
"detect_ground_echo");
828 canonize_image(&source[0], prob);
831 canonize_image(&source[0], &median0);
833 histogram_sample_count = 3;
834 pipeline_process(&source[0], &median0, 1, 1, histogram_median2);
837 canonize_image(&source[0], &debug_grad_raw);
838 fill_image(&debug_grad_raw, 0);
839 canonize_image(&source[0], &debug_grad);
840 fill_image(&debug_grad, 0);
844 fprintf(stderr,
" intensity_grad %.2d per 1000m, half_altitude %d \n",
848 for (i = 0; i < image_width; i++) {
850 for (l = 0; l < ppi_count; l++) {
851 bin[l] = bin_to_bin(i, source[1].elevation_angle,
852 source[l + 1].elevation_angle);
853 altitude[l] = bin_to_altitude(i, source[l + 1].elevation_angle);
856 for (j = 0; j < image_height; j++) {
863 g_min = get_pixel(&median0, i, j, 0);
866 for (l = 1; l < ppi_count; l++) {
870 g = get_pixel(&source[l], i, j, 0);
873 altD = altitude[l] - altitude[l - 1] + 100;
874 altM = (altitude[l] + altitude[l - 1]) / 2;
877 grad = (1000 * (g - g_min)) / altD;
879 pGRAD = 128 + pseudo_sigmoid(gradD, -(grad - gradT)) / 2;
882 if (pGRAD > pGRADmax)
886 pALT = 128 - pseudo_sigmoid(altD, altM - altT) / 2;
888 p = pGRAD * pALT / 256;
898 put_pixel_max(&debug_grad_raw, i, j, 0, pGRADmax);
899 put_pixel_max(&debug_grad, i, j, 0, p_max);
904 put_pixel_max(prob, i, j, 0, p_max);
908 write_image(
"debug_ground_1grad_raw", &debug_grad_raw, PGM_RAW);
909 write_image(
"debug_ground_2grad", &debug_grad, PGM_RAW);
910 write_image(
"debug_ground_3grad", prob, PGM_RAW);
914 reset_image(&debug_grad_raw);
915 reset_image(&debug_grad);
916 reset_image(&median0);
919void detect_ground_echo_mingrad(
FmiImage *source,
int ppi_count,
920 FmiImage *prob,
int intensity_grad,
int half_altitude)
924 int grad, alt_delta, alt_m;
925 const int max_altitude = half_altitude * 3;
926 const int half_width = ABS(intensity_grad);
927 const int image_height = source[0].height;
928 const int image_width = source[0].width;
931 FmiImage debug_grad_raw, debug_grad;
935 altitude = (
float *) RAVE_MALLOC(source->width *
sizeof(
float));
936 bin = (
int *) RAVE_MALLOC(source->width *
sizeof(
int));
938 init_new_image(&debug_grad_raw);
939 init_new_image(&debug_grad);
941 setup_context(source);
943 fmi_debug(2,
"detect_ground_echo");
945 canonize_image(&source[0], prob);
949 canonize_image(&source[0], &debug_grad_raw);
950 fill_image(&debug_grad_raw, 255);
951 canonize_image(&source[0], &debug_grad);
952 fill_image(&debug_grad, 0);
956 fprintf(stderr,
" intensity_grad %.2d per 1000m, half_altitude %d \n",
957 intensity_grad, half_altitude);
959 for (i = 0; i < image_width; i++) {
960 for (l = 0; l < ppi_count; l++) {
961 bin[l] = bin_to_bin(i, source[1].elevation_angle,
962 source[l + 1].elevation_angle);
963 altitude[l] = bin_to_altitude(i, source[l + 1].elevation_angle);
965 for (j = 0; j < image_height; j++) {
972 for (l = 0; l < ppi_count - 1; l++) {
975 alt_m = (altitude[l + 1] + altitude[l]) / 2;
977 if (alt_m > max_altitude)
980 alt_delta = (altitude[l + 1] - altitude[l]);
981 grad = 1000 * (get_pixel(&source[l + 1], i, j, 0)
982 - get_pixel(&source[l], i, j, 0)) / alt_delta;
995 p = 128 + pseudo_sigmoid(half_width, -(grad - intensity_grad));
1002 put_pixel_min(&debug_grad_raw, i, j, 0, 128 + grad);
1003 put_pixel_max(&debug_grad, i, j, 0, p);
1009 p = (pseudo_gauss(half_altitude, alt_m)) * p / 256;
1011 put_pixel_max(prob, i, j, 0, p);
1017 write_image(
"debug_ground_1grad_raw", &debug_grad_raw, PGM_RAW);
1018 write_image(
"debug_ground_2grad", &debug_grad, PGM_RAW);
1019 write_image(
"debug_ground_3grad", prob, PGM_RAW);
1022 RAVE_FREE(altitude);
1023 reset_image(&debug_grad_raw);
1024 reset_image(&debug_grad);
1027void detect_too_warm(
FmiImage *source,
FmiImage *prob,
FmiImage *meteosat,Celsius c50,Celsius c75,
int min_intensity,
int min_size){
1029 int b50=celsius_to_meteosatbyte(c50);
1030 int b75=celsius_to_meteosatbyte(c75);
1032 init_new_image(&specks);
1034 canonize_image(source,&specks);
1035 detect_specks(source,&specks,min_intensity,histogram_area);
1036 semisigmoid_image(&specks,min_size);
1037 if (FMI_DEBUG(5)) write_image(
"debug_warm_specks",&specks,PGM_RAW);
1039 copy_image(meteosat,prob);
1040 sigmoid_image(prob,b50,b75-b50);
1042 if (FMI_DEBUG(5)) write_image(
"debug_warm_temp",prob,PGM_RAW);
1044 multiply_image255(prob,&specks,prob);
1045 if (FMI_DEBUG(4)) write_image(
"debug_warm",prob,PGM_RAW);
1046 reset_image(&specks);
1049void remove_thin_horz_lines(
FmiImage *target,
int min_elevation,
int weight)
1053 unsigned char g1, g2;
1059 init_new_image(&trace);
1064 fmi_debug(1,
"remove_sun/emitter_lines");
1065 printf(
"weight=%d \n", weight);
1067 canonize_image(target, &trace);
1071 detect_horz_line_segments(target, &trace, min_length, min_elevation);
1074 printf(
"weight=%d \n", weight);
1079 for (k = 0; k < target->channels; k++) {
1080 for (j = 0; j < target->height; j++) {
1083 for (i = 0; i < trace.width; i++) {
1084 if (get_pixel(&trace, i, j, k) > 0)
1089 w = weight * n / trace.width;
1095 for (i = 1; i < trace.width; i++) {
1096 g1 = get_pixel(&trace, i, j, k);
1097 g2 = w * (float) get_pixel(&trace, i - 1, j, k);
1098 put_pixel(&trace, i, j, k, MAX(g1,g2));
1100 for (i = trace.width - 2; i > 0; i--) {
1101 g1 = get_pixel(&trace, i, j, k);
1102 g2 = w * (float) get_pixel(&trace, i + 1, j, k);
1103 put_pixel(&trace, i, j, k, MAX(g1,g2));
1107 for (i = 0; i < trace.width; i++) {
1108 if (get_pixel(&trace, i, j, k) > 2) {
1109 g1 = get_pixel(target, i, j - 1, k);
1110 g2 = get_pixel(target, i, j + 1, k);
1112 put_pixel(target, i, j, k, SUN);
1120 write_image(
"lines", &trace, PGM_RAW);
1121 reset_image(&trace);
1125void enhance_horz_lines2(
FmiImage *trace,
int weight){
1133 fmi_debug(3,
"enhance_horz_lines2");
1135 init_new_image(&trace2);
1138 for (i=0;i<256;i++) histogram_weights[i]=i+1;
1140 canonize_image(trace,&trace2);
1142 pipeline_process(trace,&trace2,4,1,histogram_max);
1143 pipeline_process(&trace2,trace,4,0,histogram_mean);
1149 fprintf(stderr,
" **** weight=%d\n",weight);
1155 count=(2*hrad+1)*(2*vrad+1) * weight;
1157 for (k=0;k<trace->channels;k++){
1158 for (j=0;j<trace->height;j++){
1160 for (i=0;i<trace->width;i++) n+=(get_pixel(trace,i,j,k)>0?1:0);
1162 histogram_sample_count=count* n/trace->width;
1164 initialize_histogram(trace,hist,hrad,vrad,0,j,NULL);
1165 for(i=0;i<trace->width;right(trace,hist,hrad,vrad,&i,&j))
1166 put_pixel(&trace2,i,j,k,histogram_median2(hist));}
1169 copy_image(&trace2,trace);
1170 reset_image(&trace2);
1175void enhance_vert_lines(
FmiImage *trace,
int weight)
1184 fmi_debug(3,
"enhance_horz_lines2");
1186 init_new_image(&trace2);
1189 for (i = 0; i < 256; i++)
1190 histogram_weights[i] = i + 1;
1192 canonize_image(trace, &trace2);
1194 pipeline_process(trace, &trace2, 4, 1, histogram_max);
1195 pipeline_process(&trace2, trace, 4, 0, histogram_mean);
1199 for (k = 0; k < trace->channels; k++) {
1200 for (i = 0; i < trace->width; i++) {
1202 for (j = 0; j < trace->height; j++)
1203 n += (get_pixel(trace, i, j, k) > 0 ? 1 : 0);
1209 count = (2 * hrad + 1) * (2 * vrad + 1) * weight * n / trace->width;
1210 histogram_sample_count = count;
1212 initialize_histogram(trace, hist, hrad, vrad, 0, j, NULL);
1213 for (j = 0; j < trace->height; up(trace, hist, hrad, vrad, &i, &j))
1217 put_pixel(&trace2, i, j, k, histogram_median2(hist));
1222 copy_image(&trace2, trace);
1223 reset_image(&trace2);
1227void put_nonzero(
FmiImage *img,
int x,
int y,
int channel,Byte c){
1228 if (c>0) img->array[channel*img->area + y*img->width + x]=c;
1236 init_new_image(&trace2);
1248 pipeline_process(trace,&trace2,0,1,histogram_min);
1249 max_image(target,&trace2,&trace2);
1250 if (FMI_DEBUG(2)) write_image(
"glue",&trace2,PGM_RAW);
1257 propagate_up(&trace2,trace,target,0,put_nonzero);
1259 propagate_down(&trace2,trace,target,0,put_pixel_max);
1260 reset_image(&trace2);
1264void distance_compensation_die(
FmiImage *image,
int slope){
1265 register int i,j,k,l;
1266 for (k=0;k<image->channels;k++)
1267 for (i=0;i<image->width;i++){
1268 l=((image->width-i*slope/256)/image->width);
1269 for (j=0;j<image->height;j++)
1270 put_pixel(image,i,j,k,get_pixel(image,i,j,k)*l);
1275void distance_compensation_mul(
FmiImage *image,
int coeff)
1277 register int i, j, k, l, m;
1279 for (k = 0; k < image->channels; k++) {
1280 for (i = 0; i < image->width; i++) {
1281 l = image->width + (coeff - 1) * i;
1282 for (j = 0; j < image->height; j++) {
1283 m = get_pixel(image, i, j, k) * l / image->width;
1287 put_pixel(image, i, j, k, m);
1295void distance_compensation_div(
FmiImage *image,
int slope)
1297 register int i, j, k;
1299 for (k = 0; k < image->channels; k++) {
1300 for (i = 0; i < image->width; i++) {
1302 l = 1024 * slope * i / image->width + 1024;
1303 for (j = 0; j < image->height; j++) {
1304 m = get_pixel(image, i, j, k);
1305 put_pixel(image, i, j, k, m * 1024 / l + (m > 0));
1317void remove_horz_lines(
FmiImage *target,
int min_length,
int min_elevation,
int weight){
1329 init_new_image(&trace);
1330 init_new_image(&trace2);
1331 init_new_image(&trace3);
1333 canonize_image(target,&trace);
1334 canonize_image(target,&trace2);
1335 canonize_image(target,&trace3);
1337 fmi_debug(1,
"remove_emitters2");
1338 if (FMI_DEBUG(2)) printf(
" min_elevation=%d\n",min_elevation);
1339 detect_horz_edges(target,&trace);
1340 distance_compensation_die(&trace,50);
1341 threshold_image(&trace,&trace,min_elevation);
1344 fill_image(&trace2,0);
1345 propagate_right(NULL,&trace,&trace2,+1,put_pixel);
1346 limit_image_intensities(&trace2,0,32);
1347 fill_image(&trace,0);
1348 propagate_left(&trace2,&trace2,&trace,0,put_pixel);
1349 if (FMI_DEBUG(2)) printf(
" min_length=%d\n",min_length);
1350 threshold_image(&trace,&trace,min_length);
1351 if (FMI_DEBUG(2)) write_image(
"debug_edges",&trace,PGM_RAW);
1355 fill_image(&trace2,0);
1356 propagate_up(&trace,target,&trace2,-8,put_pixel);
1357 propagate_down(&trace2,target,&trace2,0,put_pixel_min);
1359 fill_image(&trace3,0);
1360 propagate_down(&trace,target,&trace3,-8,put_pixel);
1361 propagate_up(&trace3,target,&trace3,0,put_pixel_min);
1363 max_image(&trace2,&trace3,&trace3);
1364 if (FMI_DEBUG(2)) write_image(
"debug_edges2",&trace3,PGM_RAW);
1365 threshold_image(&trace3,&trace3,min_length/2);
1369 enhance_horz_lines2(&trace3,weight);
1370 if (FMI_DEBUG(2)) write_image(
"debug_lines",&trace3,PGM_RAW);
1372 invert_image(&trace3);
1373 mask_image(target,&trace3,255,EMITTER);
1379 reset_image(&trace);
1380 reset_image(&trace2);
1381 reset_image(&trace3);
1388void detect_insect_band(
FmiImage *source,
FmiImage *prob,
int start_intensity,
1389 int radius,
int slope)
1391 register int i, j, k;
1392 int threshold, temp;
1393 canonize_image(source, prob);
1394 for (k = 0; k < source->channels; k++) {
1395 for (i = 0; i < source->width; i++) {
1397 threshold = start_intensity * (256 - pseudo_sigmoid(slope, temp)) / 512
1400 for (j = 0; j < source->height; j++) {
1401 temp = threshold - get_pixel(source, i, j, k);
1402 if (temp <= -threshold)
1405 if (get_pixel(source, i, j, k) > DATA_MIN)
1406 put_pixel(prob, i, j, k, 128 + 127 * temp / threshold);
1408 put_pixel(prob, i, j, k, 0);
1416 int intensity_delta,
int altitude_max,
int altitude_delta)
1418 register int i, j, k;
1421 setup_context(source);
1423 canonize_image(source, prob);
1424 for (k = 0; k < source->channels; k++) {
1425 for (i = 0; i < source->width; i++) {
1427 h = bin_to_altitude(i, source[k + 1].elevation_angle);
1429 h = (pseudo_sigmoid(altitude_delta, altitude_max - h) + 255) / 2;
1432 for (j = 0; j < source->height; j++) {
1434 f = get_pixel(source, i, j, k);
1435 if ((f == 0) || (f == NO_DATA)) {
1437 put_pixel(prob, i, j, k, 0);
1439 f = (pseudo_sigmoid(intensity_delta, intensity_max - f) + 255) / 2;
1440 put_pixel(prob, i, j, k, f * h / 255);
1457 for (i = 0; i < 256; i++) {
1464 #include "fmi_radar_codes.inc"
1466 copy_image_properties(source, target);
1467 target->channels = 3;
1468 initialize_image(target);
1469 map_channel_to_256_colors(source, 0, target, map);
1477 canonize_image(source, target);
1478 for (i = 0; i < source->volume; i++) {
1479 g = source->array[i];
1481 g = ((g - 64) / 16) * 32 + 96;
1485 target->array[i] = 255 - g;
1493 canonize_image(source,target);
1494 for (i=0;i<source->volume;i++){
1495 g = source->array[i];
1497 g = ((g-64)/16)*32+64;
1502 target->array[i] =255-g;
1512 for (i = 0; i < DATA_MIN; i++) {
1521 for (i = DATA_MIN; i < 256; i++) {
1522 temp = 128 + pseudo_sigmoid(16, i - 112) / 2;
1523 map[i][0] = MIN(temp,255);
1524 temp = pseudo_gauss(32, i - 92) + 64 + pseudo_sigmoid(16, i - 144) / 4;
1525 map[i][1] = MIN(temp,255);
1526 temp = pseudo_gauss(24, i - 64) * 2 / 3 + 128 + pseudo_sigmoid(32, i - 176)
1528 map[i][2] = MIN(temp,255);
1535 copy_image_properties(source, target);
1536 target->channels = 3;
1537 initialize_image(target);
1538 map_channel_to_256_colors(source, 0, target, map);
1547 for (i=0;i<255;i++){
1548 map[0][0]= (i>128) ? pseudo_sigmoid(64,128) : 0;
1549 map[0][1]= (i<128) ? 255-pseudo_sigmoid(64,128) : 0;
1552 copy_image_properties(source,target);
1554 initialize_image(target);
1555 map_channel_to_256_colors(source,0,target,map);
1564 int i,j=0,k,j_start=0,j_end;
1567 init_new_image(&target);
1569 setup_context(volume);
1570 copy_image_properties(volume,&target);
1572 initialize_image(&target);
1573 fill_image(&target,0);
1574 for (i=0;i<volume->width;i++){
1576 for (k=0;j<volume->channels;k++){
1577 j_end=bin_to_bin(i,0,volume[k+1].elevation_angle);
1578 for (j=j_start;j<j_end;j++)
1579 put_pixel(&target,i,j,0,5);
1583 reset_image(&target);
1586void gradient_rgb(
FmiImage *volume){
1588 const int sweeps=volume->height/360;
1590 fprintf(stderr,
"gradient_rgb: %d sweeps\n",sweeps);
1593 fmi_error(
"gradient_rgb: needs at least 4 sweeps");
1595 copy_image_properties(&volume[1],target);
1597 initialize_image(target);
1599 split_to_link_array(target,3,&target[1]);
1601 subtract_image128(&volume[2],&volume[1],&target[1]);
1603 subtract_image128(&volume[3],&volume[1],&target[2]);
1604 subtract_image128(&volume[4],&volume[1],&target[3]);
1607 canonize_image(target,&cart);
1608 to_cart(target,&cart,NO_DATA);
1610 write_image(
"Grad",target,PPM_RAW);
1611 write_image(
"Gradc",&cart,PPM_RAW);
1617int histogram_dominate_anaprop(Histogram h){
1618 register int i,i_max;
1620 for (i=1;i<DATA_MIN;i++)