项目复盘总结

开发需求:

在桌面机器人(向下俯视)摄像头拍摄到的图像中做条形码识别与二维码识别。

条形码在图像固定位置,二维码做成卡片的形式在固定区域内随意摆放。

开发环境及相关库:ubuntu 18.04 + Clion + opencv4.1.0 + zxing + zbar

开发思路及识别流程:

摄像头拍摄图像分辨率为640*480

1. 图像画面还原校正

由于摄像头(俯视)拍摄到的图像存在线性的透视偏差,类似于车辆行驶的车道线,两条相交的直线,因为透视效应直线向视距远处集中。

此处采用透视变换还原图像为正视图,这里存在一个倾角计算的问题。

根据图像分辨率与实际物体大小的比例进行计算,得出透视变换所需的四个基本点。

2. 抓取条形码区域

由于识别条形码的位置为固定,确定了矫正方式后,因此就有以下几种方式将条形码矫正回来。

(1)将截取的固定区域做透视变换区域

(2)将整个图像画面做透视变换区域,再做整个画面的区域截取。

经过验证,最终采用(2)方式,因为摄像头出厂设置有相对误差,不容易计算透视变换的四个基本点。

而针对整个画面和实际图像的比例可以基本确定,故通过(2)要优化(1)。缺点是透视变换的矩阵太大,会加长总时间。

3.抓取二维码区域

由于二维码卡片在整个画面中的位置是随机摆放的,同时二维码卡片与画面背景之间有严格的边界。

因此考虑从二维码卡片的轮廓入手,这是抓取卡片区域的大方向。

如何将二维码轮廓与背景其他轮廓分开,这里涉及到比较针对性的预处理方式。

考虑以下几种方式

(1)从Canny图像中查找到的轮廓集合做面积和长宽比例限制上的筛选,调整相关参数,从而得出符合要求的二维码区域

(2)针对查找的轮廓集合做多边形拟合,卡片为四边形区域,因此拟合顶点为4。

(3)在查找的轮廓中,根据二维码的三个矩形区域做轮廓层级的hierarchy层级筛选

经过验证,最终采用(2)方式,虽然(1)也能截取到二维码区域,但卡片区域轮廓的包围矩形无法修正透视变换后存在的形变拉伸,以及存在无法识别到旋转倾斜角度过大的问题。

使用(2)方式的好处是,经过拟合后的四边形轮廓可以直接得到卡片区域的四个角点。

但使用轮廓拟合方式也存在一定的问题,即拟合到的四边形轮廓数量过多,实际上只需要一个。因此需要将多余的筛选掉。

同时四边形轮廓的角点在轮廓集合内是无序的,因此需要根据需求,将四个角点进行与透视变换对应的排序。

照猫画虎,根据排序好的四个角点代入到透视变换,得出校正正视图。此处透视变换的参数,为了与二维码的长宽比适应,透视变换的size长宽比设置为1:1

   

4.识别条形码与二维码

由于zxing和zbar库在性能与识别率上各有千秋,总体来说在当前集成的环境中,zbar高于zxing,但zbar识别不到的部分能被zxing识别出来。

因此考虑使用zxing与zbar混合识别的方式,先走zbar后走zxing。

遇到的问题及相关解决方案:

1.硬件问题:摄像头角度倾角过大

从而导致透视变换处理之后的图像仍然达不到识别库的要求。

解决方案:摄像头硬件参数调校。

2.环境:光照问题

在强光照射下,二维码的部分黑色区域由黑色转变成绿色或红色,造成一定程度上的失真。

解决方案:自适应亮度调节,亮度增强

3.图像矫正本身的缺陷

透视变换的插值方式会在一定程度上造成图像失真或增强不必要的白噪声。

默认使用的是 INTER_LINEAR 方式,经测试验证,INTER_CUBIC方式更加适合条形码与二维码在变换中的插值。

/***
* 默认插值方式 INTER_LINEAR = 1 双线性插值
* INTER_NEAREST = 0最近邻插值
* INTER_CUBIC = 2 三次样条插值
* INTER_AREA = 3 区域插值.图像放大时类似于线性插值,图像缩小时可以避免波纹出现。
* INTER_LANCZOS4 = 4 使用8×8像素邻域的Lanczos插值
* INTER_LINEAR_EXACT = 5 位精确双线性插值
* INTER_MAX = 7 插值码掩码
* WARP_FILL_OUTLIERS = 8 标志,填充所有目标图像像素。如果其中一些与图像,设置为零
* WARP_INVERSE_MAP = 16 标志,反变换
*/

