转载自:https://www.it610.com/article/1291934151255072768.htm
python下使用aruco标记进进行三维姿势估计视觉机器人 python3 aruco python opencv 计算机视觉 aruco ArUco标记首先什么是aruco标记呢?
aruco标记是可用于摄像机姿态估计的二进制方形基准标记。它的主要优点是检测简单、快速,并且具有很强的鲁棒性。ArUco 标记是由宽黑色边框和确定其标识符(ID)的内部二进制矩阵组成的正方形标记。aruco标记的黑色边框有助于其在图像中的快速检测,内部二进制编码用于识别标记和提供错误检测和纠正。aruco标记尺寸的大小决定内部矩阵的大小,例如尺寸为 4x4 的标记由 16 位二进制数组成。
通俗地说,aruco标记其实就是一种编码,就和我们日常生活中的二维码是相似的,只不过由于编码方式的不同,导致它们存储信息的方式、容量等等有所差异,所以在应用层次上也会有所不同。由于单个aruco标记就可以提供足够的对应关系,例如有四个明显的角点及内部的二进制编码,所以aruco标记被广泛用来增加从二维世界映射到三维世界时的信息量,便于发现二维世界与三维世界之间的投影关系,从而实现姿态估计、相机矫正等等应用。
OpenCV中的ArUco模块包括了对aruco标记的创建和检测,以及将aruco标记用于姿势估计和相机矫正等应用的相关API,同时还提供了标记板等等。本次笔记中主要先整理aruco标记的创建与检测。
首先我们创建aruco标记时,需要先指定一个字典,这个字典表示的是创建出来的aruco标记具有怎样的尺寸、怎样的编码等等内容,我们使用APIgetPredefinedDictionary()来声明我们使用的字典。在OpenCV中,提供了多种预定义字典,我们可以通过PredefineD_DICTIONARY_name来查看有哪些预定义字典。而且字典名称表示了该字典的aruco标记数量和尺寸,例如DICT_7X7_50表示一个包含了50种7x7位标记的字典。
ArUco标记生成器
在线aruco标记生成器:http://aruco.dgut.top/
(备用):https://chev.me/arucogen/
在OpenCV中生成ArUco标记opencv-python生成aruco标记确定好我们需要的字典后,就可以通过APIdrawMarker()
来绘制出aruco标记,其参数含义如下:
import cv2import numpy as np# 生成aruco标记# 加载预定义的字典dictionary = cv2.aruco.Dictionary_get(cv2.aruco.DICT_6X6_250)# 生成标记markerImage = np.zeros((200, 200), dtype=np.uint8)markerImage = cv2.aruco.drawMarker(dictionary, 22, 200, markerImage, 1)cv2.imwrite("marker22.png", markerImage)
opencv的aruco模块共有25个预定义的标记词典。每个词典中所有的Aruco标记均包含相同数量的块或位(例如4×4、5×5、6×6或7×7),且每个词典中Aruco标记的数量固定(例如50、100、250或1000)。
cv2.aruco.Dictionary_get()
函数会加载cv2.aruco.DICT_6X6_250
包含250个标记的字典,其中每个标记都是6×6位二进制模式
cv2.aruco.drawMarker(dictionary, 22, 200, markerImage, 1)
中的第二个参数22
是aruco的标记ID(0~249),第三个参数决定生成的标记的大小,在上面的示例中,它将生成200×200
像素的图像,第四个参数表示将要存储aruco标记的对象(上面的markerImage
),最后,第五个参数是边界宽度参数,它决定应将多少位(块)作为边界添加到生成的二进制图案中。
执行后将会生成这样的标记:标记ID分别是22
展开所支持的标记字典
展开查看的内容;DICT_4X4_50 Python: cv.aruco.DICT_4X4_50DICT_4X4_100 Python: cv.aruco.DICT_4X4_100DICT_4X4_250 Python: cv.aruco.DICT_4X4_250DICT_4X4_1000 Python: cv.aruco.DICT_4X4_1000DICT_5X5_50 Python: cv.aruco.DICT_5X5_50DICT_5X5_100 Python: cv.aruco.DICT_5X5_100DICT_5X5_250 Python: cv.aruco.DICT_5X5_250DICT_5X5_1000 Python: cv.aruco.DICT_5X5_1000DICT_6X6_50 Python: cv.aruco.DICT_6X6_50DICT_6X6_100 Python: cv.aruco.DICT_6X6_100DICT_6X6_250 Python: cv.aruco.DICT_6X6_250DICT_6X6_1000 Python: cv.aruco.DICT_6X6_1000DICT_7X7_50 Python: cv.aruco.DICT_7X7_50DICT_7X7_100 Python: cv.aruco.DICT_7X7_100DICT_7X7_250 Python: cv.aruco.DICT_7X7_250DICT_7X7_1000 Python: cv.aruco.DICT_7X7_1000DICT_ARUCO_ORIGINAL Python: cv.aruco.DICT_ARUCO_ORIGINALDICT_APRILTAG_16h5 Python: cv.aruco.DICT_APRILTAG_16h54x4 bits, minimum hamming distance between any two codes = 5, 30 codes
批量生成aruco标记
import cv2import numpy as np# 生成aruco标记# 加载预定义的字典dictionary = cv2.aruco.Dictionary_get(cv2.aruco.DICT_6X6_250)# 生成标记markerImage = np.zeros((200, 200), dtype=np.uint8)for i in range(30): markerImage = cv2.aruco.drawMarker(dictionary, i, 200, markerImage, 1); firename='armark/'+str(i)+'.png' cv2.imwrite(firename, markerImage);
在armark文件夹下会生成一系列的6*6 aruco标记
Aruco标记的检测和定位静态检测
在环境中图像检测Aruco标记,环境中有7个标记
import numpy as npimport timeimport cv2import cv2.aruco as aruco#读取图片frame=cv2.imread('img_3739.jpg')#调整图片大小frame=cv2.resize(frame,None,fx=0.2,fy=0.2,interpolation=cv2.INTER_CUBIC)#灰度话gray = cv2.cvtcolor(frame, cv2.color_BGR2GRAY)#设置预定义的字典aruco_dict = aruco.Dictionary_get(aruco.DICT_6X6_250)#使用默认值初始化检测器参数parameters = aruco.DetectorParameters_create()#使用aruco.detectMarkers()函数可以检测到marker,返回ID和标志板的4个角点坐标corners, IDs, rejectedimgPoints = aruco.detectMarkers(gray,aruco_dict,parameters=parameters)#画出标志位置aruco.drawDetectedMarkers(frame, corners,IDs)cv2.imshow("frame",frame)cv2.waitKey(0)cv2.destroyAllwindows()
对于每次成功检测到标记,将按从左上,右上,右下和左下的顺序检测标记的四个角点。在C ++中,将这4个检测到的角点存储为点矢量,并将图像中的多个标记一起存储在点矢量容器中。在Python中,它们存储为Numpy 数组。
第一个参数
detectMarkers()
函数用于检测和确定标记角点的位置。image
是带有标记的场景图像。第二个参数dictionary
是用于生成标记的字典。成功检测到的标记将存储在markerCorners中,其ID存储在markerIDs中。先前初始化的DetectorParameters对象作为传递参数。第三个参数parameters
:DetectionParameters
类的对象,该对象包括在检测过程中可以自定义的所有参数;返回参数corners
:检测到的aruco标记的角点列表,对于每个标记,其四个角点均按其原始顺序返回(从右上角开始顺时针旋转),第一个角是右上角,然后是右下角,左下角和左上角。返回IDs
:检测到的每个标记的 ID,需要注意的是第三个参数和第四个参数具有相同的大小;返回参数rejectedimgPoints
:抛弃的候选标记列表,即检测到的、但未提供有效编码的正方形。每个候选标记也由其四个角定义,其格式与第三个参数相同,该参数若无特殊要求可以省略。
corners, IDs, rejectedimgPoints = aruco.detectMarkers(gray,aruco_dict,parameters=parameters)
当我们检测到aruco标签之后,为了方便观察,我们需要进行可视化 *** 作,把标签标记出来:使用drawDetectedMarkers()
这个API来绘制检测到的aruco标记,其参数含义如下:
参数image: 是将绘制标记的输入 / 输出图像(通常就是检测到标记的图像)参数corners:检测到的aruco标记的角点列表参数IDs:检测到的每个标记对应到其所属字典中的ID,可选(如果未提供)不会绘制ID。参数bordercolor:绘制标记外框的颜色,其余颜色(文本颜色和第一个角颜色)将基于该颜色进行计算,以提高可视化效果。无返回值
aruco.drawDetectedMarkers(image, corners,IDs,bordercolor)
效果演示:
动态检测
利用摄像头进行一个实时动态监测aruco标记并且估计姿势,摄像头的内参需要提前标定,如何标定请看我另一篇文章
import numpy as npimport timeimport cv2import cv2.aruco as aruco# mtx = np.array([# [2946.48, 0, 1980.53],# [ 0, 2945.41, 1129.25],# [ 0, 0, 1],# ])# #我的手机拍棋盘的时候图片大小是 4000 x 2250# #ip摄像头拍视频的时候设置的是 1920 x 1080,长宽比是一样的,# #ip摄像头设置分辨率的时候注意一下### dist = np.array( [0.226317, -1.21478, 0.00170689, -0.000334551, 1.9892] )#相机纠正参数# dist=np.array(([[-0.51328742, 0.33232725 , 0.01683581 ,-0.00078608, -0.1159959]]))## mtx=np.array([[464.73554153, 0.00000000e+00 ,323.989155],# [ 0., 476.72971528 ,210.92028],# [ 0., 0., 1. ]])dist=np.array(([[-0.58650416 , 0.59103816, -0.00443272 , 0.00357844 ,-0.27203275]]))newcameramtx=np.array([[189.076828 , 0. , 361.20126638] ,[ 0 ,2.01627296e+04 ,4.52759577e+02] ,[0, 0, 1]])mtx=np.array([[398.12724231 , 0. , 304.35638757], [ 0. , 345.38259888, 282.49861858], [ 0., 0., 1. ]])cap = cv2.VIDeoCapture(0)Font = cv2.Font_HERShey_SIMPLEX #Font for displaying text (below)#num = 0while True: ret, frame = cap.read() h1, w1 = frame.shape[:2] # 读取摄像头画面 # 纠正畸变 newcameramtx, roi = cv2.getoptimalNewCameraMatrix(mtx, dist, (h1, w1), 0, (h1, w1)) dst1 = cv2.undistort(frame, mtx, dist, None, newcameramtx) x, y, w1, h1 = roi dst1 = dst1[y:y + h1, x:x + w1] frame=dst1 gray = cv2.cvtcolor(frame, cv2.color_BGR2GRAY) aruco_dict = aruco.Dictionary_get(aruco.DICT_6X6_250) parameters = aruco.DetectorParameters_create() dst1 = cv2.undistort(frame, mtx, dist, None, newcameramtx) ''' detectMarkers(...) detectMarkers(image, dictionary[, corners[, IDs[, parameters[, rejectedI mgPoints]]]]) -> corners, IDs, rejectedimgPoints ''' #使用aruco.detectMarkers()函数可以检测到marker,返回ID和标志板的4个角点坐标 corners, IDs, rejectedimgPoints = aruco.detectMarkers(gray,aruco_dict,parameters=parameters)# 如果找不打ID if IDs is not None: rvec, tvec, _ = aruco.estimatePoseSingleMarkers(corners, 0.05, mtx, dist) # 估计每个标记的姿态并返回值rvet和tvec ---不同 # from camera coeficcIEnts (rvec-tvec).any() # get rID of that nasty numpy value array error# aruco.drawAxis(frame, mtx, dist, rvec, tvec, 0.1) #绘制轴# aruco.drawDetectedMarkers(frame, corners) #在标记周围画一个正方形 for i in range(rvec.shape[0]): aruco.drawAxis(frame, mtx, dist, rvec[i, :, :], tvec[i, :, :], 0.03) aruco.drawDetectedMarkers(frame, corners) ###### DRAW ID ##### cv2.putText(frame, "ID: " + str(IDs), (0,64), Font, 1, (0,255,0),2,cv2.liNE_AA) else: ##### DRAW "NO IDS" ##### cv2.putText(frame, "No IDs", (0,64), Font, 1, (0,255,0),2,cv2.liNE_AA) # 显示结果框架 cv2.imshow("frame",frame) key = cv2.waitKey(1) if key == 27: # 按esc键退出 print('esc break...') cap.release() cv2.destroyAllwindows() break if key == ord(' '): # 按空格键保存# num = num + 1# filename = "frames_%s.jpg" % num # 保存一张图像 filename = str(time.time())[:10] + ".jpg" cv2.imwrite(filename, frame)
效果博客地址:https://blog.dgut.top/2020/07/15/python-aruco/
本文参考:
1.https://blog.csdn.net/sinat_17456165/article/details/105649131
2.https://www.learnopencv.com/augmented-reality-using-aruco-markers-in-opencv-c-python/
总结以上是内存溢出为你收集整理的python下使用aruco标记进进行三维姿势估计(转载)全部内容,希望文章能够帮你解决python下使用aruco标记进进行三维姿势估计(转载)所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)