二维码和车牌识别基本都会涉及到图像的校正,主要是形变和倾斜角度的校正,一种二维码的畸变如下图:

这个码用微信扫了一下,识别不出来,但是用Zbar还是可以准确识别的~~。

这里介绍一种二维码校正方法,通过定位二维码的4个顶点,利用仿射变换校正。基本思路:滤波->二值化->膨胀(腐蚀)操作->形态学边界->寻找直线->定位交点->仿射变换校正->Zbar识别。

滤波、二值化:

腐蚀操作:

形态学边界:

寻找直线:

角点定位:

仿射变换校正:

Zbar识别:

Code实现:

#include "zbar.h"
#include "cv.h"
#include "highgui.h"
#include <iostream> using namespace std;
using namespace zbar; //添加zbar名称空间
using namespace cv; int main(int argc,char*argv[])
{
Mat imageSource=imread(argv[1],0);
Mat image;
imageSource.copyTo(image);
GaussianBlur(image,image,Size(3,3),0); //滤波
threshold(image,image,100,255,CV_THRESH_BINARY); //二值化
imshow("二值化",image);
Mat element=getStructuringElement(2,Size(7,7)); //膨胀腐蚀核
//morphologyEx(image,image,MORPH_OPEN,element);
for(int i=0;i<10;i++)
{
erode(image,image,element);
i++;
}
imshow("腐蚀s",image);
Mat image1;
erode(image,image1,element);
image1=image-image1;
imshow("边界",image1);
//寻找直线 边界定位也可以用findContours实现
vector<Vec2f>lines;
HoughLines(image1,lines,1,CV_PI/150,250,0,0);
Mat DrawLine=Mat::zeros(image1.size(),CV_8UC1);
for(int i=0;i<lines.size();i++)
{
float rho=lines[i][0];
float theta=lines[i][1];
Point pt1,pt2;
double a=cos(theta),b=sin(theta);
double x0=a*rho,y0=b*rho;
pt1.x=cvRound(x0+1000*(-b));
pt1.y=cvRound(y0+1000*a);
pt2.x=cvRound(x0-1000*(-b));
pt2.y=cvRound(y0-1000*a);
line(DrawLine,pt1,pt2,Scalar(255),1,CV_AA);
}
imshow("直线",DrawLine);
Point2f P1[4];
Point2f P2[4];
vector<Point2f>corners;
goodFeaturesToTrack(DrawLine,corners,4,0.1,10,Mat()); //角点检测
for(int i=0;i<corners.size();i++)
{
circle(DrawLine,corners[i],3,Scalar(255),3);
P1[i]=corners[i];
}
imshow("交点",DrawLine);
int width=P1[1].x-P1[0].x;
int hight=P1[2].y-P1[0].y;
P2[0]=P1[0];
P2[1]=Point2f(P2[0].x+width,P2[0].y);
P2[2]=Point2f(P2[0].x,P2[1].y+hight);
P2[3]=Point2f(P2[1].x,P2[2].y);
Mat elementTransf;
elementTransf= getAffineTransform(P1,P2);
warpAffine(imageSource,imageSource,elementTransf,imageSource.size(),1,0,Scalar(255));
imshow("校正",imageSource);
//Zbar二维码识别
ImageScanner scanner;
scanner.set_config(ZBAR_NONE, ZBAR_CFG_ENABLE, 1);
int width1 = imageSource.cols;
int height1 = imageSource.rows;
uchar *raw = (uchar *)imageSource.data;
Image imageZbar(width1, height1, "Y800", raw, width * height1);
scanner.scan(imageZbar); //扫描条码
Image::SymbolIterator symbol = imageZbar.symbol_begin();
if(imageZbar.symbol_begin()==imageZbar.symbol_end())
{
cout<<"查询条码失败,请检查图片!"<<endl;
}
for(;symbol != imageZbar.symbol_end();++symbol)
{
cout<<"类型:"<<endl<<symbol->get_type_name()<<endl<<endl;
cout<<"条码:"<<endl<<symbol->get_data()<<endl<<endl;
}
namedWindow("Source Window",0);
imshow("Source Window",imageSource);
waitKey();
imageZbar.set_data(NULL,0);
return 0;
}

