前言
本文做了一个小工具,用来实时检测屏幕中出现的二维码,并通过Server酱发送信息推送到微信。
二维码检测
二维码检测主要通过opencv的detectAndDecode
方法,基本用法如下:
data, bbox, rectifiedImage = detector.detectAndDecode(inputImage)
- inputImage: 待检测的图像,应该是一个OpenCV的图像格式,即numpy数组。
- data: 解码后的二维码文本内容。如果没有检测到二维码,这将是一个空字符串。
- bbox: 检测到的二维码的边界框,是一个四角形,标识出二维码的位置。如果没有检测到二维码,这将是None。
- rectifiedImage: 一个经过校正的二维码图像,它是二维码从原图中提取并转换为正面视角的结果。如果没有检测到二维码,这将是None。
检测示例:
import cv2
# 创建一个QRCodeDetector对象
detector = cv2.QRCodeDetector()
# 读取图像
image = cv2.imread("img.png")
# 检测并解码二维码
data, points, _ = detector.detectAndDecode(image)
# 检查是否检测到二维码
if points is not None:
# 将points的数据类型转换为int,以便绘图
points = points.astype(int)
# 绘制二维码的边界
for i in range(len(points)):
# 绘制多边形来表示二维码的边界
cv2.polylines(image, [points[i]], isClosed=True, color=(0, 255, 0), thickness=5)
# 显示带有二维码边界的图像
cv2.imshow("QR Code Detection", image)
cv2.waitKey(0)
cv2.destroyAllWindows()
else:
print("No QR Code detected.")
实测效果是小窗检测不太行,全屏状态下检测效果不错。
Server酱消息推送
Server酱是一个接入微信的消息推送工具,官方地址:https://sct.ftqq.com/
使用时,需要在官网注册一个账号,获得一个key用来推送到自己的微信,免费额度是5条/日。
使用示例:
text
是提醒的标题,desp
为提醒的具体内容,支持markdown语法。
import urllib.parse
import urllib.request
def sc_send(text, desp='', key='[SENDKEY]'):
postdata = urllib.parse.urlencode({'text': text, 'desp': desp}).encode('utf-8')
url = f'https://sctapi.ftqq.com/{key}.send'
req = urllib.request.Request(url, data=postdata, method='POST')
with urllib.request.urlopen(req) as response:
result = response.read().decode('utf-8')
return result
key = '自己key'
ret = sc_send('签到提醒', '老师开始签到了', key)
print(ret)
工具完整代码
将两部分结合,即可实现实时检测+信息推送的功能,为防止误测,连续5次检测到二维码视为检测成功。
import cv2
import mss
import numpy as np
import time
import urllib.parse
import urllib.request
# 发送信息
def sc_send(text, desp='', key='[SENDKEY]'):
postdata = urllib.parse.urlencode({'text': text, 'desp': desp}).encode('utf-8')
url = f'https://sctapi.ftqq.com/{key}.send'
req = urllib.request.Request(url, data=postdata, method='POST')
with urllib.request.urlopen(req) as response:
result = response.read().decode('utf-8')
return result
# 检测二维码
def detect_QR(monitor=1, key=None):
with mss.mss() as sct:
detector = cv2.QRCodeDetector()
detect_times = 0
while True:
sct_img = sct.grab(sct.monitors[monitor])
img = np.array(sct_img)
img = cv2.cvtColor(img, cv2.COLOR_BGRA2BGR)
# 检测并解码二维码
data, points, _ = detector.detectAndDecode(img)
# 检测到二维码
if data:
detect_times += 1 # 检测到二维码,计数器加一
print(f"检测到二维码 {detect_times} 次")
if detect_times >= 5:
# 连续五次检测到二维码,发送消息并结束程序
_ = sc_send('签到提醒', '老师开始签到了', key)
print("消息已发送,程序结束。")
break
_ = sc_send('签到提醒', '老师开始签到了', key)
else:
detect_times = 0 # 未检测到二维码,重置计数器
time.sleep(0.3) # 稍作延时,避免过于频繁的检测
if __name__ == '__main__':
# 对第二显示屏进行持续截图并检测二维码
detect_QR(1, key="自己的key")