调用微信开源二维码模型

一、 OpenCV 的 wechat_qrcode_WeChatQRCode

请确保四个文件完整(detect.prototxt, detect.caffemodel, sr.prototxt, sr.caffemodel

这四个开源文件在gitee上可以搜到下载就行

gitee地址gitee模型地址_wechat-qrcode

或直接下载有时候下载不了

代码

复制代码
import cv2
import os
import time
import numpy as np
from datetime import datetime
from PIL import Image, ImageDraw, ImageFont

# ========== 配置模型路径(纯英文,确保 OpenCV 可读取) ==========
MODEL_DIR = r"C:\yolov8-2\detect_3-video\wechat-qrcode-master\data"
DETECT_PROTOTXT = os.path.join(MODEL_DIR, "detect.prototxt")
DETECT_CAFFEMODEL = os.path.join(MODEL_DIR, "detect.caffemodel")
SR_PROTOTXT = os.path.join(MODEL_DIR, "sr.prototxt")
SR_CAFFEMODEL = os.path.join(MODEL_DIR, "sr.caffemodel")

# 全局初始化检测器(只初始化一次,提高性能)
try:
    qr_detector = cv2.wechat_qrcode_WeChatQRCode(
        DETECT_PROTOTXT, DETECT_CAFFEMODEL,
        SR_PROTOTXT, SR_CAFFEMODEL
    )
    print("微信二维码检测器初始化成功")
except Exception as e:
    print(f"检测器初始化失败: {e}")
    exit(1)

# ========== 全局变量 ==========
current_frame = None
save_dir_base = "images_videos"
save_counter = 0
display_text = ""
display_until = 0.0

# ---------- 中文字体 ----------
def get_chinese_font(font_size=36):
    font_paths = [
        "C:/Windows/Fonts/simhei.ttf",
        "C:/Windows/Fonts/simsun.ttc",
        "C:/Windows/Fonts/simfang.ttf",
    ]
    for path in font_paths:
        if os.path.exists(path):
            return ImageFont.truetype(path, font_size)
    return ImageFont.load_default()

try:
    chinese_font = get_chinese_font(36)
except:
    print("警告:未找到中文字体,中文可能显示为方框。")
    chinese_font = ImageFont.load_default()

def draw_chinese_text_opencv(img_bgr, text, position, font, color_bgr=(0,255,0)):
    """在 OpenCV 图像上绘制中文(使用 PIL)"""
    img_rgb = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2RGB)
    pil_img = Image.fromarray(img_rgb)
    draw = ImageDraw.Draw(pil_img)
    color_rgb = (color_bgr[2], color_bgr[1], color_bgr[0])
    draw.text(position, text, font=font, fill=color_rgb)
    return cv2.cvtColor(np.array(pil_img), cv2.COLOR_RGB2BGR)

# ---------- 鼠标回调:左键保存原始图像 ----------
def mouse_callback(event, x, y, flags, param):
    global current_frame, save_counter, display_text, display_until
    if event == cv2.EVENT_LBUTTONDOWN and current_frame is not None:
        save_counter += 1
        now = datetime.now()
        subdir_name = now.strftime("%Y-%m-%d_%H-%M-%S")
        save_path = os.path.join(save_dir_base, subdir_name)
        os.makedirs(save_path, exist_ok=True)
        filename = now.strftime("%Y-%m-%d_%H-%M-%S-%f") + ".png"
        full_path = os.path.join(save_path, filename)
        cv2.imwrite(full_path, current_frame.copy())
        print(f"已保存图像: {full_path}")
        display_text = f"保存第 {save_counter} 张"
        display_until = time.time() + 1.5

# ---------- 摄像头曝光/对焦调节 ----------
def adjust_camera(cap):
    try:
        # 自动曝光 -> 手动
        cap.set(cv2.CAP_PROP_AUTO_EXPOSURE, 0.0)
        print("已关闭自动曝光(手动模式)")
    except:
        cap.set(cv2.CAP_PROP_AUTO_EXPOSURE, 0.25)
        print("尝试设置 AUTO_EXPOSURE = 0.25")
    # 曝光值(常用 -6 ~ -2)
    if not cap.set(cv2.CAP_PROP_EXPOSURE, -3.0):
        cap.set(cv2.CAP_PROP_EXPOSURE, 0.5)
    cap.set(cv2.CAP_PROP_BRIGHTNESS, 0.5)
    cap.set(cv2.CAP_PROP_GAIN, 0.5)
    # 手动对焦
    cap.set(cv2.CAP_PROP_AUTOFOCUS, 0)
    cap.set(cv2.CAP_PROP_FOCUS, 100)
    print("摄像头参数已设置(手动曝光、手动对焦)")