Opencv+Zbar二维码识别(二维码校正)的更多相关文章

  1. Flutter扫码识别二维码内容

    前面一篇写了生成二维码图片,这篇来写使用相机扫描识别二维码 识别二维码需要用到插件 barcode_scan 首先在 pubspec.yaml 文件中添加以下依赖,添加依赖后在 pubspec.yam ...

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

    一维码由一组规则排列的黑色线条.白色线条以及对应的字符组成.对倾斜的(没有严重形变)一维码的角度校正,可以根据其黑白相间.排列规则的特点,计算傅里叶频谱,通过傅里叶频谱中直线的倾斜角度计算空间域图像一 ...

  3. winform 扫码识别二维码

    因为公司业务需求,需要在Windows系统下调用摄像头识别二维码需求,就有了这个功能. 我根据网上网友提供的一些资料,自己整合应用到项目中,效果还不错(就是感觉像素不是太好) 现在将调用摄像头+识别二 ...

  4. Opencv+Zbar二维码识别(标准条形码/二维码识别)

    使用Opencv+Zbar组合可以很容易的识别图片中的二维码,特别是标准的二维码,这里标准指的是二维码成像清晰,图片中二维码的空间占比在40%~100%之间,这样标准的图片,Zbar识别起来很容易,不 ...

  5. 配置zbar识别二维码(转载)

    原文地址:http://blog.csdn.net/dcrmg/article/details/52108258  二维码解码器Zbar+VS2012开发环境配置 Zbar条码解码器是一个开源的二维码 ...

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

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

  7. tornado zbar 二维码识别 ,配合nginx 反向代理,supervisord 监控

    tornado zbar 二维码识别 ,配合nginx 反向代理,supervisord 监控 1.zbar识别二维码程序,python2.6.6 #!/usr/bin/env python # co ...

  8. [opencv]二维码识别开发流程及问题复盘总结

    项目复盘总结 开发需求: 在桌面机器人(向下俯视)摄像头拍摄到的图像中做条形码识别与二维码识别. 条形码在图像固定位置,二维码做成卡片的形式在固定区域内随意摆放. 开发环境及相关库:ubuntu 18 ...

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

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

随机推荐

  1. PS学习一

    1.使用缩放工具时是对文档窗口进行的缩放,它只影响视图比例:而对图像的缩放则是指对图像文件本身进行的物理缩放,它会使图像的内容变大或变小. 2.分辨率是指单位长度内包含的像素点的数量,它的单位通常为像 ...

  2. Linux系统下设置vi编辑器,tab键为4

    1.cd ~ 2.vi .exrc 3.set tabstop=4(保存并退出)即可

  3. jQuery的鼠标移入与移出事件

    mouseover与mouseenter 不论鼠标指针穿过被选元素或其子元素,都会触发 mouseover 事件. 只有在鼠标指针穿过被选元素时,才会触发 mouseenter 事件. mouseou ...

  4. 21Spring重用切点表达式

    直接看代码: package com.cn.spring.aop.impl; //加减乘除的接口类 public interface ArithmeticCalculator { int add(in ...

  5. Python解释器的种类以及特点

    CPython 由C语言开发的  使用最广的解释器 IPython 基于cpython之上的一个交互式计时器 交互方式增强 功能和cpython一样 PyPy 目标是执行效率 采用JIT技术 对pyt ...

  6. vue项目编译配置 用于结合Django项目

  7. Python关于函数作为返回值的理解(3分钟就看完了)

    话不多说,直接看例子,上代码: def line_conf(): def line(x): return 2 * x + 1 return line #return a function object ...

  8. 将scl分频

    多个scl后一个高脉冲,脉冲宽度一个scl脉冲. always @ ( posedge MCLK or negedge RST_N ) begin if (rClkCount == 24) //如果有 ...

  9. VI/VIM 编辑器

    [是什么?] VI 是 Unix 操作系统和类 Unix 操作系统中最通用的文本编辑器. VIM 编辑器是从 VI 发展出来的一个性能更强大的文本编辑器.可以主动的以字体颜色辨别语法的正确性,方便程序 ...

  10. 图论算法——最短路径Dijkstra,Floyd,Bellman Ford

    算法名称 适用范围 算法过程 Dijkstra 无负权 从s开始,选择尚未完成的点中,distance最小的点,对其所有边进行松弛:直到所有结点都已完成 Bellman-Ford 可用有负权 依次对所 ...