二维码解码算法:opencv 和 zxing-cpp

二维码解码库

在 C++ 生态中,常见的二维码解码库有:

  1. libdecodeqr 多年未更新
  2. ZBar 多年未更新,
  3. zxing-cpp 官方 ZXing(Java)的高质量 C++ 移植,由专业团队维护;
  4. opencv4 QRCodeDetector (对opencv 有版本要求)

测试

基于opencv

c 复制代码
import cv2
import numpy as np
import argparse
import os

def enhance_image(img):
    if len(img.shape) == 3:
        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    else:
        gray = img.copy()
    clahe = cv2.createCLAHE(clipLimit=3.0, tileGridSize=(8, 8))
    enhanced = clahe.apply(gray)
    kernel = np.array([[0, -1, 0], [-1, 5, -1], [0, -1, 0]])
    return cv2.filter2D(enhanced, -1, kernel)

def try_decode_opencv(img, scale=1.0):
    if scale != 1.0:
        h, w = img.shape[:2]
        img = cv2.resize(img, (int(w * scale), int(h * scale)))
    detector = cv2.QRCodeDetector()
    data, points, _ = detector.detectAndDecode(img)
    if data:
        if scale != 1.0 and points is not None:
            points = points / scale
        return data, points
    return None, None

def decode_qr_robust(img):
    strategies = [
        ("original", lambda: try_decode_opencv(img, 1.0)),
        ("enhanced", lambda: try_decode_opencv(enhance_image(img), 1.0)),
        ("scale_1.5x", lambda: try_decode_opencv(img, 1.5)),
        ("scale_2x", lambda: try_decode_opencv(img, 2.0)),
    ]
    for name, func in strategies:
        try:
            data, points = func()
            if data:
                print(f"✅ 成功 ({name}): {data}")
                return data, points
        except Exception as e:
            continue
    print("❌ 解码失败")
    return None, None

def draw_result(img, points, text):
    out = img.copy()
    if points is not None:
        pts = points.reshape((-1, 1, 2)).astype(np.int32)
        cv2.polylines(out, [pts], True, (0, 255, 0), 2)
        txt = text[:50] + "..." if len(text) > 50 else text
        # txt = text
        # print(pts.shape)
        x = int(pts[0][0][0])
        y = int(pts[0][0][1]) - 20
        cv2.putText(out, txt, (20, y), cv2.FONT_HERSHEY_COMPLEX, 1, (0, 0, 255), 2, cv2.LINE_AA)
    return out

def test_image(path):
    img = cv2.imread(path)
    if img is None:
        print("❌ 图像读取失败")
        return
    data, points = decode_qr_robust(img)
    if data:
        out = draw_result(img, points, data)
        out_path = path.replace(".", "_decoded.")
        cv2.imwrite(out_path, out)
        print(f"🖼️  保存结果: {out_path}")

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument("--image", required=True)
    args = parser.parse_args()
    test_image(args.image)

基于zxing-cpp

c 复制代码
git clone https://github.com/zxing-cpp/zxing-cpp.git

cd zxing-cpp
mkdir build
cd build
cmake ..
make

官方自带测试用例:zxing-cpp/example

为了快速测试,直接基于zxing-cpp/example/ZXingOpenCV.cpp 修改下,增加支持读图片:

c 复制代码
int main(int argc, char* argv[])
{
    Mat image;
	// 读取图片
	std::string imagePath = argv[1];
	image = imread(imagePath);
	if (image.empty()) {
		std::cerr << "❌ 无法读取图像: " << imagePath << std::endl;
		return -1;
	}
	
	std::cout << "🖼️  正在解码图像: " << imagePath << std::endl;
	int64 t0 = cv::getTickCount();     
	auto barcodes = ReadBarcodes(image);
	// ⏱️ 结束计时
    double t_ms = (cv::getTickCount() - t0) / cv::getTickFrequency() * 1000;
	std::cout << "⏱️  解码耗时: " << t_ms << " ms" << std::endl;

	// 绘制结果
	bool found = false;
	for (auto& barcode : barcodes) {
		if (barcode.isValid()) {
			std::cout << "✅ 解码成功: " << barcode.text() << std::endl;
			DrawBarcode(image, barcode);
			found = true;
		}
	}

	if (found)
	{
		// 可选:保存结果
		imwrite("decoded_output.jpg", image);
		std::cout << "💾 结果已保存为 decoded_output.jpg" << std::endl;
	}else
	{
		std::cout << "❌ 未检测到有效二维码" << std::endl;
	}
	
    return 0;
}
相关推荐
2601_958320577 分钟前
【小白易懂版】OpenClaw 飞书机器人绑定配置详细教程(含安装包)
人工智能·机器人·飞书·open claw·小龙虾·open claw安装
AI创界者13 分钟前
《2026 视觉革命:深度测评 GPT-Image-2,基于 DMXAPI 实现 4K 超分与批量生图实战》
人工智能
云上码厂15 分钟前
2023年之前物理信息神经网络PINN papers
人工智能·深度学习·神经网络
aini_lovee18 分钟前
多目标粒子群优化(MOPSO)双适应度函数MATLAB实现
人工智能·算法·matlab
Cosolar19 分钟前
提示词工程面试题系列 - Zero-Shot Prompting 和 Few-Shot Prompting 的核心区别是什么?
人工智能·设计模式·架构
灵机一物24 分钟前
灵机一物AI原生电商小程序、PC端(已上线)-【无标Anthropic 研究深度解析:AI 对就业市场的实际冲击与高危职业排行题】
人工智能·ai·程序员·职业发展·anthropic·就业市场
电子科技圈25 分钟前
芯科科技在蓝牙亚洲大会展示汽车与边缘AI前沿蓝牙创新技术, 解锁车用、家居、健康及工商业等应用场景
人工智能·科技·嵌入式硬件·mcu·物联网·网络安全·汽车
yong999026 分钟前
图像融合与拼接:完整MATLAB工具箱
算法·计算机视觉·matlab
春风不语50528 分钟前
深入理解主成分分析(PCA)
算法
apollowing29 分钟前
启发式算法WebApp实验室:从搜索策略到群体智能的能力进阶(二十二)
算法·启发式算法·web app