# ---------- 二维码检测(使用微信检测器)----------
def decode_qrcodes_wechat(frame, display_frame, font):
    """
    使用 cv2.wechat_qrcode_WeChatQRCode 检测二维码,
    在 display_frame 上绘制绿色边框和解码文本。
    """
    res, points = qr_detector.detectAndDecode(frame)
    if res:
        for i, info in enumerate(res):
            if info:
                pts = points[i].astype(int)
                # 绘制多边形边框
                cv2.polylines(display_frame, [pts], True, (0, 255, 0), 2)
                # 获取矩形区域(用于文本定位)
                x_min = int(pts[:, 0].min())
                y_min = int(pts[:, 1].min())
                # 文本显示在二维码上方,避免超出画面
                text_y = y_min - 10 if y_min - 10 > 20 else y_min + 30
                # 绘制文本(支持中文)
                display_frame = draw_chinese_text_opencv(
                    display_frame, f"QR: {info}",
                    (x_min, text_y), font, (0, 255, 0)
                )
                print(f"[二维码] {info}")
    return display_frame

# ---------- 主函数 ----------
def main():
    global current_frame

    # 打开摄像头(索引1,可根据需要修改)
    cap = cv2.VideoCapture(1, cv2.CAP_DSHOW)
    if not cap.isOpened():
        print("错误:无法打开摄像头1,尝试索引0...")
        cap = cv2.VideoCapture(0, cv2.CAP_DSHOW)
        if not cap.isOpened():
            print("无法打开任何摄像头")
            return

    adjust_camera(cap)

    # 设置期望分辨率(可修改)
    desired_width, desired_height = 1280, 720  # 推荐 720p 保证流畅度和识别率
    cap.set(cv2.CAP_PROP_FRAME_WIDTH, desired_width)
    cap.set(cv2.CAP_PROP_FRAME_HEIGHT, desired_height)
    actual_w = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
    actual_h = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
    print(f"实际分辨率: {actual_w}x{actual_h}")

    # 可选:如果实际分辨率不理想,可以尝试备选分辨率
    if (actual_w, actual_h) != (desired_width, desired_height):
        fallback = [(1920,1080), (1280,720), (640,480)]
        for w,h in fallback:
            cap.set(cv2.CAP_PROP_FRAME_WIDTH, w)
            cap.set(cv2.CAP_PROP_FRAME_HEIGHT, h)
            tw, th = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)), int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
            if (tw,th) == (w,h):
                print(f"成功设置分辨率为 {w}x{h}")
                break

    print(f"最终帧宽度: {cap.get(cv2.CAP_PROP_FRAME_WIDTH)}")
    print(f"最终帧高度: {cap.get(cv2.CAP_PROP_FRAME_HEIGHT)}")
    print("操作说明:")
    print("  - 鼠标左键单击 -> 保存当前画面(不包含框和文字)")
    print("  - 二维码会被绿色框标出,并显示内容")
    print("  - 按 'q' 键退出")

    window_name = "WeChat QR Scanner (Left click save, q exit)"
    cv2.namedWindow(window_name)
    cv2.setMouseCallback(window_name, mouse_callback)
    os.makedirs(save_dir_base, exist_ok=True)

    while True:
        ret, frame = cap.read()
        if not ret:
            print("错误:无法读取摄像头帧")
            break

        # 保存原始帧(供鼠标保存使用)
        current_frame = frame.copy()
        # 显示用副本(会绘制二维码框和文字)
        display_frame = frame.copy()

        # 二维码检测
        display_frame = decode_qrcodes_wechat(frame, display_frame, chinese_font)

        # 显示"保存第X张"提示(绿色文字,持续1.5秒)
        if display_text and time.time() < display_until:
            display_frame = draw_chinese_text_opencv(
                display_frame, display_text,
                (20, 50), chinese_font, (0, 255, 0)
            )

        cv2.imshow(window_name, display_frame)

        key = cv2.waitKey(1) & 0xFF
        if key == ord('q'):
            break

    cap.release()
    cv2.destroyAllWindows()

if __name__ == "__main__":
    main()

二、二维码和条形码生成,参考下面文章

python生成条形码和二维码

相关推荐
许彰午4 小时前
Git实战——从零到团队协作以一个开源项目为例
git·开源
好好风格5 小时前
这个开源项目,把本地大模型做成会说话的 Live2D 桌宠
人工智能·python·开源
X54先生(人文科技)5 小时前
《元创力》纪实录·卷宗2.1 关联观察孤岛的回归:当一座“反AI叙事飞地”成为最后的堡垒
人工智能·架构·开源·ai写作·零知识证明
该昵称用户已存在7 小时前
碳数据治理开源底座:MyEMS 能源中台的资产化架构与价值释放设计思路
架构·开源·能源
爱学习的鱼佬7 小时前
告别内网模型接入烦恼!ModelStandardization:让 Open WebUI等工具无缝对接私有大模型
rust·开源·大模型·openai·openwebui·model api代理·内网部署
Real-Staok7 小时前
开源多模态大模型全景对比:你的电脑,已经是 AI 工作站
人工智能·开源·电脑
AiTop1007 小时前
PaddleOCR-VL-1.6正式开源:0.9B轻量架构跑出96.33%准确率,反超GPT、Gemini登顶全球OCR榜单
gpt·架构·开源
lauo7 小时前
ibbot手机:一部手机,双重革命
人工智能·智能手机·架构·开源·github
AI进阶客栈7 小时前
开源 MQ Master:Spring Boot 统一管控 5 大消息队列
spring boot·后端·开源