本文使用python进行apriltag编码格式二维码的识别。大致流程是先在图片里面定位并找到apriltag编码二维码的位置,然后使用一些图像处理的方法对其解码,最后将返回值等信息返回到终端。由于python包含的库众多,灵活的使用这些库就可以避免重复造轮子,大大减少我们的工作量。楼主最近把python识别apriltag编码二维码的代码彻底整完了,实现了在windows上调用免驱外接摄像头识别apriltag编码二维码。
以下为楼主个人经历过程:先是实现了对图片中的apriltag的二维码识别,后来由异想天开实现视频里面的apriltag二维码,最后实现了摄像头实时获取图像中apriltag二维码的识别。
一、对图片中的Apriltag编码二维码的识别
主要采用了python的opencv库和pupil_apriltags库。代码使用前记得先安装这两个python库。
import cv2
import pupil_apriltags as apriltag # windows
image = cv2.imread('tag36h11_0.png') # 读入python同目录文件下的图片文件
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) #对图片进行灰度处理
# 创建一个apriltag检测器,然后检测AprilTags
options = apriltag.Detector(families='tag36h11') # windows
results = options.detect(gray)
print(results)
for r in results:
# 获取4个角点的坐标
b = (tuple(r.corners[0].astype(int))[0], tuple(r.corners[0].astype(int))[1])
c = (tuple(r.corners[1].astype(int))[0], tuple(r.corners[1].astype(int))[1])
d = (tuple(r.corners[2].astype(int))[0], tuple(r.corners[2].astype(int))[1])
a = (tuple(r.corners[3].astype(int))[0], tuple(r.corners[3].astype(int))[1])
# 绘制检测到的AprilTag的框
cv2.line(image, a, b, (255, 0, 255), 2, lineType=cv2.LINE_AA)
cv2.line(image, b, c, (255, 0, 255), 2, lineType=cv2.LINE_AA)
cv2.line(image, c, d, (255, 0, 255), 2, lineType=cv2.LINE_AA)
cv2.line(image, d, a, (255, 0, 255), 2, lineType=cv2.LINE_AA)
# 绘制 AprilTag 的中心坐标
(cX, cY) = (int(r.center[0]), int(r.center[1]))
cv2.circle(image, (cX, cY), 5, (0, 0, 255), -1)
# 在图像上绘制标文本
tagFamily = r.tag_family.decode("utf-8")
cv2.putText(image, tagFamily, (a[0], a[1] - 15), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)
cv2.imwrite('image1.png', image)
cv2.namedWindow('Image', cv2.WINDOW_NORMAL)
cv2.imshow("Image", image) #窗口名称,可以更改
cv2.waitKey(0)
以下为代码运行结果:
[Detection object:
tag_family = b'tag36h11'
tag_id = 0
hamming = 0
decision_margin = 66.34220886230469
homography = [[-7.82350400e+00 -3.46495003e+02 9.98496708e+02]
[ 3.75361123e+02 2.31623378e+01 7.02495227e+02]
[-2.89906851e-03 2.67533628e-02 1.00000000e+00]]
center = [998.49670816 702.49522737]
corners = [[ 640.82324219 340.20843506]
[ 629.1697998 1075.36657715]
[1378.03015137 1086.9239502 ]
[1385.87426758 311.3999939 ]]
pose_R = None
pose_t = None
pose_err = None
]
可以看出识别结果为格式tag36h11的id=0号
二、对视频中的Apriltag编码二维码识别
这一部分楼主想法也很简单,将视频先抽帧成图片,每次抽帧进行一次图片的识别,思路大概是这样,代码如下:
import cv2
from PIL import Image
import numpy as np
import pupil_apriltags as apriltag # windows
import os
cap = cv2.VideoCapture(r"apriltag_test.mp4") # 获取视频对象,此视频需要放到此代码文件同目录下
isOpened = cap.isOpened # 判断是否打开
# 视频信息获取
fps = cap.get(cv2.CAP_PROP_FPS)
imageNum = 0
sum = 0
timef = 2 # 隔2帧保存一张图片
while isOpened:
sum += 1
(frameState, frame) = cap.read() # 记录每帧及获取状态
if frameState == True and (sum % timef == 0):
# 格式转变,BGRtoRGB
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
# 转变成Image
frame = Image.fromarray(np.uint8(frame))
frame = np.array(frame)
# RGBtoBGR满足opencv显示格式
frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)
imageNum = imageNum + 1
fileName = r'C:\Users\20711\AppData\Roaming\JetBrains\PyCharm2023.2\light-edit\picture\image' + str(
imageNum) + '.jpg' # 存储路径
cv2.imwrite(fileName, frame, [cv2.IMWRITE_JPEG_QUALITY, 100])
print(fileName + " successfully write in") # 输出存储状态
image = cv2.imread('image' + str(imageNum) + '.jpg') # 读入python同目录文件下的图片文件
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # 对图片进行灰度处理
# 创建一个apriltag检测器,然后检测AprilTags
options = apriltag.Detector(families='tag36h11') # windows
results = options.detect(gray)
print(results)
for r in results:
# 获取4个角点的坐标
b = (tuple(r.corners[0].astype(int))[0], tuple(r.corners[0].astype(int))[1])
c = (tuple(r.corners[1].astype(int))[0], tuple(r.corners[1].astype(int))[1])
d = (tuple(r.corners[2].astype(int))[0], tuple(r.corners[2].astype(int))[1])
a = (tuple(r.corners[3].astype(int))[0], tuple(r.corners[3].astype(int))[1])
# 绘制检测到的AprilTag的框
cv2.line(image, a, b, (255, 0, 255), 2, lineType=cv2.LINE_AA)
cv2.line(image, b, c, (255, 0, 255), 2, lineType=cv2.LINE_AA)
cv2.line(image, c, d, (255, 0, 255), 2, lineType=cv2.LINE_AA)
cv2.line(image, d, a, (255, 0, 255), 2, lineType=cv2.LINE_AA)
# 绘制 AprilTag 的中心坐标
(cX, cY) = (int(r.center[0]), int(r.center[1]))
cv2.circle(image, (cX, cY), 5, (0, 0, 255), -1)
# 在图像上绘制标文本
tagFamily = r.tag_family.decode("utf-8")
cv2.putText(image, tagFamily, (a[0], a[1] - 15), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)
cv2.imwrite('image'+str(imageNum)+'.jpg', image)
cv2.namedWindow('Image', cv2.WINDOW_NORMAL)
cv2.imshow("Image", image)
cv2.waitKey(0)
elif frameState == False:
break
print('finish!')
cap.release()
deletenum=0
while deletenum<imageNum:
deletenum+=1
# Inbuilt function to remove files
os.remove("image" + str(deletenum) + '.jpg')
print("File removed successfully")
识别结果:可以看出来识别效果挺不错,
三、对摄像头中Apriltag编码二维码的识别
import pupil_apriltags as apriltag # for windows
import cv2
cap = cv2.VideoCapture(1) # 调用开启摄像头
at_detector = apriltag.Detector(families='tag36h11') # for windows
while True:
# 获得图像 ret判断是否获取到图像,frame储存图像帧
ret, frame = cap.read()
# 检测按键 按ESC键退出程序
k=cv2.waitKey(1)
if k==27:
break
# 检测apriltag
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
tags = at_detector.detect(gray)
for t in tags:
print('tag_id:', t.tag_id)
# 获取4个角点的坐标
b = (tuple(t.corners[0].astype(int))[0], tuple(t.corners[0].astype(int))[1])
c = (tuple(t.corners[1].astype(int))[0], tuple(t.corners[1].astype(int))[1])
d = (tuple(t.corners[2].astype(int))[0], tuple(t.corners[2].astype(int))[1])
a = (tuple(t.corners[3].astype(int))[0], tuple(t.corners[3].astype(int))[1])
# 绘制检测到的AprilTag的框
cv2.line(frame, a, b, (255, 0, 255), 2, lineType=cv2.LINE_AA)
cv2.line(frame, b, c, (255, 0, 255), 2, lineType=cv2.LINE_AA)
cv2.line(frame, c, d, (255, 0, 255), 2, lineType=cv2.LINE_AA)
cv2.line(frame, d, a, (255, 0, 255), 2, lineType=cv2.LINE_AA)
# 绘制 AprilTag 的中心坐标
(cX, cY) = (int(t.center[0]), int(t.center[1]))
cv2.circle(frame, (cX, cY), 5, (0, 0, 255), -1)
cv2.putText(frame, "tag36h11 tag_id:"+str(t.tag_id), (a[0], a[1] - 15), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)
# 显示检测结果
cv2.imshow('capture', frame)
cap.release()
cv2.destroyAllWindows()
识别效果展示:可以看出能同时识别多张不同apriltag编码二维码,且由于apriltag中tag36h11编码格式的二维码具有良好的识别性,识别结果不易出错。
_____________________________________________________________________________
12_16更新,终于把python代码在树莓派上运行时所需要的两个库配置好了,楼主之前没接触过树莓派raspbian系统,liunx也没用过,所用树莓派版本为将近10年前的3b版本,安装python库的时候用了很长时间,看了很多博主的帖子,重装了好几次树莓派系统。
参考树莓派安装python库链接:http://t.csdnimg.cn/wMBSx
如果看到这篇帖子的小伙伴有什么想法或建议,欢迎大家随时打扰我。