温馨提示:本站仅提供公开网络链接索引服务,不存储、不篡改任何第三方内容,所有内容版权归原作者所有
AI智能索引来源:http://www.jianshu.com/p/36b1ed153524
点击访问原文链接

图像中二维码的检测和定位 - 简书

图像中二维码的检测和定位 - 简书登录注册写文章首页下载APP会员IT技术简创图像中二维码的检测和定位fengzhizi715关注赞赏支持图像中二维码的检测和定位
二维码

二维条码/二维码(2-dimensional bar code)是用某种特定的几何图形按一定规律在平面(二维方向上)分布的黑白相间的图形记录数据符号信息的;在代码编制上巧妙地利用构成计算机内部逻辑基础的“0”、“1”比特流的概念,使用若干个与二进制相对应的几何形体来表示文字数值信息,通过图象输入设备或光电扫描设备自动识读以实现信息自动处理:它具有条码技术的一些共性:每种码制有其特定的字符集;每个字符占有一定的宽度;具有一定的校验功能等。同时还具有对不同行的信息自动识别功能、及处理图形旋转变化点。

QR-Code-Overview.jpeg

定位图案

Position Detection Pattern是定位图案,用于标记二维码的矩形大小。这三个定位图案有白边叫Separators for Postion Detection Patterns。之所以三个而不是四个意思就是三个就可以标识一个矩形了。 Timing Patterns也是用于定位的。原因是二维码有40种尺寸,尺寸过大了后需要有根标准线,不然扫描的时候可能会扫歪了。 Alignment Patterns 只有Version 2以上(包括Version2)的二维码需要这个东东,同样是为了定位用的。

通过查找定位图案,可以实现二维码扫描的检测和定位。

检测和定位的步骤

先对图片进行灰度处理:

image = image.getImage().convert2Gray().getProcessor();
ByteProcessor src = ((ByteProcessor)image);

再对图像做二值化处理:

Threshold t = new Threshold();
t.process(src, Threshold.THRESH_OTSU, Threshold.METHOD_THRESH_BINARY_INV, 20);

然后是对y、x方向进行形态学上的开操作

 MorphOpen mOpen = new MorphOpen();
byte[] data = new byte[width*height];
System.arraycopy(src.getGray(), 0, data, 0, data.length);
ByteProcessor copy = new ByteProcessor(data, width, height);
mOpen.process(src, new Size(n1, n2)); // Y方向开操作
src.getImage().resetBitmap();

mOpen.process(copy, new Size(n2, n1)); // X方向开操作
CV4JImage cv4JImage = new CV4JImage(width,height);
((ByteProcessor)cv4JImage.getProcessor()).putGray(copy.getGray());

所谓开操作是指先腐蚀后膨胀的操作。在之前的文章二值图像分析:案例实战(文本分离+硬币计数)曾经介绍过开操作的用途。

import com.cv4j.core.datamodel.ByteProcessor;
import com.cv4j.core.datamodel.Size;

public class MorphOpen {

/**
* in order to remove litter noise block, erode + dilate operator
*
* @param binary
* @param structureElement
*/
public void process(ByteProcessor binary, Size structureElement) {
FastErode erode = new FastErode();
FastDilate dilate = new FastDilate();
erode.process(binary, structureElement, 1);
dilate.process(binary, structureElement, 1);
}
}

接下来是标记联通区域,找到二维码的三个特征区域,也就是定位图案。

 // 联通组件查找连接区域
