精华内容
下载资源
问答
  • 有关zxing剪裁,线程池之类的就不说了, 简单扯一下从灰度上边做优化,为什么要用灰度优化? 因为你不出的东西, 剪裁的再小,线程再多也还是不出。 什么是灰度 要从这个方面入手就得先搞懂什么是灰度: 灰度...

    引言

    有关zxing剪裁,线程池之类的就不说了, 简单扯一下从灰度上边做优化,为什么要用灰度优化? 因为你扫不出的东西, 剪裁的再小,线程再多也还是扫不出。

    什么是灰度

    要从这个方面入手就得先搞懂什么是灰度: 灰度使用黑色调表示物体,即用黑色为基准色,不同的饱和度的黑色来显示图像。 每个灰度对象都具有从 0%(白色)到100%(黑色)的亮度值。 使用黑白或灰度扫描仪生成的图像通常以灰度显示。
    度娘搜出来的一端话。 简单来说就是不带任何色彩只有黑色到白色这段区间范围黑白电视展示出来的这种。 纯黑色值是0, 纯白色是255。大概了解后可以接着往下看

    灰度与YUV

    YUV是什么? 度娘说:是一种颜色编码方法。常使用在各个视频处理组件中。 YUV在对照片或视频编码时,考虑到人类的感知能力,允许降低色度的带宽。
    与RGB一对比就清楚了 , RGB我们都了解是红绿蓝三原色,根据不同的比例来展示不同的颜色, 那么一个像素就要存储RGB中各个信息也就是三个字节, 而描述中说到要降低色度的宽带那么目的就是降低每个像素的占用字节数。那么具体是如何实现的? YUV格式 这里不多说明(主要笔者我也不清楚这么多,不敢班门弄斧) 。好大概看了后我们清楚了YUV的数据格式排列, 要么是packed,要么是planar。 并且YUV中Y直接就是他的灰度值即上述说的范围(0-255)

    获取灰度值

    我们先以Camera2为例,Camera2如何获取YUV数据

            mYuvReader = ImageReader.newInstance(prelargest.getWidth(), prelargest.getHeight(),
                    ImageFormat.YUV_420_888, /* maxImages */ 2);
            mYuvReader.setOnImageAvailableListener(mOnYuvAvailableListener, null);
    

    大概看下这段代码, Camera2 在添加输出的时候是可以选定YUV的这里只谈YUV_420_888, 通过大量的资料查询了解到了YUV_420_888 是一种planar格式, 即, 先排列所有的Y, 在紧接着UV,UV…。 来看下他的获取

                Image.Plane[] planes = image.getPlanes();
                int remaining0 = planes[0].getBuffer().remaining();
                int remaining2 = planes[2].getBuffer().remaining();
                byte[] yRawSrcBytes = new byte[remaining0];
                byte[] uvRawSrcBytes = new byte[remaining2];
                byte[] nv21 = new byte[remaining0 + remaining2];
                planes[0].getBuffer().get(yRawSrcBytes);
                planes[2].getBuffer().get(uvRawSrcBytes);
         
                System.arraycopy(yRawSrcBytes, 0, nv21, 0, yRawSrcBytes.length);
                System.arraycopy(uvRawSrcBytes, 0, nv21, yRawSrcBytes.length, uvRawSrcBytes.length);
    

    上边这些代码按道理planes[0].getBuffer().get(yRawSrcBytes)即输出的Y,
    planes[2].getBuffer().get(uvRawSrcBytes)输出V啊, 那U去那了??? 通过查阅了解到底层封装的时候为了上层好处理,把VU和UV封装到了一起,那么我们直接取UV即可。 这里最后的NV21 便是最后一个完整YUV数据组。

    再聊聊Camera1的,

     mCamera.setPreviewCallback((data, camera) ->
                            mCallback.onPreviewByte(data));
    

    在Camera1中我们都是通过这步操作来获取实时的数据, 其实这种数据默认就是NV21的,也就是YUV_420,并且格式为Y,Y,…U,V…。

    如何优化

    上边这么多就是为此时做铺垫。首先我们看看Zxing里边是如何读取数据的,我们知道他读取的是YUV格式, 那么到底仅仅只是Y,还是说UV也参与其中?

      public byte[] getMatrix() {
            int width = getWidth();
            int height = getHeight();
    
            // If the caller asks for the entire underlying image, save the copy and give them the
            // original data. The docs specifically warn that result.length must be ignored.
            if (width == dataWidth && height == dataHeight) {
                return yuvData;
            }
    
            int area = width * height;
            byte[] matrix = new byte[area];
            int inputOffset = top * dataWidth + left;
    
            // If the width matches the full width of the underlying data, perform a single copy.
            if (width == dataWidth) {
                System.arraycopy(yuvData, inputOffset, matrix, 0, area);
                return matrix;
            }
    
            // Otherwise copy one cropped row at a time.
            for (int y = 0; y < height; y++) {
                int outputOffset = y * width;
                System.arraycopy(yuvData, inputOffset, matrix, outputOffset, width);
                inputOffset += dataWidth;
            }
            return matrix;
        }
    

    这是PlanarYUVLuminanceSource 类中的一步剪裁操作。 可以看到剪裁的截止是area = width * height; 即像素的个数, 而YUV的总长是Y+U+V的长度, 很显然跳过了UV, 仅仅只需要灰度Y。 那么图像能不能扫出来只取决于Y的值。好, 为了直观表现出来, 我只读取了YUV中Y的值然后做成了图片,操作如下

    
                byte[] cropNv21 = new byte[nv21.length / 2 * 3];
    
                for (int i = 0; i < w * h; i++) {
                    cropNv21[i] = nv21[i];
                }
                for (int i = 0; i < w * h / 2; i++) {
                    cropNv21[nv21.length + i] = (byte) 0b10000000;
                }
                System.arraycopy(cropNv21, 0, cropNv21, 0, w * h);
    
                YuvImage yuvImage = new YuvImage(cropNv21, ImageFormat.NV21, w, h, null);
    
                try {
                    yuvImage.compressToJpeg(new Rect(0, 0, w, h), 100, new FileOutputStream(file));
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                }
    
    

    由于我是在zxing截取后操作的, 截取后没了UV数据为了输出一张完整的图片只能手动添加一些UV, 经实测给二进制 0b10000000也就是十进制-128能得到纯的灰度值图片。

    UV值为-128

    当UV值为0如下,所以猜测UV的解析值范围为 [-128 ,127]
    UV值为0
    好这样就清楚了 , 我们把扫不出的码转成灰度图, 看它到底长什么样。。
    这是一张彩色二维码
    在这里插入图片描述
    转换后
    在这里插入图片描述
    我们不用关注Zxing源码到底是如何扫出来的(太复杂即使勉强看懂也很难从本质上做出修改🌝🌝当然算法牛人略过),但是根据转换后的灰度图可以清楚看到, 上半部分分颜色偏白 。 所以我们要做的不是修改Zxing源码,而是尽可能保证图像更贴近一个规整的二维码图像。

    伽马增强

    在这里插入图片描述
    在这里插入图片描述
    观察上图在某些等级r范围内,输入的灰度级越大输出变化越小, 输入的越小变化越大, 而为了保证白色底色变化小,黑色再黑也没关系, 浅黑色能加深一些即可, 所以我选定的区间是[3,7],给一个4看看输出的效果

     for (int i = 0; i < w * h; i++) {
                    cropNv21[i] = (byte) (255 * Math.pow((cropNv21[i] & 0xff) / 255f, 4f));
                }
    

    在这里插入图片描述这时候拿出我们的zxing,我擦成了。

    总结:java中伽马优化由于频繁调Math.pow还是比较吃性能, 后期可以想办法优化。

    线性增强

    来看下这种二维码
    在这里插入图片描述
    没有任何色彩, 灰度化后跟原图应该是差不多, zxing扫不出的原因就是理应的黑色区域灰度值过高,这里要想办法降低。这里笔者经过大量测试发现一个极其巧妙的处理方式

         byte[] newByte = data.clone();
            short random = (short) (Math.random() * 4 + 3);
            for (int i = 0; i < width * height; i++) {
                newByte[i] = (byte) (newByte[i] * random);
            }
    

    上边运算等同于( newByte[i] & 0xff ) % 250 , 没错, 一个灰度值恰好大于255存储在一个字节里相当于又从0开始, 白色瞬间成黑色, 而且由于线性扩大,黑色和白色差值越来越大。
    看看处理后效果
    在这里插入图片描述
    搞定。

    总结: 由于没有接入openCv,识别能力取决于适配的程度, 这个还是比较困难, 但是优点也很明显,非常轻量。几k基本就能处理一类。

    关注我的github持续更新, 一个很完善的扫码库。

    github

    NBZxing

    展开全文
  • Android对ZXing扫码工具界面定制和扫码效率优化做了讲解,博客地址http://blog.csdn.net/ahuyangdong/article/details/76407722。最新的lib版本:https://github.com/ahuyangdong/QrCodeLib
  • 可能是你已经找了很久的Zxing扫码优化方案 【原创文章】转载请标记出处。-----拉婓Laughing---- 关于在Unity3D中,Zxing-二维码解析的优化方案(下附代码) Zxing是Unity开发移动,PC端程序的常用二维码插件,...

    【原创文章】转载请标记出处。-----拉婓Laughing----

    关于在Unity3D中,Zxing-二维码解析的优化方案(下附代码)

    Zxing是Unity开发移动,PC端程序的常用二维码插件,简单轻便,极易上手。笔者在工作中,也经常使用Zxing来开发项目,好用归好用,笔者也遇到不少Zxing乏力的场景,比如** “浅色的二维码” **,无法高效快速的进行扫码解析等。因此花时间对Zxing的扫码代码研究了一下,并对原来的扫码功能进行了优化,还算OK,项目使用足够了。

    ==============================================================================================

    疑难与挑战

    在实际项目中,发现现有的Zxing二维码库,对于浅色二维码的进行扫码,特别在昏暗的环境中,二维码图像还原度不高的情况下,解析效率很低。

    二维码解析属于常规高频技术模块,需要针对这一问题,进行有效改善。

    下附笔者需要扫描的二维码(二维码在移动设备的屏幕上显示,需要用户的手机去扫描,环境昏暗,条件更加苛刻)

    笔者需要扫描的二维码

    问题分析

    1.笔者将摄像头获取到的黄色二维码图像,进行灰度图转换处理,(为了处理成跟正常的黑白色二维码尽量相近),发现黄色和白色的灰度图颜色十分相近,造成了Zxing解析困难。
    2.笔者对比了微信,支付宝等扫码界面,发现虽然有聚焦的小窗口提示用户将二维码放置在窗口内,但是实际上二维码没有在窗口内完整显示,也能扫码成功,且扫码速度很快。
    3.笔者阅读了更为底层的Zxing扫码的代码,发现Zxing对于二维码解析的方法,主要有两种

    (1)HybridBinarizer二值化方法
    (2)GlobalHistogramBinarizer

    考虑合理的选择解析方法进行实际应用。
    总结一下,优化研发的落脚点为:

    1.二维码图像预处理
    2.扫码方法的选择
    3.功能模块的源码优化


    既然找到了着手点,笔者开始了实践。

    研发纪要
    主要解决方案:
    1.考虑到利用CPU对二维码图像进行预处理的效率不高,容易对扫码速度产生消极影响,故优先着手对Zxing扫码库的扫码方法进行选择优化。

    二维码组成:
    二维码组成

    通过对源码的阅读以及查阅众多资料,了解到Zxing的扫码原理步骤为:

    1.获取摄像头采集图像的原始数据(Byte[])

    2.将图像进行灰度图的转化。

    3.将变成灰度图的图像进行直方图的检测,区分二维码实际参与解析的有效像素。

    4.将单元图像,投入Zxing的扫码方法,进行解析。(主要涉及到的方法为:(1)HybridBinarizer二值化方法 (2)GlobalHistogramBinarizer)

    =========================================================================================

    第一步扫码图像的预处理及扫码方法的选择

    我们筛选掉一开始的对图像提取Color32的像素信息,直接黑盒调用Zxing的扫码方法。采用上述步骤对二维码进行解析。

    又考虑到,实际我们参与扫码的二维码已黑白色为主,而仅在此情况下进行扫码,GlobalHistogramBinarizer的效率要高于HybridBinarizer,减少了图像二值化的处理。故优先固定为GlobalHistogramBinarizer方法进行解析。

    在对图像进行灰度图进行转化时,考虑到转换后的二维码像素精度,使用YUV替代初始的RGB色彩空间,对获取到的图像进行保存。

    2.如上操作后,二维码的解析速度已经得到了一定的提升,并且可以扫描出上图中黄色的二维码。但是随后又发现,浅蓝色等灰度值偏高的二维码难以被解析出来,怀疑是GloblaHistogramBinarizer内部的算法影响。

    故在整体的扫码方法设计上,我们采用两步进行:如果第一种基础扫码已经完成扫码,则结束;如果扫不出来,则进入第二步重新扫码。

    第二步扫码方案的逻辑优化:

    在黑盒调用Zxing解析图像的方法之前,将图片转换为二值图。对于二值转换的阈值选取,采用“均值计算”得到,经处理后,传入一开始的解析方法,对二维码进行解析。

    第三步将原来的二维码识别区域,调整为全部摄像头画面。

    模仿微信,支付宝等扫码功能,将原来限制的二维码识别区域,调整为全部摄像头画面

    参考代码
    while(true)
            {
                if(decoding&& te != null)
                {   
                    orginalc = te.GetPixels32();
                    z = 0;
                    // convert the image color data
                    for (int y = H - 1; y >= 0; y--)
                    {
                        for (int x = 0; x < W; x++)
                        {
    
                            targetbyte[z++] = (byte)(((int)orginalc[y * W + x].r) << 16 | ((int)orginalc[y * W + x].g) << 8 | ((int)orginalc[y * W + x].b));
                        }
                    }  
                    
                  //采用YUV色彩空间,对图像进行灰度图转化
                    PlanarYUVLuminanceSource planarYUV = new PlanarYUVLuminanceSource(targetbyte, W, H,0,0,W,H,false);
                    var bitmap = new BinaryBitmap(new GloblaHistogramBinarizer(planarYUV));
                    Result data;
                    var reader = new MultiFormatReader(); 
                    data = reader.decode(bitmap);
                    if (data != null)
                    {
                        {
                            decoding = false;
                            dataText = data.Text;
                            Debug.Log(dataText+ e_QRScanFinished.ToString());
                            e_QRScanFinished(dataText);
                        }
                    }
                  
                  //如果上述步骤扫码不成功,则转入下列方法,对图像预处理后,再直接对图像进行解析
                    else
                    {
                        
                        yield return new WaitForEndOfFrame();
                        Color[] color = te.GetPixels();
                        float res=0;
                      //选取二值化的阈值
                        for(int i = 0; i < color.Length; i++)
                        {
                            res += (color[i].r + color[i].g + color[i].b) / 3; 
                        }
                        res /= color.Length;
                      //二值化的实际处理
                        for (int i = 0; i < color.Length; i++)
                        {
                            if((color[i].r+color[i].g+color[i].b)/3<res)
                            {
                                color[i] = Color.black;
                            }
                            else
                            {
                                color[i] = Color.white;
                            }
                        }   
                        texTemp.SetPixels(color);
                        texTemp.Apply();         
                        data = DecodeByStaticPic(texTemp);
                        if (data != null)
                        {
                            {
                                decoding = false;
                                dataText = data.Text;
                                Debug.Log(dataText);
                                e_QRScanFinished(dataText);
                            }
                        }
                    }
                }
    

    问题与风险

    经实际测试:

    对二维码前景为下列色盘中的任意色进行了扫码测试,除了标记出来的极端色块,因影响过大,难以解析外,其余颜色都解析成功,利用PC编辑器和罗技C920摄像头,扫码解析的平均时间,在1.5-3.0秒左右。

    测试扫码色块的示意图
    【原创文章】转载请标记出处。-----拉婓Laughing----【2019-5-13】

    展开全文
  • https://toutiao.io/posts/d5buuo/preview https://github.com/jenly1314/ZXingLite
    展开全文
  • Android Zxing 二维码扫码性能优化

    千次阅读 2016-08-30 14:44:49
    最近再一次做到了扫码项目,扫码出现的扫码性能问题再次摆上了案头,经过自己研究并与同行沟通后得出了目前自己能做到的对扫码性能优化的处理。 1、精简解码码制 目前 github 上 Zxing 支持的码制 ...

    最近再一次做到了扫码项目,扫码出现的扫码性能问题再次摆上了案头,经过自己研究并与同行沟通后得出了目前自己能做到的对扫码性能优化的处理。

    1、精简解码码制

    目前 github 上 Zxing 支持的码制


    国内常用的有二维码 QR Code 以及各种条码

    在这里具体做法就是在支持解码类与解码库把可解码裁剪为只剩下自己项目需要的码制。(重中之重,个人经验,这个对性能提高最有效)


    2、扩大扫码截图大小

    在使用中发现,Zxing 提供的源码与网上很多 Demo 都有这么个问题,扫码的时候把二维码完全填充的扫描框里边的时候是解析不出来了,反而把扫码距离放远立马就能扫描到信息了。分析是扫描截图,解析图片时二维码过大导致。尝试增大截图大小之后性能显著提升。在这里结合之后沟通得出的经验,这个截图增大在宽高100px。具体的结合自己的实际情况调整。


    3、缩短自动聚焦的间隔时间

    Zxing 默认的聚焦间隔时间是2000毫秒。扫码是在每一次调用相机聚焦完成后触发回调取图解析的。在这里缩短聚焦时间会提高解析频率,扫码性能自然就提升了。当然也有不好的地方,提高了聚焦的频率,对手机电量的消耗自然增加了。我这里是把聚焦间隔修改成了1000毫秒,这个依据手机硬件的性能修改,不同厂家的手机对相机聚焦的处理是不同的,如果你设置的这个聚焦间隔时间小于了手机厂家默认设计的相机聚焦间隔就会导致程序的崩溃。这个设置请慎重使用。


    其他的方案据说还有对解码算法的优化,限于技术水平与时间,暂时就没去研究算法的优化,如果有人有对算法优化比较好的案例。欢迎分享学习。

    展开全文
  • 本篇文章已授权微信公众号 guolin_blog (郭霖)独家发布引言本篇博文是基于 Android 二维码的扫码功能实现(一) 文章写的,建议阅读这篇文章之前,先看看上篇文章。还有建议阅读本文的同学,结合zxing的源码理解。...
  • Android Zxing二维码扫描优化

    千次阅读 2019-07-03 10:06:03
    关于Zxing的使用,网上有大量...https://github.com/BayMax-Yi/BayMaxScanner 该库基于zxing做了修改,优化二维码、条形识别的速度。以及封装了生成二 维码,条形功能。话不多说,先上效果图: 扫描二维码 ...
  • Android Camera结合Zxing优化扫码

    千次阅读 2017-08-04 12:44:09
    由于之前集成的zxing扫塑料上面的不太好扫,决定优化。Zxing的解码我们优化不了了,经过测试,是因为亮度不够,所以最终选择在灯光和放大焦距完成了最终的优化。 设置模式只需要几行代码即可://得到Camera对象 ...
  • 对Android zxing二维码扫描个人优化版的优化,增加了横竖屏、前后置摄像头的配置,配置文件QRCodeSConfig.java,使用的是zxing3.2.0版本。手机和平板测试都没问题。
  • 主要介绍了C# Xamarin利用ZXing.Net.Mobile进行扫码的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
  • zxing扫码demo

    2017-05-24 14:40:48
    扫码代码,zxing源码demo,优化后直接支持横竖屏
  • 对zxing进行优化的思考 前言 对于Google 的开源框架...Android 基于Zxing扫码实现(三)、从相册选取二维码 Android 二维码开发功能实现(四)------基于Zxing实现编码功能(生成二维码,一维码等) 日常关于条码的...
  • 手机具备条码扫描的功能,可以优化购物流程,快速存储电子名片(二维码)等。 本文所述实例就使用了ZXing 1.6实现条码/二维码识别。ZXing是个很经典的条码/二维码识别的开源类库,早在很久以前,就有开发者在J2ME上...
  • 本人在做公司项目,使用zxing以后发现扫描公司开发产品上的二维码比较慢,想优化扫描速度不知从何入手 , 扫描时候的聚焦速度比较慢,有没有懂路的人指点一下
  • 关于zxing扫码界面的优化

    千次阅读 2017-04-08 23:22:54
    关于zxing扫码界面的优化
  • ZXingLite for Android 是ZXing的精简版,优化扫码和生成二维码功能,扫码界面支持完全自定义,让集成更简单。 Gif 展示 ViewfinderView属性说明 属性 值类型 默认值 说明 maskColor color #...
  • 精简版ZXing库,快速实现扫码功能,让集成更简单.zip,ZXing的精简版,优化扫码和生成二维码/条形码功能,扫描风格支持:微信的线条样式,支付宝的网格样式。几句代码轻松拥有扫码功能 ,ZXingLite让集成更简单。(...
  • 一句话依赖就能实现功能,包含闪光灯开关,拾取本地图片解析,生成二维码(可带徽标)功能等。 如果直接依赖不满足你的需求,需要自己修改样式或二进制的话,可以放入库作为模块集成到你的项目中,集成方法...
  • Android zxing二维码扫描个人优化
  • Zxing扫码流程梳理

    千次阅读 2016-09-20 18:26:02
    最近在优化扫码功能,对Zxing提供的demo做了一个梳理
  • 《Android实现二维码扫描功能》系列文章陆续收到不少开发者的反馈,看到大家这么关注这个专栏,最近抽空对ZXing扫码和生成二维码又做了优化,封装了一个Android library:zxing-lib,这样在接入应用的过程中会更加...
  • ZXingLite for Android 是ZXing的精简版,基于ZXing优化扫码和生成二维码/条形码功能,扫码界面完全支持自定义,也可一行代码使用默认实现的扫码功能。总之你想要的都在这里。 简单如斯,你不试试? Come on~ Gif ...
  • ZXing.NET C#使用ZXing识别二维码,条形 包含VS2008至2017版本
  • android扫码优化

    千次阅读 2019-06-28 10:15:04
    现在一维码二维码在我们的日常生活中使用如此的广泛,所以拥有扫码功能的APP变得非常普遍,一个安卓APP需要扫码功能就要用到zxing了,zxing是谷歌开源的让开发者更方便使用摄像头的库,而我们常用的扫码功能就是其中...
  • zxing扫码--镭射线

    2015-09-16 09:48:00
    同步发表于...Google出品的zxing时比较出名的二维码扫描库,但是和其他开源组件不同,zxing包含了很多东西,同时github上的官方实例也较为复杂,如果初次接触,要很快集成扫码并自定UI并不容易; 本文通...
  • zxing 二维码扫描优化

    千次阅读 2018-04-11 18:16:59
    先罗列优化点:1.优化扫描精度 (增加解析成功率)hints.put(DecodeHintType.TRY_HARDER, Boolean.TRUE); 2.生成图片(用于被解析)时不剪切图片(增加二维码图片的完整性)优化前:new PlanarYUVLuminanceSource...
  • 利用谷歌zxing,高仿微信扫一扫,轻松实现自定义扫一扫UI,实现扫码功能需求。最新优化上传于2018.12.已验证通过。
  • 还在用 ZXing ? 试试华为统一扫码服务吧!

    千次阅读 多人点赞 2021-05-26 21:51:05
    Android 项目开发过程中,扫码场景使用最多的开源库是 ZXing ,Github 上针对 ZXing优化和二次封装不胜枚举,但是 Zxing 的缺陷在于只是实现了扫码的一些基础操作,对于更为复杂的扫码环境比如强光,弯曲,形变等...
  • 超简单集成Android Zxing实现二维码

    万次阅读 多人点赞 2016-10-13 10:54:35
    最新版本的请看http://blog.csdn.net/yuzhiqiang_1993/article/details/78292004,优化了扫描速度,修复了一些bug,增加了闪光灯,解析二维码图片,生成二维码等功能,简化了集成步骤。 因为按下文方法集成...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 496
精华内容 198
关键字:

zxing扫码优化