图像的二值化涉及几种方式。
可以参看http://blog.csdn.net/jia20003/article/details/8074627
这里只介绍近似一维的Means方法寻找二值化阀值
(1)初始化阀值,可以自己设置或者随机生成,这里使用的是128
(2)根据阀值将像素数组分为G1和G2两个模块。
(3)G1的平均值是m1,G2的平均值是m2.
(4)一个新的阀值T=(m1+m2)/2;
activity:
public class ImageJAndroid6Activity extends Activity {
ImageView sourceImage;
ImageView destinationImage;
int width;
int height;
int[] input;
int[] output;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
sourceImage=(ImageView) findViewById(R.id.source);
destinationImage=(ImageView) findViewById(R.id.destination);
}
public void remove(View v){
Bitmap bitmap=BitmapFactory.decodeResource(getResources(),R.drawable.cc);
width=bitmap.getWidth();
height=bitmap.getHeight();
input=new int[width*height];
bitmap.getPixels(input, 0, width, 0, 0, width, height);
int threshold=getThreshold(input,width,height);
Log.i("msg",threshold+"");
for(int y=0;y<height;y++){
for(int x=0;x<width;x++){
int a=input[y*width+x]>>24&0xff;
int red=input[y*width+x]>>16&0xff;
int green=input[y*width+x]>>8&0xff;
int blue=input[y*width+x]&0xff;
if(red>threshold){ //直接以红色通道作为判断。
red=green=blue=255;
}else{
red=green=blue=0;
}
input[y*width+x]=a<<24|red<<16|green<<8|blue;
}
}
Bitmap newBitmap=Bitmap.createBitmap(width,height,Config.RGB_565);
newBitmap.setPixels(input, 0, width, 0, 0, width,height);
destinationImage.setImageBitmap(newBitmap);
}
private int getThreshold(int[] inPixels, int height, int width) {
int inithreshold = 127;
int finalthreshold = 0;
int temp[] = new int[inPixels.length];
for(int index=0; index<inPixels.length; index++) {
temp[index] = (inPixels[index] >> 16) & 0xff;
}
List<Integer> sub1 = new ArrayList<Integer>();
List<Integer> sub2 = new ArrayList<Integer>();
int means1 = 0, means2 = 0;
while(finalthreshold != inithreshold) {
finalthreshold = inithreshold;
for(int i=0; i<temp.length; i++) {
if(temp[i] <= inithreshold) {
sub1.add(temp[i]);
} else {
sub2.add(temp[i]);
}
}
means1 = getMeans(sub1);
means2 = getMeans(sub2);
sub1.clear();
sub2.clear();
inithreshold = (means1 + means2) / 2;
}
return finalthreshold;
}
private static int getMeans(List<Integer> data) {
int result = 0;
int size = data.size();
for(Integer i : data) {
result += i;
}
return (result/size);
}
}
效果:
但是彩色图片直接二值化的话,取得效果不是很好。
如果我们在彩色图片二值化之前将其灰度化的话,那么取得的效果是比上面的要好。