opencv实践示例一:识别二维码
·
opencv实践示例:
一:识别二维码:
-
基本思路:
-
打开摄像头获取实时画面;
-
将每帧转换为灰度图并增强对比度,提高识别率;
-
使用 OpenCV 的
QRCodeDetector检测二维码; -
如果检测成功:
- 提取角点;
- 在画面上画出绿色边框;
- 用
cv2.getPerspectiveTransform和cv2.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()
效果如下:

更多推荐


所有评论(0)