Opencv+Zbar二维码识别(二维码校正)
二维码和车牌识别基本都会涉及到图像的校正,主要是形变和倾斜角度的校正,一种二维码的畸变如下图:
这个码用微信扫了一下,识别不出来,但是用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二维码识别(二维码校正)的更多相关文章
- Flutter扫码识别二维码内容
前面一篇写了生成二维码图片,这篇来写使用相机扫描识别二维码 识别二维码需要用到插件 barcode_scan 首先在 pubspec.yaml 文件中添加以下依赖,添加依赖后在 pubspec.yam ...
- Opencv+Zbar二维码识别(一维码校正)
一维码由一组规则排列的黑色线条.白色线条以及对应的字符组成.对倾斜的(没有严重形变)一维码的角度校正,可以根据其黑白相间.排列规则的特点,计算傅里叶频谱,通过傅里叶频谱中直线的倾斜角度计算空间域图像一 ...
- winform 扫码识别二维码
因为公司业务需求,需要在Windows系统下调用摄像头识别二维码需求,就有了这个功能. 我根据网上网友提供的一些资料,自己整合应用到项目中,效果还不错(就是感觉像素不是太好) 现在将调用摄像头+识别二 ...
- Opencv+Zbar二维码识别(标准条形码/二维码识别)
使用Opencv+Zbar组合可以很容易的识别图片中的二维码,特别是标准的二维码,这里标准指的是二维码成像清晰,图片中二维码的空间占比在40%~100%之间,这样标准的图片,Zbar识别起来很容易,不 ...
- 配置zbar识别二维码(转载)
原文地址:http://blog.csdn.net/dcrmg/article/details/52108258 二维码解码器Zbar+VS2012开发环境配置 Zbar条码解码器是一个开源的二维码 ...
- 基于opencv+python的二维码识别
花了2天时间终于把二维码识别做出来了,不过效果一般,后面会应用在ROS辅助定位上,废话少说先上图: 具体过程参考了这位大神的博客:http://blog.csdn.net/qq_25491201/ar ...
- tornado zbar 二维码识别 ,配合nginx 反向代理,supervisord 监控
tornado zbar 二维码识别 ,配合nginx 反向代理,supervisord 监控 1.zbar识别二维码程序,python2.6.6 #!/usr/bin/env python # co ...
- [opencv]二维码识别开发流程及问题复盘总结
项目复盘总结 开发需求: 在桌面机器人(向下俯视)摄像头拍摄到的图像中做条形码识别与二维码识别. 条形码在图像固定位置,二维码做成卡片的形式在固定区域内随意摆放. 开发环境及相关库:ubuntu 18 ...
- [opencv]二维码识别率提升方案-resize调整
这里采用循环resize的方式,对二维码图像进行放缩. 识别到name(二维码结果)不为空,则立即退出循环 //循环识别 for (int i = 1;name.empty(); i++){ resi ...
随机推荐
- git-svn操作
1.git svn clone --username=chenzheng http://10.0.0.178/repos/trunk/hxqcgf/auto_accessories.admin.h ...
- 7-26 Windows消息队列(25 分)(堆排序)
7-26 Windows消息队列(25 分) 消息队列是Windows系统的基础.对于每个进程,系统维护一个消息队列.如果在进程中有特定事件发生,如点击鼠标.文字改变等,系统将把这个消息加到队列当中. ...
- sed和awk的常用实例
一.文本间隔 1.在每一行后面增加一空行 sed G guo.sh awk '{printf("%s\n\n",$0 ) }' 2.将文件中原来的空行删掉,并在在每一行后边增加一空 ...
- POJ 1679 判最小生成树的不唯一性 或 利用次小生成树求解
题目大意: 给定一个无向图,寻找它的最小生成树,如果仅有一种最小生成树,输出所有边的和,否则输出unique! 根据kruscal原理来说,每次不断取尽可能小的边不断添加入最小生成树中,那么可知如果所 ...
- Discuz! X2.5数据库字典【转载】
DROP TABLE IF EXISTS pre_common_admincp_cmenu; CREATE TABLE pre_common_admincp_cmenu ( `id` SMALLINT ...
- Thinkphp5.0 的使用模型Model查询
Thinkphp5.0 的使用模型Model查询 一.查询多条记录 获取多个数据可以使用:select()方法和all()方法. 示例一:使用all()方法. //(1)筛选条件使用闭包函数 $res ...
- POJ 1127_Jack Straws
%: 对于二维向量p1=(x1,y1),p2=(x2,y2),定义内积p1⋅p2=x1x2+y1y2,外积p1×p2=x1y2−y1x2,则判断点q是否在线段p1−p2上: 先利用外积判断q是否在直线 ...
- [bzoj3894]文理分科_网络流_最小割
文理分科 bzoj-3894 题目大意:题目链接. 注释:略. 想法: 这种题也是一种套路. 我们新建一个点表示收益点. 然后把所有的收益都加一起,求最小割表示代价即可. Code: #include ...
- cogs——1364. 聚会
1364. 聚会 ★ 输入文件:partyb.in 输出文件:partyb.out 简单对比时间限制:1 s 内存限制:128 MB [问题描述] 小S想要从某地出发去同学k的家中参加 ...
- AtCoder Grand Contest 012 B Splatter Painting(记忆化搜索)
题意: 给一个包含N个顶点,M条边,无自环和重边的简单无向图,初始每个点颜色都为0,每条边的长度为1,连接着ai,bi两个节点.经过若干个操作, 每次将与某个点vi距离不超过di的所有点染成某种颜色c ...