安卓图片二值化实现
安卓实现图片单阈值二值化
·
最近应用在使用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;
}
更多推荐
已为社区贡献7条内容
所有评论(0)