#include <iostream>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/core/core.hpp>
#include <zbar.h>
#include <zbar/Image.h>
using namespace std;
using namespace cv;
using namespace zbar;
//zbar接口
string ZbarDecoder(Mat &src, Mat img)
{
string result;
ImageScanner scanner;
// configure the reader
scanner.set_config(ZBAR_QRCODE, ZBAR_CFG_ENABLE, 1);
// wrap image data
Image image(img.cols, img.rows, "Y800", (uchar *)img.data, img.cols * img.rows);
// scan the image for barcodes
int n = scanner.scan(image);
// extract results
if(n > 0) {
for(Image::SymbolIterator symbol = image.symbol_begin();symbol != image.symbol_end(); ++symbol) {
vector<Point> vp;
int n = symbol->get_location_size();
for(int i=0;i<n;i++) {
vp.push_back(Point(symbol->get_location_x(i),symbol->get_location_y(i)));
}
RotatedRect r = minAreaRect(vp);
Point2f pts[4];
r.points(pts);
Point textPoint(pts[1]);
result = symbol->get_data();
for(int i=0;i<4;i++){
line(src,pts[i],pts[(i+1)%4],Scalar(255,0,0),3);
textPoint.x>=pts[i].x?textPoint.x=pts[i].x:textPoint.x=textPoint.x;
textPoint.y>=pts[i].y?textPoint.y=pts[i].y:textPoint.y=textPoint.y;
putText(src,result,textPoint,FONT_HERSHEY_COMPLEX,1,Scalar(0,0,255),1,8,false);
}
cout<<"类型: "<<endl<<symbol->get_type_name()<<endl<<endl;
cout<<"条码: "<<endl<<symbol->get_data()<<endl<<endl;
cout<<"Angle: "<<r.angle<<endl;
}
}
image.set_data(NULL, 0);
return result;
}
//main function
Mat GetQR(Mat &frame)
{
Mat gray, binImg;
cvtColor(frame, gray, CV_BGR2GRAY);
//在otsu二值结果的基础上,不断增加阈值,用于识别模糊图像
int thre = threshold(gray, binImg, 0, 255, cv::THRESH_OTSU);
string result;
while(result.empty() && thre<255)
{
threshold(gray, binImg, thre, 255, cv::THRESH_BINARY);
//对二值图像进行识别,如果失败则开运算进行二次识别
result = ZbarDecoder(frame, binImg);
if(result.empty())
{
Mat openImg;
Mat element = getStructuringElement(MORPH_RECT, Size(3, 3));
morphologyEx(binImg, openImg, MORPH_OPEN, element);
result = ZbarDecoder(frame, openImg);
}
thre += 20;//阈值步长设为20,步长越大,识别率越低,速度越快
}
return frame;
}
int main()
{
cout << "Hello World!" << endl;
VideoCapture capture;
Mat frame;
capture.open(0);
while (capture.isOpened()) {
capture.read(frame);
frame = GetQR(frame);
imshow("frame", frame);
if(waitKey(30) == 'q')
break;
}
capture.release();
return 0;
}