姿态估计在许多计算机视觉的应用中都是十分重要的环节,在机器人导航、增强现实等场景中广泛运用。这个过程主要基于找到点在真实3d环境中的坐标和2d图像中的对应坐标。这通常是一个比较困难的步骤,因此运用通用的标记物或者标准标号来使这个问题简单一点。

ArUco简介

ArUco是一个开源的微型的现实增强库,目前好像已经集成在OpenCV3.0以上的版本内了,它除了用于现实增强,还很用于实现一些机器视觉方面的应用,上图中的波士顿动力也曾用此方法用于Atlas的视觉定位,下面是两个重要的网址:

  ArUco下载地址:ArUco下载(可以下载2.0.19或3.0.0)

  ArUco的Marker生成网址:Marker生成(可以定制Marker的size、ID以及Padding)

  ArUco开源库的几个特点如下:

    1.基于C++;

    2.仅依赖于OpenCV(≥2.4.9)和Eigen3(源码中已经包含);

    3.BDS开源。

Demo

pip install opencv-contrib-python才有扩展模块,扩展模块中包含aruco

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#!/usr/bin/env python2
#-*- coding:utf-8 -*-

import cv2
import numpy as np
import glob
import matplotlib.pyplot as plt
import matplotlib.patches as patches


# 找棋盘格角点

criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001) # 阈值
#棋盘格模板规格
w = 9 # 10 - 1
h = 6 # 7 - 1
# 世界坐标系中的棋盘格点,例如(0,0,0), (1,0,0), (2,0,0) ....,(8,5,0),去掉Z坐标,记为二维矩阵
objp = np.zeros((w*h,3), np.float32)
objp[:,:2] = np.mgrid[0:w,0:h].T.reshape(-1,2)
objp = objp*18.1 # 18.1 mm

# 储存棋盘格角点的世界坐标和图像坐标对
objpoints = [] # 在世界坐标系中的三维点
imgpoints = [] # 在图像平面的二维点

images = glob.glob('./image/*.jpeg') # 拍摄的十几张棋盘图片所在目录

i = 1
for fname in images:

img = cv2.imread(fname)
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
# 找到棋盘格角点
ret, corners = cv2.findChessboardCorners(gray, (w,h),None)
# 如果找到足够点对,将其存储起来
if ret == True:
print("i:", i)
i = i+1

cv2.cornerSubPix(gray,corners,(11,11),(-1,-1),criteria)
objpoints.append(objp)
imgpoints.append(corners)
# 将角点在图像上显示
cv2.drawChessboardCorners(img, (w,h), corners, ret)
cv2.namedWindow('findCorners', cv2.WINDOW_NORMAL)
cv2.resizeWindow('findCorners', 810, 405)
cv2.imshow('findCorners',img)
cv2.waitKey(1)
cv2.destroyAllWindows()
#%% 标定
ret, mtx, dist, rvecs, tvecs = \
cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1], None, None)


print("ret:",ret )
print("mtx:\n",mtx) # 内参数矩阵
print("dist:\n",dist ) # 畸变系数 distortion cofficients = (k_1,k_2,p_1,p_2,k_3)
print("rvecs:\n",rvecs) # 旋转向量 # 外参数
print("tvecs:\n",tvecs ) # 平移向量 # 外参数

image-20200722115025204

运行结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
('i:', 1)
('ret:', 0.13208626458863457)
('mtx:\n', array([[5.59437366e+03, 0.00000000e+00, 1.00215404e+02],
[0.00000000e+00, 5.60128040e+03, 3.30492230e+02],
[0.00000000e+00, 0.00000000e+00, 1.00000000e+00]]))
('dist:\n', array([[-8.72904292e-01, 6.56007276e+01, 2.91616286e-05,
1.83077688e-02, -2.60847623e+03]]))
('rvecs:\n', [array([[ 1.95799885e-03],
[ 8.11435888e-03],
[-1.48322196e-06]])])
('tvecs:\n', [array([[ 3.34306017],
[ -56.90285439],
[1427.09696361]])])

错误

错误一

可能会提示

qt.qpa.plugin: Could not find the Qt platform plugin “cocoa” in “”
This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem.

解决办法

1
pip install opencv-python-headless

应该是版本的问题,最新版的opencv可能少了这个。
也可以安装其他老版的opencv来解决

1
pip install opencv-python==4.0.0.21

错误二

Error: Assertion failed (nimages > 0) in cv::calibrateCameraRO

原因:

① 图片路径问题,没有指向包含棋盘格的图片

② 图片中不包含棋盘格或者图片模糊等问题,导致查找棋盘格角点失败

解决方法:

① 仔细检查图片路径和棋盘格图片是否对应

② 检查棋盘格图片是否模糊,可以写个小tool显示找到角点的位置,如果发现图片有问题没有找到角点,就重新拍摄

原文

玩了下opencv的aruco(python版)

Detection of ArUco Markers