赞
踩
查过网上很多资料,Qt+zbar是还需配合opencv来用,我看调用opencv起到两个作用,第一个当然是采集图像,第二个把采集的图像转为灰度图像。我在软件代码里已经使用ffmpeg才获取的视频流,得到了QImage图像,现在需要调用识别QImage内的条码或者二维码。我的Qt版本是5.4.1,原来二维码编码和解码得框架QZxing至少需要Qt5.5.0才能编译得过去,只得找替代QZxing的办法,找Zbar,首先是下载源码然后交叉编译,如何编译这个这里不在说明。
首先我先参考了https://blog.csdn.net/bbdxf/article/details/79356259。
#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[])
{
ImageScanner scanner;
scanner.set_config(ZBAR_NONE, ZBAR_CFG_ENABLE, 1);
Mat image = imread("code.jpg");
if(!image.data)
{
cout<<"请确认图片"<<endl;
system("pause");
return 0;
}
Mat imageGray;
cvtColor(image,imageGray,CV_RGB2GRAY);
int width = imageGray.cols;
int height = imageGray.rows;
uchar *raw = (uchar *)imageGray.data;
Image imageZbar(width, height, "Y800", raw, width * height);
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;
}
imshow("Source Image",image);
waitKey();
imageZbar.set_data(NULL,0);
return 0;
}
上面代码解码一个图片文件用opencv,我们得想办法避开它,博主使用下面法子。
Image barcode = new Image(width, height, "RGB4");
barcode.setData(imgRGB888);
int result = scanner.scanImage(barcode.convert("Y800"));
大概意思就是如果是RGB4或者RGB32格式必须先转化为灰度图像。
我曾找到使用zbar源码内QZbarImage类,在QZbarImage.h内,QZbarImage其实就是重载Zbar::Image,装载QImage,
能够使用ImageScanner scanner.scan(QZbarImage imageZbar);也就是被它这个带 进了死胡同,它要求RGB32或者ARGB32。以为这样能扫出来,可能也是由于对zbar使用不够了解,从某些博客里了解到,为了提高扫码识别性,需要转化为灰度,还要进行什么二值化处理。现在想法QZbarImage加载QImage后,其实也还是进行转为灰度图,QZbarImage image.conver("Y800")。
我的解决办法是QImage RGB32格式直接转码为QImage Indexed8,原文链接https://blog.csdn.net/liyuanbhu/article/details/46659725
QImage toGray( QImage image ) { int height = image.height(); int width = image.width(); QImage ret(width, height, QImage::Format_Indexed8); ret.setColorCount(256); for(int i = 0; i < 256; i++) { ret.setColor(i, qRgb(i, i, i)); } switch(image.format()) { case QImage::Format_Indexed8: for(int i = 0; i < height; i ++) { const uchar *pSrc = (uchar *)image.constScanLine(i); uchar *pDest = (uchar *)ret.scanLine(i); memcpy(pDest, pSrc, width); } break; case QImage::Format_RGB32: case QImage::Format_ARGB32: case QImage::Format_ARGB32_Premultiplied: for(int i = 0; i < height; i ++) { const QRgb *pSrc = (QRgb *)image.constScanLine(i); uchar *pDest = (uchar *)ret.scanLine(i); for( int j = 0; j < width; j ++) { pDest[j] = qGray(pSrc[j]); } } break; } return ret; }
QImage Rgb32Image;
QImage IndexedImage=toGray(Rgb32Image);
Zbar::Image imagebar(IndexedImage.width(),IndexedImage.height(),"Y800",IndexedImage.bits(),IndexedImage.byteCount());
scanner.scan(imagebar);
在调试过程中,二维码是很好识别,有一种条码编码格式识别不了,如果你们发现二维码能识别,条码识别,可能是你的这种条码无法用zbar解码。如果Qt版本在5.5.0以上,可以考虑使用QZxing来识别条码二维码,Qt+Zbar ARM识别条码二维码 无需opencv,记录至此。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。