安卓图片二值化实现

最近应用在使用zxing进行二维码扫描时,发现对于金属质地,黑色凹槽的二维码识别率非常低且耗时很长,所以就有了探究二维码识别原理的想法。

正文

      先灰度化再二值化是图片识别非常重要的一步,能够方便的提取图片特征。

      原理是,将图片的灰度设定一个阈值,高于这个阈值的点变为黑色,低于这个阈值的点变为白色,这样能很方便的判断图片特征。

      通用的灰度公式是:gray=r*0.3+g*0.59+b*0.11

      获取颜色的argb方式:

alpha=color >>> 24

red=(color >> 16) & 0xFF

green=(color >> 8) & 0xFF    

blue=color & 0xFF

      生成颜色的方式:color=(alpha << 24) | (red << 16) | (green << 8) | blue

      获取图片的color信息:

Bitmap对象.getPixels(@ColorInt int[] pixels, int offset, int stride,int x, int y, int width, int height)

  • pixels  接收位图颜色的数组
  • offset  第一个写入像素的索引[]
  • stride  行之间要跳过的项目数(以像素[]为单位)(必须大于等于位图的宽度)。可能是负面的。
  • x       从位图中读取的第一个像素的x坐标
  • y       从位图中读取的第一个像素的y坐标
  • width    从每行读取的像素数
  • height   要读取的行数

      写入图片的color信息:

Bitmap对象.setPixels(@ColorInt int[] pixels, int offset, int stride,nt x, int y, int width, int height) 方法:用数组中的颜色替换位图中的像素。 

  •  pixels   要写入位图的颜色
  •  offset   从像素[]读取的第一种颜色的索引
  •  stride   要在行之间跳过的颜色数(以像素为单位)。通常,该值与位图的宽度相同,但可以更大(或负值)。
  •  x        位图中要写入的第一个像素的x坐标。
  •  y        位图中要写入的第一个像素的y坐标。
  •  width    每行从像素[]复制的颜色数
  •  height   要写入位图的行数

完整代码:

 public static Bitmap singleThreshold(final Bitmap bm,int digit) {

        int width = bm.getWidth();
		int height = bm.getHeight(); 
        int color;
		int r, g, b, a;
		
        Bitmap bmp = Bitmap.createBitmap(width, height
                , Bitmap.Config.ARGB_8888);//创建一个图片对象

        int[] oldPx = new int[width * height]; 
        int[] newPx = new int[width * height]; 
        bm.getPixels(oldPx, 0, width, 0, 0, width, height); //获取图片的颜色像素

        for (int j = 0; j < width * height; j++) {     
			//获取单个颜色的argb数据
			color = oldPx[j];
			r = Color.red(color); 
            g = Color.green(color); 
            b = Color.blue(color); 
            a = Color.alpha(color); 
            //计算单点的灰度值
			int gray = (int)((float)r*0.3+(float)g*0.59+(float)b*0.11);
			//根据阈值对比,低于的设置为黑色,高于的设置为白色
            if(gray < digit) {
			gray = 0; 
            } else {
			gray = 255; 
            }
            newPx[j] = Color.argb(a,gray,gray,gray);
			}
         
        bmp.setPixels(newPx, 0, width, 0, 0, width, height);
        return bmp;
    }

你可能感兴趣的:(安卓,android,java)