网上找了很多,没有一个能用的,本文的方法是自己在别人的基础上修改而来,纯Java算法,效率没有C++的高,追求效率的可以用Jni,具体参考:http://vaero.blog.51cto.com/4350852/822997
感谢网上分享的朋友们!
有图有真相:
接下来直接上代码:
public void binarization(Bitmap img) { width = img.getWidth(); height = img.getHeight(); int area = width * height; int gray[][] = new int[width][height]; int average = 0;// 灰度平均值 int graysum = 0; int graymean = 0; int grayfrontmean = 0; int graybackmean = 0; int pixelGray; int front = 0; int back = 0; int[] pix = new int[width * height]; img.getPixels(pix, 0, width, 0, 0, width, height); for (int i = 1; i < width; i++) { // 不算边界行和列,为避免越界 for (int j = 1; j < height; j++) { int x = j * width + i; int r = (pix[x] >> 16) & 0xff; int g = (pix[x] >> 8) & 0xff; int b = pix[x] & 0xff; pixelGray = (int) (0.3 * r + 0.59 * g + 0.11 * b);// 计算每个坐标点的灰度 gray[i][j] = (pixelGray << 16) + (pixelGray << 8) + (pixelGray); graysum += pixelGray; } } graymean = (int) (graysum / area);// 整个图的灰度平均值 average = graymean;Log.i(TAG,"Average:"+average); for (int i = 0; i < width; i++) // 计算整个图的二值化阈值 { for (int j = 0; j < height; j++) { if (((gray[i][j]) & (0x0000ff)) < graymean) { graybackmean += ((gray[i][j]) & (0x0000ff)); back++; } else { grayfrontmean += ((gray[i][j]) & (0x0000ff)); front++; } } } int frontvalue = (int) (grayfrontmean / front);// 前景中心 int backvalue = (int) (graybackmean / back);// 背景中心 float G[] = new float[frontvalue - backvalue + 1];// 方差数组 int s = 0;Log.i(TAG,"Front:"+front+"**Frontvalue:"+frontvalue+"**Backvalue:"+backvalue); for (int i1 = backvalue; i1 < frontvalue + 1; i1++)// 以前景中心和背景中心为区间采用大津法算法(OTSU算法) { back = 0; front = 0; grayfrontmean = 0; graybackmean = 0; for (int i = 0; i < width; i++) { for (int j = 0; j < height; j++) { if (((gray[i][j]) & (0x0000ff)) < (i1 + 1)) { graybackmean += ((gray[i][j]) & (0x0000ff)); back++; } else { grayfrontmean += ((gray[i][j]) & (0x0000ff)); front++; } } } grayfrontmean = (int) (grayfrontmean / front); graybackmean = (int) (graybackmean / back); G[s] = (((float) back / area) * (graybackmean - average) * (graybackmean - average) + ((float) front / area) * (grayfrontmean - average) * (grayfrontmean - average)); s++; } float max = G[0]; int index = 0; for (int i = 1; i < frontvalue - backvalue + 1; i++) { if (max < G[i]) { max = G[i]; index = i; } } for (int i = 0; i < width; i++) { for (int j = 0; j < height; j++) { int in = j * width + i; if (((gray[i][j]) & (0x0000ff)) < (index + backvalue)) { pix[in] = Color.rgb(0, 0, 0); } else { pix[in] = Color.rgb(255, 255, 255); } } } Bitmap temp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); temp.setPixels(pix, 0, width, 0, 0, width, height); image.setImageBitmap(temp); }