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

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

#include 
#include 
#include 
#include 
#include 
#include

#include 
#include 
#include 
#include 
#include 

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

#include 
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, "未识别");
}

 

你可能感兴趣的:(VC++(日积月累篇))