opencv实践示例:

一:识别二维码:
  • 基本思路:

    • 打开摄像头获取实时画面;

    • 将每帧转换为灰度图并增强对比度,提高识别率;

    • 使用 OpenCV 的 QRCodeDetector 检测二维码;

    • 如果检测成功:

      • 提取角点;
      • 在画面上画出绿色边框;
      • cv2.getPerspectiveTransformcv2.warpPerspective 进行透视矫正,将二维码“板正”显示;
    • 提取二维码内容,并显示在画面上;

    • 每帧都实时检测;

    • 用户按下 q 键退出。

  • 新老函数大回顾:

    • cv2.QRCodeDetector():构建二维码检测器
    • cv2.getPerspectiveTransform(src_pts, dst_pts):获取透视变换矩阵 M,该矩阵将源角点(二维码实际角点)映射到目标角点(正方形框)上。
    • cv2.warpPerspective(frame, M, (300, 300)):通过透视变换矩阵 M 对输入的 frame 进行变换,将二维码提取并放入 300x300 的目标框中。
import cv2
import numpy as np

qr_detector = cv2.QRCodeDetector() # 初始化二维码检测器
cap = cv2.VideoCapture(0) #打开摄像头

# 设置摄像头分辨率,这样免得程序卡死,提高实时性
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)

if not cap.isOpened():
    print("the camera is not opened")
    exit()

# 定义排序角点的函数,便于后面的板正
def sort_points(pts):
    pts = pts.reshape(-1, 2)  # 确保点是二维数组,-1表示自动确定几行,2表示两列,比如[1,2,2,3]返回[[1,2],[2,3]]
    hull = cv2.convexHull(pts)  # 获取凸包(凸包就是一组点中能“包住”所有点的最小凸多边形),以此确定二维码的四个角,过滤掉噪声。
    return hull.reshape(-1, 2)  # 返回排序后的角点

while True: #当摄像头打开时
    ret, frame = cap.read() #ret表示是否读取到了帧,用true,faulse表示,frame表示读取到的帧
    if not ret:
        break

    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) #将帧转为灰度图,减少曝光的作用
    gray = cv2.equalizeHist(gray) #使用直方图均衡化,更近一步的减少曝光对识别二维码的作用
    _, thresholded = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)  # 使用自适应阈值增强二维码对比度,增强二维码的边缘

    # 检测二维码
    data, points, _ = qr_detector.detectAndDecode(thresholded) #解码,data表示解码出的内容(字符串),points返回的是二维码的角点信息。
   
    if points is not None and len(points) == 1 and points[0].shape[0] == 4:#对角点进行排序
    src_pts = sort_points(points[0]) 
        if len(points) == 4:  # 确保有 4 个点
          int_pts = src_pts.astype(int) #将这些点转化成整数类型,便于画点
            for i in range(4):   #绘制四条边
                pt1 = tuple(int_pts[i]) #起点
                pt2 = tuple(int_pts[(i + 1) % 4])  #下一个点
                cv2.line(frame, pt1, pt2, (0, 255, 0), 2)  #表示在帧中描绘二维码的边框,用red标注,粗细为2个像素点

            # 如果解码成功
            if data:
                #显示二维码内容,包括在哪个页面,显示什么内容,坐标,字体,字号,颜色,粗细
                cv2.putText(frame, data, (int_pts[0][0], int_pts[0][1] - 10),
                            cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 0, 255), 2)  
                print("二维码内容:", data)

                # 定义目标透视变换后的四个点
                dst_pts = np.array([
                    [0, 0], [300, 0],
                    [300, 300], [0, 300]
                ], dtype="float32")

                # 获取透视变换矩阵
                M = cv2.getPerspectiveTransform(src_pts, dst_pts)  #将读取的二维码原图映射到四个点,实现板正过程
                warped = cv2.warpPerspective(frame, M, (300, 300))  # 重新包装,大小为300*300
                cv2.imshow("warped", warped)  # 显示透视变换后的二维码图像

    # 将图像在自定义的大小内展示
    cv2.namedWindow("QRCode Detection (Color)", cv2.WINDOW_NORMAL)
    cv2.resizeWindow("QRCode Detection (Color)", 1000, 600)
    cv2.imshow("QRCode Detection (Color)", frame)

    # 按 'q' 键退出
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap.release() #记得用完摄像头之后都需要释放哟
cv2.destroyAllWindows()

效果如下:
在这里插入图片描述

Logo

中国智能体开发者社区,聚焦智能体与大模型开发,提供前沿资讯、实用工具链、开源项目及行业案例。通过技术沙龙、开发者大赛等活动,促进经验交流与协作,助力开发者快速构建创新智能应用。

更多推荐