我正在尝试使用Android Derek Bradley实现自适应阈值算法。但它一直在返回黑色像素。这是我的代码片段。请建议我应该怎么做。提前谢谢。
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;
}
答案 0 :(得分:9)
经过长时间的努力,我用以下代码解决了这个问题。
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;
}
答案 1 :(得分:2)
您可以使用Catalano Framework。在样本文件夹中有一个使用Bradley for Android的例子。
FastBitmap fb = new FastBitmap(bitmap);
fb.toGrayscale();
BradleyLocalThreshold bradley = new BradleyLocalThreshold();
bradley.applyInPlace(fb);
bitmap = fb.toBitmap();