Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android: Adaptive Thresholding

I'm trying to implement adaptive thresholding algorithm by Derek Bradley using Android. But it is returning black pixels all the time. Here is my code snippet. Please suggest me about what should I do. Thanks in advance.

public static Bitmap GrayscaleToBin(Bitmap bm2)
{

    Bitmap bm;
    bm=bm2.copy(Config.ARGB_8888, true);
    final   int width = bm.getWidth();
    final  int height = bm.getHeight();
    int[]  pixels;
    pixels = new int[width*height];
    bm.getPixels(pixels,0,width,0,0,width,height);     
    //Bradley AdaptiveThrsholdging       
    int []intImg= new int[width*height];
    int sum=0;
    for(int i=0;i<width;++i){
        sum=0;
        for(int j=0;j<height;++j)
        {
            sum=sum+pixels[i+j*width];
            if(i==0){intImg[i+j*width]=sum;}
            else
            {
                intImg[i+j*width]= intImg[i-1+j*width]+sum;
            }
        }
    }
    int x1,x2,y1,y2=0,count=0;
    int s=width >> 3;   
    int t=15;
    for(int i=0;i<width;++i)
    {
        for(int j=0;j<height;++j)
        {
            x1=i-s/2;
            x2=i+s/2;
            y1=j-s/2;
            y2=j+s/2;
            if (x1 <0) x1 = 0;  
            if (x2>= width) x2 = width-1;  
            if (y1 <0) y1 = 0;  
            if (y2>= height) y2 = height-1;  
            count = (x2-x1) * (y2-y1);  
            sum = intImg [y2 * width + x2] -  
            intImg [y1 * width + x2] -  
            intImg [y2 * width + x1] +  
            intImg [y1 * width + x1]; 
            if((pixels[i+j*width]*count)<=(sum*(100-t)/100))
            {
                pixels[i+j*width]=0;
            }
            else
            {
                pixels[i+j*width]=255; 
            }
        }
    }
    /*---------------------------------------------------------------------------*/
    bm.setPixels(pixels,0,width,0,0,width,height);
    // Log.d("cdsfss","afterloop");
    return bm;
}
like image 891
Moyeen Avatar asked Feb 07 '13 18:02

Moyeen


People also ask

What is adaptive thresholding?

Adaptive thresholding is the method where the threshold value is calculated for smaller regions and therefore, there will be different threshold values for different regions. In OpenCV, you can perform Adaptive threshold operation on an image using the method adaptiveThreshold() of the Imgproc class.

What is the need of adaptive thresholding?

Like global thresholding, adaptive thresholding is used to separate desirable foreground image objects from the background based on the difference in pixel intensities of each region.

What is the difference between global and adaptive thresholding?

Global thresholding determines the threshold value based on the histogram of the overall pixel intensity distribution of the image. In contrast, adaptive thresholding computes the threshold value for each fractional region of the image, so that each fractional region has a different threshold value.

What is cv2 adaptive threshold?

adaptiveThreshold is the threshold method, again just like the simple thresholding and Otsu thresholding methods. Here we pass in a value of cv2. THRESH_BINARY_INV to indicate that any pixel value that passes the threshold test will have an output value of 0 . Otherwise, it will have a value of 255 .


1 Answers

After a Long struggle I have solved the issue with the following code.

public static Bitmap GrayscaleToBin(Bitmap bm2)
 {
 Bitmap bm;
 bm=bm2.copy(Config.RGB_565, true);
 final   int width = bm.getWidth();
 final  int height = bm.getHeight();

 int pixel1,pixel2,pixel3,pixel4,A,R;
 int[]  pixels;
 pixels = new int[width*height];
 bm.getPixels(pixels,0,width,0,0,width,height);
 int size=width*height;
      int s=width/8;
      int s2=s>>1;
      double t=0.15;
      double it=1.0-t;
      int []integral= new int[size];
      int []threshold=new int[size];
      int i,j,diff,x1,y1,x2,y2,ind1,ind2,ind3;
      int sum=0;
      int ind=0;
      while(ind<size)
      {
       sum+=pixels[ind] & 0xFF;
       integral[ind]=sum;
       ind+=width;
      }
   x1=0;
   for(i=1;i<width;++i)       
   {
       sum=0;
       ind=i;
       ind3=ind-s2;
       if(i>s)
       {
           x1=i-s;
       }
       diff=i-x1;
       for(j=0;j<height;++j)
       {
           sum+=pixels[ind] & 0xFF;
           integral[ind]=integral[(int)(ind-1)]+sum;
           ind+=width;
           if(i<s2)continue;
           if(j<s2)continue;
           y1=(j<s ? 0 : j-s);
           ind1=y1*width;
           ind2=j*width;

        if (((pixels[ind3]&0xFF)*(diff * (j - y1))) < ((integral[(int)(ind2 + i)] - integral[(int)(ind1 + i)] - integral[(int)(ind2 + x1)] + integral[(int)(ind1 + x1)])*it)) {
            threshold[ind3] = 0x00;
        } else {
            threshold[ind3] = 0xFFFFFF;
        }
        ind3 += width;
    }
}

y1 = 0;
for( j = 0; j < height; ++j )
{
    i = 0;
    y2 =height- 1;
    if( j <height- s2 ) 
    {
        i = width - s2;
        y2 = j + s2;
    }

    ind = j * width + i;
    if( j > s2 ) y1 = j - s2;
    ind1 = y1 * width;
    ind2 = y2 * width;
    diff = y2 - y1;
    for( ; i < width; ++i, ++ind )
    {

        x1 = ( i < s2 ? 0 : i - s2);
        x2 = i + s2;

        // check the border
        if (x2 >= width) x2 = width - 1;

        if (((pixels[ind]&0xFF)*((x2 - x1) * diff)) < ((integral[(int)(ind2 + x2)] - integral[(int)(ind1 + x2)] - integral[(int)(ind2 + x1)] + integral[(int)(ind1 + x1)])*it)) {
            threshold[ind] = 0x00;
        } else {
            threshold[ind] = 0xFFFFFF;
        }
    }
}
   /*-------------------------------
    * --------------------------------------------*/
   bm.setPixels(threshold,0,width,0,0,width,height);

   return bm;
}
like image 135
Moyeen Avatar answered Nov 15 '22 12:11

Moyeen