[opencv]二维码识别开发流程及问题复盘总结的更多相关文章

  1. [opencv]二维码识别率提升方案-resize调整

    这里采用循环resize的方式,对二维码图像进行放缩. 识别到name(二维码结果)不为空,则立即退出循环 //循环识别 for (int i = 1;name.empty(); i++){ resi ...

  2. 基于opencv+python的二维码识别

    花了2天时间终于把二维码识别做出来了,不过效果一般,后面会应用在ROS辅助定位上,废话少说先上图: 具体过程参考了这位大神的博客:http://blog.csdn.net/qq_25491201/ar ...

  3. Opencv+Zbar二维码识别(二维码校正)

    二维码和车牌识别基本都会涉及到图像的校正,主要是形变和倾斜角度的校正,一种二维码的畸变如下图: 这个码用微信扫了一下,识别不出来,但是用Zbar还是可以准确识别的~~. 这里介绍一种二维码校正方法,通 ...

  4. android 图片二维码识别和保存(二)

    续上一篇,开发图片二维码识别功能后,我们对功能进行性能分析内存占用显著提高了,不使用该功能内存占用大约是147M,使用这个功能多次以后,高达203M. 因此对功能进行研究,发现每次生成的图片没有即时的 ...

  5. Python zxing 库解析(条形码二维码识别)

    各种扫码软件 最近要做个二维码识别的项目,查到二维码识别有好多开源的不开源的软件 http://www.oschina.net/project/tag/238/ Zbar 首先试了一下Zbar,pyt ...

  6. 基于opencv3.0和下的条形码与二维码识别

    其中对条码与二维码的识别分为以下4个步骤 1. 利用opencv和Zbar(或者Zxing)对标准的条形码图片(即没有多余背景干扰,且图片没有倾斜)进行解码,将解码信息显示出来,并与原始信息对比. 2 ...

  7. android 图片二维码识别和保存(一)

    最新业务开发二维码识别的功能,这个功能,在很多应用上都有,比如微信长按图片识别二维码,如果图片中存在可以识别的二维码时,可以增加一个选项 识别二维码.那么如何去实现这个功能呢.这里其实也非常简单,首先 ...

  8. 使用zxing二维码识别

    1.多二维码识别 (同一张图片中多二维码识别) 直接上代码舒服: pom文件: <!-- QR Code --> <dependency> <groupId>com ...

  9. 第47章 QR-Decoder-OV5640二维码识别—零死角玩转STM32-F429系列

    第47章     QR-Decoder-OV5640二维码识别 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.y ...

随机推荐

  1. C++异常处理(try、catch、throw)

    本文为转载 博主原文连接 我们通常希望自己编写的程序能够在异常的情况下也能作出相应的处理,而不至于程序莫名其妙地中断或者中止运行了.在设计程序时应充分考虑各种异常情况,并加以处理. 在C++中,一个函 ...

  2. Linux常用命令之文件权限管理

    Linux文件权限管理1.改变文件或目录的权限:chmod命令详解命令名称:chmod命令所在路径:/bin/chmod执行权限:所有用户语法:chmod [{ugoa}{+-=}{rwx}] [文件 ...

  3. Logback设置保留日志文件个数

    Logback日志文件占用存储空间太多,设置保留文件个数,清理之前的文件. 主要由如下三个参数配合使用 maxHistory ,可选节点,控制保留的归档文件的最大数量,超出数量就删除旧文件,,例如设置 ...

  4. hive 启动不成功,报错:hive 启动报 Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/hadoop/mapred/MRVersi

    1. 现象:在任意位置输入 hive,准备启动 hive 时,报错: Exception in thread "main" java.lang.NoClassDefFoundErr ...

  5. lambda表达式快速创建

    Java 8十个lambda表达式案例 1. 实现Runnable线程案例 使用() -> {} 替代匿名类: //Before Java 8: new Thread(new Runnable( ...

  6. linux查询健康状态,如何直观的判断你的Linux系统是否健康

    一提到对于查看系统运行的健康状况,可能大多数朋友考虑到的就是查看进程或者打开任务管理器,但是对于应用在真实生产环境中服务器的linux系统来说,以上两种方式都不是***效的查看方式,那么今天就给大家推 ...

  7. Spring Boot事务支持

    一.创建项目 二.添加依赖 <dependencies> <dependency> <groupId>org.projectlombok</groupId&g ...

  8. 【Java 8】函数式接口(二)—— 四大函数接口介绍

    前言 Java8中函数接口有很多,大概有几十个吧,具体究竟是多少我也数不清,所以一开始看的时候感觉一脸懵逼,不过其实根本没那么复杂,毕竟不应该也没必要把一个东西设计的很复杂. 几个单词 在学习了解之前 ...

  9. matplotlib画直线图的基本用法

    一  figure使用 1 import numpy as np 2 import matplotlib.pyplot as plt 3 4 # 从-3到中取50个数 5 x = np.linspac ...

  10. 南邮CTF-MISC-Remove Boyfriend

    Remove Boyfriend 打开wireshark,找到关键字部分Remove Boyfriend 在第五行 在此行右击 点击追踪流 选择TCP流,可以分析出流量的传输过程 通过上面的执行列表 ...