VC++ OpenCV+ZBar提高二维码识别率

基于ZBar做二维码识别,识别率很低,为了提高识别率,可以先将图像进行灰度化处理再进行识别,准确率将会有很大提升。

#include <vector>
#include <algorithm>
#include <string>
#include <math.h>
#include <iostream>
#include<map>

#include <cv.h>
#include <highgui.h>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

#ifdef _DEBUG
#pragma comment(lib, "opencv_world300d.lib")
#else
#pragma comment(lib, "opencv_world300.lib")
#endif

#include <zbar.h>
using namespace zbar;
#pragma comment(lib, "libzbar-0.lib")

using namespace cv;
using namespace std;

namespace QRCode{

    std::string GetQRInBinImg(Mat binImg);
    std::string ZbarDecoder(Mat img);

	//对二值图像进行识别,如果失败则开运算进行二次识别
	std::string GetQR(Mat img)
	{
		Mat binImg;
		Mat adaptiveImg;
		double thre = threshold(img, binImg, 0, 255, CV_THRESH_OTSU + CV_THRESH_BINARY_INV);//threshold 第一个参数即原图像必须为灰度图
		std::string result;
		result = GetQRInBinImg(binImg);
		if(result.empty())//如果阈值otsuthreshold失败,则采用高斯自适应阈值化,可以识别出一定的控制阈值也识别不出来的二维码
		{
			cv::adaptiveThreshold(img, adaptiveImg, 255, ADAPTIVE_THRESH_GAUSSIAN_C, cv::THRESH_BINARY, 33, 0);//threshold第一个参数即原图像必须为灰度图,最佳33
			result = GetQRInBinImg(adaptiveImg);
		}

		thre = thre/2;//ostu和自适应阈值都失败,将从ostu阈值的一般开始控制阈值不断增长
		while (result.empty() && thre<255)
		{
			threshold(img, binImg, thre, 255, cv::THRESH_BINARY);
			result = GetQRInBinImg(binImg);
			thre += 5;//阈值步长设为5,步长越大,识别率越低,速度越快,对于当前测试图片的情况为5识别出来的最多
		}
		return result;
	}
	//主体函数
	std::string GetQRInBinImg(Mat binImg)
	{    
		std::string result = ZbarDecoder(binImg);
		if (result.empty())
		{
			Mat openImg;
			Mat element = getStructuringElement(MORPH_RECT, Size(3, 3));
			morphologyEx(binImg, openImg, MORPH_OPEN, element);
			result = ZbarDecoder(openImg);
		}
		return result;
	}
	 
	//zbar接口
	std::string ZbarDecoder(Mat img)
	{
		float point[8];
		string result;
		std::string res;
		ImageScanner scanner;
		const void *raw = (&img)->data;
		scanner.set_config(ZBAR_NONE, ZBAR_CFG_ENABLE, 1);
		Image image(img.cols, img.rows, "Y800", raw, img.cols * img.rows);
		int n = scanner.scan(image);
		Image::SymbolIterator symbol = image.symbol_begin();
		res = image.symbol_begin()->get_data();
		cout << res.c_str() << endl;
		image.set_data(NULL, 0);
		return res;
	}
}

 调用示例:

cv::Mat src = cv::imread(lpszFileName);
Mat imageGray;
cvtColor(src, imageGray, CV_RGB2GRAY);
string ret = QRCode::GetQR(imageGray);
if ( !ret.empty() )
{
	TRACE("图片%s...识别结果=[%s]\n", lpszFileName, ret.c_str());
}
else
{
	TRACE("图片%s...[%s]\n", lpszFileName, "未识别");
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值