ConnectedAreaLabel ccal = new ConnectedAreaLabel();
ccal.setFilterNoise(true);
List rectList = new ArrayList<>();
int[] labelMask = new int[width*height];
ccal.process(src, labelMask, rectList, true);
float w = 0;
float h = 0;
float rate = 0;
List qrRects = new ArrayList<>();
for(Rect roi : rectList) {

if (roi == null) continue;

if((roi.width > width/4 || roi .width height/4))
continue;

if((roi.x width -10)|| (roi.y height-10))
continue;

w = roi.width;
h = roi.height;
rate = (float)Math.abs(w / h - 1.0);
if(rate 

最后,通过定位图案能够找到二维码所在的区域,如果找不到会返回空的矩形。否则返回一个Rect,它表示找到的二维码所在图像中的区域。

我们可以对该区域进行标识,下面是算法的具体使用,找到图像中的二维码之后,用红色的边框框起来。

 CV4JImage cv4JImage = new CV4JImage(bitmap);

QRCodeScanner qrCodeScanner = new QRCodeScanner();
Rect rect = qrCodeScanner.findQRCodeBounding(cv4JImage.getProcessor(),1,6);

Bitmap bm = bitmap.copy(Bitmap.Config.ARGB_8888, true);
Canvas canvas = new Canvas(bm);
Paint paint = new Paint();
paint.setColor(Color.RED);
paint.setStrokeWidth((float) 10.0);
paint.setStyle(Paint.Style.STROKE);

android.graphics.Rect androidRect = new android.graphics.Rect(rect.x-20,rect.y-20,rect.br().x+20,rect.br().y+20);
canvas.drawRect(androidRect,paint);
image.setImageBitmap(bm);
定位图片中的二维码区域.png 定位有创意的二维码.png 截图微信的二维码.png

对于iPhone截屏之后的图片,该图片尺寸是1242 × 2208。在没有对图片做任何缩放处理的情况下,使用该算法进行定位二维码的区域也是ok的。


大图中的二维码.png

当然,对于大图如果适当地降采样处理或者缩放的话,算法速度会更快。

写在最后

彩色二维码和小程序的圆形二维码目前能够检测吗?
暂时不能。因为图像在二值化之后,彩色的部分像素点会变成白色的像素点,导致二维码轮廓不完整,最终导致无法实现二值分析。我们会在完成模版匹配的功能之后,继续优化算法完善该功能,加上检测彩色和圆形二维码的能力。

算法的源码位于cv4j的QRCodeScanner中,该算法不能识别二维码的字符串,只能找到二维码的区域,如果需要识别二维码还是需要使用Google Zxing。

总结

cv4j 是gloomyfish和我一起开发的图像处理库,纯java实现,目前还处于早期的版本。

文章中的算法是对二值图像分析的综合运用,使用它再结合Google的ZXing能够提高二维码的识别率。当然,由于它是pure java实现的,稍作改动能够用它来判断出某张图片中是否包含有二维码。

如果您想看该系列先前的文章可以访问下面的文集:
http://jianshu.zhutiblog.com/com/nb/10401400

最后编辑于 :2017.12.10 02:38:59©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。相关阅读更多精彩内容图像处理常用边缘检测算子总结不同图像灰度不同,边界处一般会有明显的边缘,利用此特征可以分割图像。需要说明的是:边缘和物体间的边界并不等同,边缘...大川无敌阅读 14,151评论 0赞 29Android - 收藏集Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...passiontim阅读 179,609评论 25赞 708挑战Python题解-0077.已知矩形长a,宽b,输出其面积和周长,面积和周长以一个空格隔开解法一:直接法 解法二:格式化字符串everfight阅读 347评论 0赞 0记我大学最难过的时光我想,我的大学里最难过的一段时光莫过于大三下学期。我不知道如果大三下的你是不是也跟我一样有同样的感受。看似很多的选...爱迷路的火龙果阅读 497评论 4赞 09月9号学习笔记1、二进制转十六进制 四位二进制表示一位十六进制,先把四位二进制转成十进制,再转成十六进制eg:10110110=...陈志龙阅读 641评论 0赞 0友情链接更多精彩内容鱼籽鱼泡的做法广州长隆免费停车攻略蛋糕什么样的好吃花生怎么做才能好吃到停不下来?比熊幼犬应该选择什么样的狗粮?长沙油爆虾的做法新平哀牢山旅游攻略江西值得去的景点常州一日游攻略引路人攻略你知道狗狗有哪些不同的类型吗?韩国攻略大全户外徒步装备如何挑选更实用?DeepSeek 新模型与 Claude 对比测评狗狗翻肠怎么办?有什么解决办法?给狗狗的话应该怎么说才最有效?丹霞山住宿攻略临沂市有什么好玩的地方旅游景点北海有什么好玩的地方卷心菜炒粉条的做法菠萝蜜什么样的好吃厦门自驾游有哪些必打卡的线路推荐?济南到上海自驾游攻略人民的名义:第一次常委会,沙瑞金的几处失误与官场逻辑的现实折射哪家店的宠物用品性价比最高?自制泰迪狗粮真的健康吗?上海游轮游攻略南宁附近旅游景点狗狗舔爪子是什么意思家庭宠物寄养需要注意哪些问题?评论19赞3535赞36赞赞赏手机看全文

图像中二维码的检测和定位 - 简书,AI智能索引,全网链接索引,智能导航,网页索引

    二维码 二维条码/二维码(2-dimensional bar code)是用某种特定的几何图形按一定规律在平面(二维方向上)分布的黑白相间的图形记录数据符号信息的;在代码编制...