sauvola算法實現

實現了sauvola算法。

參數是:k, windowSize,自己調調看效果

  1. void sauvola(unsigned char * grayImage,unsigned char * biImage,int w,int h,int k,int windowSize)  
  2. {     
  3.     int whalf = windowSize >> 1;  
  4.       
  5.     int i,j;  
  6.     int IMAGE_WIDTH = w;  
  7.     int IMAGE_HEIGHT = h;  
  8.     // create the integral image  
  9.     unsigned long * integralImg = (unsigned long*)malloc(IMAGE_WIDTH*IMAGE_HEIGHT*sizeof(unsigned long*));  
  10.     unsigned long * integralImgSqrt = (unsigned long*)malloc(IMAGE_WIDTH*IMAGE_HEIGHT*sizeof(unsigned long*));  
  11.     int sum = 0;  
  12.     int sqrtsum = 0;  
  13.     int index;  
  14.     for (i=0; i<IMAGE_HEIGHT; i++)  
  15.     {  
  16.         // reset this column sum  
  17.         sum = 0;  
  18.         sqrtsum = 0;  
  19.   
  20.         for (j=0; j<IMAGE_WIDTH; j++)  
  21.         {  
  22.             index = i*IMAGE_WIDTH+j;  
  23.   
  24.             sum += grayImage[index];  
  25.             sqrtsum += grayImage[index] * grayImage[index];  
  26.   
  27.             if (i==0)  
  28.             {  
  29.                 integralImg[index] = sum;  
  30.                 integralImgSqrt[index] = sqrtsum;  
  31.             }  
  32.             else  
  33.             {  
  34.                 integralImgSqrt[index] = integralImgSqrt[(i-1)*IMAGE_WIDTH+j] + sqrtsum;  
  35.                 integralImg[index] = integralImg[(i-1)*IMAGE_WIDTH+j] + sum;  
  36.             }  
  37.         }  
  38.     }  
  39.       
  40.     //Calculate the mean and standard deviation using the integral image  
  41.     int xmin,ymin,xmax,ymax;  
  42.     double mean,std,threshold;  
  43.     double diagsum,idiagsum,diff,sqdiagsum,sqidiagsum,sqdiff,area;  
  44.   
  45.     for (i=0; i<IMAGE_WIDTH; i++){  
  46.         for (j=0; j<IMAGE_HEIGHT; j++){  
  47.             xmin = max(0,i - whalf);  
  48.             ymin = max(0,j - whalf);  
  49.             xmax = min(IMAGE_WIDTH-1,i+whalf);  
  50.             ymax = min(IMAGE_HEIGHT-1,j+whalf);  
  51.               
  52.             area = (xmax - xmin + 1) * (ymax - ymin + 1);  
  53.             if(area <= 0)  
  54.             {  
  55.                 biImage[i * IMAGE_WIDTH + j] = 255;  
  56.                 continue;  
  57.             }  
  58.               
  59.             if(xmin == 0 && ymin == 0){  
  60.                 diff = integralImg[ymax * IMAGE_WIDTH + xmax];  
  61.                 sqdiff = integralImgSqrt[ymax * IMAGE_WIDTH + xmax];  
  62.             }else if(xmin > 0 && ymin == 0){  
  63.                 diff = integralImg[ymax * IMAGE_WIDTH + xmax] - integralImg[ymax * IMAGE_WIDTH + xmin - 1];  
  64.                 sqdiff = integralImgSqrt[ymax * IMAGE_WIDTH + xmax] - integralImgSqrt[ymax * IMAGE_WIDTH + xmin - 1];     
  65.             }else if(xmin == 0 && ymin > 0){  
  66.                 diff = integralImg[ymax * IMAGE_WIDTH + xmax] - integralImg[(ymin - 1) * IMAGE_WIDTH + xmax];  
  67.                 sqdiff = integralImgSqrt[ymax * IMAGE_WIDTH + xmax] - integralImgSqrt[(ymin - 1) * IMAGE_WIDTH + xmax];;  
  68.             }else{  
  69.                 diagsum = integralImg[ymax * IMAGE_WIDTH + xmax] + integralImg[(ymin - 1) * IMAGE_WIDTH + xmin - 1];  
  70.                 idiagsum = integralImg[(ymin - 1) * IMAGE_WIDTH + xmax] + integralImg[ymax * IMAGE_WIDTH + xmin - 1];  
  71.                 diff = diagsum - idiagsum;  
  72.   
  73.                 sqdiagsum = integralImgSqrt[ymax * IMAGE_WIDTH + xmax] + integralImgSqrt[(ymin - 1) * IMAGE_WIDTH + xmin - 1];  
  74.                 sqidiagsum = integralImgSqrt[(ymin - 1) * IMAGE_WIDTH + xmax] + integralImgSqrt[ymax * IMAGE_WIDTH + xmin - 1];  
  75.                 sqdiff = sqdiagsum - sqidiagsum;  
  76.             }  
  77.   
  78.             mean = diff/area;  
  79.             std  = sqrt((sqdiff - diff*diff/area)/(area-1));  
  80.             threshold = mean*(1+k*((std/128)-1));  
  81.             if(grayImage[j*IMAGE_WIDTH + i] < threshold)  
  82.                 biImage[j*IMAGE_WIDTH + i] = 0;  
  83.             else  
  84.                 biImage[j*IMAGE_WIDTH + i] = 255;     
  85.         }  
  86.     }  
  87.       
  88.     free(integralImg);  
  89.     free(integralImgSqrt);  
  90. }  




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章