VC++ OpenCV+ZBar二维码识别

本文介绍了一种利用OpenCV处理图像并结合ZBar库实现二维码识别的方法。通过不同阈值处理技术和图像形态学操作提高识别准确率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

利用OpenCV处理图像的优势,结合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,步长越大,识别率越低,速度越快
	    }
	    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("1.bmp");
Mat imageGray;
cvtColor(src, imageGray, CV_RGB2GRAY);
string ret = QRCode::GetQR(imageGray);
if ( !ret.empty() )
{
	TRACE("图片识别结果...[%s]\n", ret.c_str());
}
else
{
	TRACE("未识别");
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值