26#include "fmi_image_filter.h"
27#include "fmi_image_histogram.h"
29FmiImage *histogram_weight_image=NULL;
30int histogram_threshold=0;
31Histogram histogram_weights;
32Histogram histogram_sine;
33Histogram histogram_cosine;
35int histogram_sample_count=0;
36int (* histogram_scaling_function)(
int param,
int value)=NULL;
37int histogram_scaling_parameter=128;
39int histogram_semisigmoid(
int a,
int x){
40 return (255*(x)/(a+x));
43int histogram_semisigmoid_inv(
int a,
int x){
44 return (255-255*(x)/(a+x));
49void clear_histogram_full(Histogram hist){
51 for (i=0;i<HISTOGRAM_SIZE;i++) hist[i]=0;
61void convolve(
FmiImage *source,
FmiImage *target,
int mask_width,
int mask_height,
int **mask,
int divisor){
64 fmi_debug(2,
"convolve");
68 for (j=0;j<mask_height;j++){
69 for (i=0;i<mask_width;i++){
70 printf(
"\t(%d,%d) =",i,j);
72 printf(
" %d",mask[j][i]);
77 if (FMI_DEBUG(2)) write_image(
"conv",target,PGM_RAW);
83int histogram_sum(Histogram h){
93int histogram_median_biased(Histogram h,
int count){
105int histogram_median_biased_top(Histogram h,
int count){
109 for (i=255;i>=0;i--){
111 if (sum>=count)
return i;}
117int histogram_size(Histogram h){
121int histogram_area(Histogram h){
122 return ABS(h[HIST_AREA]);
125int histogram_area_inv255(Histogram h){
126 return 255-ABS(h[HIST_AREA]);
129int histogram_area2(Histogram h){
130 return pseudo_sigmoid(255,ABS(h[HIST_AREA]));
133int histogram_area2_inv255(Histogram h){
134 return 255-pseudo_sigmoid(1,ABS(h[HIST_AREA]));
137int histogram_perimeter(Histogram h){
138 return h[HIST_PERIMx3];
141int histogram_perimeter2(Histogram h){
142 return pseudo_sigmoid(255,h[HIST_PERIMx3]);
151int histogram_compactness(Histogram h){
155 return (4500*ABS(h[HIST_AREA])/(h[HIST_PERIMx3]*h[HIST_PERIMx3]+1));
158int histogram_min(Histogram h){
159 return histogram_median_biased(h,1);
162int histogram_max(Histogram h){
163 return histogram_median_biased_top(h,1);
166int histogram_range(Histogram h){
167 return (histogram_median_biased_top(h,1)-histogram_median_biased(h,1));
171int histogram_median(Histogram h){
175 count=histogram_sum(h)/2;
184void histogram_median2_reset(Histogram h){
185 histogram_sample_count=histogram_sum(h);
189int histogram_median2(Histogram h){
195 if (sum>=histogram_sample_count)
201int histogram_median2_top(Histogram h){
205 for (i=255;i>=0;i--){
207 if (sum>=histogram_sample_count)
212int histogram_mean(Histogram h){
223int histogram_mean_nonzero(Histogram h){
229 for (i=1;i<256;i++) {
239int histogram_mean2(Histogram h){
247 return (sum/histogram_sample_count);
250int histogram_mean_weighted(Histogram h){
263int (* histogram_mean_weighted_pyramid)(Histogram h) = histogram_mean_weighted;
265int histogram_variance_rot(Histogram h){
267 int x,y,sum_x,sum2_x,sum_y,sum2_y;
283 x=histogram_cosine[i]-128;
284 y=histogram_sine[i]-128;
291 return pseudo_sigmoid (histogram_threshold,(sum2_x-sum_x*sum_x/N + sum2_y-sum_y*sum_y/N)/N/128);
321int histogram_dom(Histogram h){
322 register int i,i_max;
330int histogram_dom_nonzero(Histogram h){
331 register int i,i_max;
342int histogram_meanX(Histogram h){
344 return h[HIST_SUM_I]/h[HIST_SIZE];
349int histogram_meanY(Histogram h){
351 return h[HIST_SUM_I]/h[HIST_SIZE];
356int histogram_principal_component_ratio(Histogram h){
358 double x,y,xx,xy,yy,n;
359 double Cxx,Cxy,Cyy,SQRT,ans;
371 if (n==0)
return 255;
380 SQRT=sqrt((Cxx-Cyy)*(Cxx-Cyy)+4*Cxy*Cxy);
383 ans=255.0*(Cxx+Cyy-SQRT)/(Cxx+Cyy+SQRT);
394int histogram_smoothness(Histogram h){
396 temp=histogram_compactness(h);
397 temp2=histogram_principal_component_ratio(h);
398 if (temp>255) temp=255;
399 if (temp2<1) temp2=1;
400 return sqrt(255*temp*temp/temp2);
407void histogram_dump_nonzero(Histogram h){
413 for (i=0;i<HISTOGRAM_SIZE;i++)
415 fprintf(stderr,
"histogram[%d]=%d\n",i,(
int)h[i]);
419void histogram_dump(Histogram h){
428 fprintf(stderr,
"\n sum=%d \t hits=%d \t mean=%d \n",sum,s,sum/s);
431void histogram_dump_stats(Histogram h){
432 char *format=
"%d\t%d %s\n";
433 printf(format,h[HIST_SIZE],HIST_SIZE,
"HIST_SIZE");
434 printf(format,h[HIST_SUM],HIST_SUM,
"HIST_SUM");
435 printf(format,h[HIST_MIN],HIST_MIN,
"HIST_MIN");
436 printf(format,h[HIST_AREA],HIST_AREA,
"HIST_AREA");
437 printf(format,h[HIST_MAX],HIST_MAX,
"HIST_MAX");
438 printf(format,h[HIST_PERIMx3],HIST_PERIMx3,
"HIST_PERIMx3");
439 printf(format,h[HIST_SUM_I],HIST_SUM_I,
"HIST_SUM_I");
440 printf(format,h[HIST_SUM_J],HIST_SUM_J,
"HIST_SUM_J");
441 printf(format,h[HIST_SUM_II],HIST_SUM_II,
"HIST_SUM_II");
442 printf(format,h[HIST_SUM_JJ],HIST_SUM_JJ,
"HIST_SUM_JJ");
443 printf(format,h[HIST_SUM_IJ],HIST_SUM_IJ,
"HIST_SUM_IJ");
444 printf(format,h[HIST_MIN_I],HIST_MIN_I,
"HIST_MIN_I");
445 printf(format,h[HIST_MIN_J],HIST_MIN_J,
"HIST_MIN_J");
446 printf(format,h[HIST_MAX_I],HIST_MAX_I,
"HIST_MAX_I");
447 printf(format,h[HIST_MAX_J],HIST_MAX_J,
"HIST_MAX_J");
451void initialize_histogram(
FmiImage *source,Histogram histogram,
int hrad,
int vrad,
int i,
int j,
int (* hist_func)(Histogram)){
455 clear_histogram(histogram);
458 if (hist_func==histogram_mean_weighted) {
459 fmi_debug(2,
"initialize_histogram: histogram_mean_weighted, source:");
461 fmi_debug(2,
"initialize_histogram: histogram_mean_weighted, weight:");
463 image_info(histogram_weight_image);
464 histogram[HIST_SIZE]=0;
465 for (k=0;k<source->channels;k++) {
466 for (m=-hrad;m<=hrad;m++) {
467 for (n=-vrad;n<=vrad;n++) {
468 w=get_pixel(histogram_weight_image,i+m,j+n,k);
469 histogram[get_pixel(source,i+m,j+n,k)]+=w;
470 histogram[HIST_SIZE]+=w;
476 for (k=0; k < source->channels; k++) {
477 for (m=-hrad; m <= hrad; m++) {
478 for (n=-vrad; n <= vrad; n++) {
479 ++histogram[get_pixel(source,i+m,j+n,k)];
486 if (histogram_sample_count==0)
487 histogram_sample_count=(2*hrad+1)*(2*vrad+1)/2;
490 if (hist_func==histogram_variance_rot)
491 for (i=0;i<256;i++) {
492 alpha=((float)i)/255*2.0*PI;
493 histogram_cosine[i]=128+127*cos(alpha);
494 histogram_sine[i] =128+127*sin(alpha);
496 fmi_debug(2,
"initialize_histogram");
512void (* histogram_window_up)(
FmiImage *,Histogram,int,int,
int *,
int *);
513void (* histogram_window_down)(
FmiImage *,Histogram,int,int,
int *,
int *);
514void (* histogram_window_right)(
FmiImage *,Histogram,int,int,
int *,
int *);
515void (* histogram_window_left)(
FmiImage *,Histogram,int,int,
int *,
int *);
519void up(
FmiImage *source,Histogram histogram,
int hrad,
int vrad,
int *i,
int *j){
522 for (m=-hrad;m<=hrad;m++){
523 --histogram[get_pixel(source,(*i)+m,(*j)-vrad ,k)];
524 ++histogram[get_pixel(source,(*i)+m,(*j)+vrad+1,k)];}
527void down(
FmiImage *source,Histogram histogram,
int hrad,
int vrad,
int *i,
int *j){
530 for (m=-hrad;m<=hrad;m++){
531 --histogram[get_pixel(source,(*i)+m,(*j)+vrad ,k)];
532 ++histogram[get_pixel(source,(*i)+m,(*j)-vrad-1,k)];}
536void right(
FmiImage *source,Histogram histogram,
int hrad,
int vrad,
int *i,
int *j){
539 for (n=-vrad;n<=vrad;n++){
540 --histogram[get_pixel(source,*i-hrad ,*j+n,k)];
541 ++histogram[get_pixel(source,*i+hrad+1,*j+n,k)];}
545void left(
FmiImage *source,Histogram histogram,
int hrad,
int vrad,
int *i,
int *j){
550 for (n=-vrad;n<=vrad;n++){
551 --histogram[get_pixel(source,*i+hrad ,*j+n,k)];
552 ++histogram[get_pixel(source,*i-hrad-1,*j+n,k)];}
558void up_w(
FmiImage *source,Histogram histogram,
int hrad,
int vrad,
int *i,
int *j){
561 register int jo=*j-vrad;
562 register int jn=*j+vrad+1;
563 for (m=-hrad;m<=hrad;m++){
565 w=get_pixel(histogram_weight_image,ii,jo,0);
566 histogram[get_pixel(source,ii,jo,0)] -= w;
567 histogram[HIST_SIZE] -= w;
568 w=get_pixel(histogram_weight_image,ii,jn,0);
569 histogram[get_pixel(source,ii,jn,0)] += w;
570 histogram[HIST_SIZE] += w;
574void down_w(
FmiImage *source,Histogram histogram,
int hrad,
int vrad,
int *i,
int *j){
577 register int jo=*j+vrad;
578 register int jn=*j-vrad-1;
580 for (m=-hrad;m<=hrad;m++){
582 w=get_pixel(histogram_weight_image,ii,jo,0);
583 histogram[get_pixel(source,ii,jo,0)] -= w;
584 histogram[HIST_SIZE] -= w;
585 w=get_pixel(histogram_weight_image,ii,jn,0);
586 histogram[get_pixel(source,ii,jn,0)] += w;
587 histogram[HIST_SIZE] += w;
592void right_w(
FmiImage *source,Histogram histogram,
int hrad,
int vrad,
int *i,
int *j){
595 register int io=*i-hrad;
596 register int in=*i+hrad+1;
597 for (n=-vrad;n<=vrad;n++){
599 w=get_pixel(histogram_weight_image,io,jj,0);
600 histogram[get_pixel(source,io,jj,0)] -= w;
601 histogram[HIST_SIZE] -= w;
602 w=get_pixel(histogram_weight_image,in,jj,0);
603 histogram[get_pixel(source,in,jj,0)] += w;
604 histogram[HIST_SIZE] += w;
609void left_w(
FmiImage *source,Histogram histogram,
int hrad,
int vrad,
int *i,
int *j){
612 register int io=*i+hrad;
613 register int in=*i-hrad-1;
614 for (n=-vrad;n<=vrad;n++){
616 w = get_pixel(histogram_weight_image,io,jj,0);
617 histogram[w * get_pixel(source,io,jj,0)] -= w;
618 histogram[HIST_SIZE] -= w;
619 w = get_pixel(histogram_weight_image,in,jj,0);
620 histogram[get_pixel(source,in,jj,0)] += w;
621 histogram[HIST_SIZE] += w;
626void pipeline_process_col_major(
FmiImage *source,
FmiImage *target,
int hrad,
int vrad,
int (* histogram_function)(Histogram),Histogram histogram){
630 fmi_debug(4,
"pipeline_process_col_major");
635 while (j<source->height-1){
637 histogram_window_up(source,histogram,hrad,vrad,&i,&j);
638 put_pixel(target,i,j,k,histogram_function(histogram));
639 if (0){ fprintf(stderr,
" - sum=i%d\t j=%d\n",i,j);}
644 if (i<source->width-1){
645 histogram_window_right(source,histogram,hrad,vrad,&i,&j);
646 put_pixel(target,i,j,k,histogram_function(histogram));}
652 histogram_window_down(source,histogram,hrad,vrad,&i,&j);
653 put_pixel(target,i,j,k,histogram_function(histogram));
657 if (i<source->width-1){
658 histogram_window_right(source,histogram,hrad,vrad,&i,&j);
659 put_pixel(target,i,j,k,histogram_function(histogram));
666void pipeline_process_row_major(
FmiImage *source,
FmiImage *target,
int hrad,
int vrad,
int (* histogram_function)(Histogram),Histogram histogram){
669 fmi_debug(4,
"pipeline_process_row_major");
675 while (i<source->width-1){
676 histogram_window_right(source,histogram,hrad,vrad,&i,&j);
677 put_pixel(target,i,j,k,histogram_function(histogram));
681 if (j<source->height-1){
682 histogram_window_up(source,histogram,hrad,vrad,&i,&j);
683 put_pixel(target,i,j,k,histogram_function(histogram));}
689 histogram_window_left(source,histogram,hrad,vrad,&i,&j);
690 put_pixel(target,i,j,k,histogram_function(histogram));
694 if (j<source->height-1){
695 histogram_window_up(source,histogram,hrad,vrad,&i,&j);
696 put_pixel(target,i,j,k,histogram_function(histogram));}
703void pipeline_process(
FmiImage *source,
FmiImage *target,
int hrad,
int vrad,
int (* histogram_function)(Histogram)){
723 histogram_window_up = up;
724 histogram_window_down = down;
725 histogram_window_right = right;
726 histogram_window_left = left;
728 if (histogram_function==histogram_mean_weighted){
729 fmi_debug(2,
"pipeline_process: histogram_mean_weighted");
730 if (histogram_weight_image==NULL)
731 fmi_error(
"pipeline_process: histogram_weight_image==NULL");
732 histogram_window_up = up_w;
733 histogram_window_down = down_w;
734 histogram_window_right = right_w;
735 histogram_window_left = left_w;
738 fmi_debug(4,
"pipeline_process");
740 printf(
" width=%d\t height=%d\n",width,height);
743 initialize_histogram(source,histogram,hrad,vrad,0,0,histogram_function);
747 put_pixel(target,0,0,0,histogram_function(histogram));
749 if (histogram_function==histogram_mean_weighted){
750 fmi_debug(2,
"pipeline_process: histogram_mean_weighted");
753 if (width > height) {
754 pipeline_process_row_major(source, target, hrad, vrad, histogram_function, histogram);
756 pipeline_process_col_major(source, target, hrad, vrad, histogram_function, histogram);