OpenCV 是一个实时计算机视觉库。它具有非常强大的功能,使处理图像和获取有关图像的信息变得容易。在这篇文章中,我们将回顾一些用于从图像进行 3D 重建以制造自主机械臂的功能。
OpenCV 使用针孔相机模型。该模型通过使用透视变换将 3D 点投影到图像平面上来工作。
OpenCV 有一些功能可以帮助我们实现目标。这些功能与棋盘模型配合使用以校准模型,因此首先是获取棋盘并拍摄一些照片。我们拍了几张照片以获得更好的校准。
import glob
import cv2
import numpy as np
criteria = (cv.TERM_CRITERIA_EPS + cv.TERM_CRITERIA_MAX_ITER, 30 , 0.001)
objp = np.zeros((9*6,3), np.float32)
objp[:,:2] = np.mgrid[0:6.0:9].T.reshape(-1,2)
objpoints = []
imgpoints = []
images = glob.glob('./Muestras_Calibracio/*.jpg')
for fname in images:
img = cv2.imread(fname)
gray = cv2.cvtColor(img,cv.COLOR_BGR2GRAY)
ret , corners = cv.findChessboardCorners(gray,(6,9), None)
if ret == True:
objpoints.append(objp)
corners2 = cv2.cornerSubPix(gray , corners , (11,11) , (-1,-1) , criteria)
imgpoints.append(corners)
cv2.drawChessboardCorners(img , (6,9) , corners2 , ret)
好的,我们已经看到了一小段代码,让我们来看看它的作用。
在第一行中,我们导入了必要的库。接下来,我们为 OpenCV 的迭代算法定义终止标准。我们在函数cornerSubPix 中使用它们。
下一个变量用于准备对象点,然后我们定义一些空数组来存储我们从棋盘中获得的所有图像的对象点和图像点。
然后我们以灰度打开我们拥有的所有图像,将它们作为参数传递给函数 findChessboardCorners()。这个函数有3个参数:第一个是图像,必须是8位灰度;第二个是每个棋盘的内角数,必须是一个元组(points_per_row,points_per_column);第三个是角落,在这种情况下,我们不想检测它们,所以我们放了 None。
下一步是使用cornerSubPix() 函数细化角点位置。然后我们在棋盘上画出角点位置。下一张图片显示了我们找到棋盘角点的位置以及我们绘制它们的位置。
所以我们刚刚找到了我们的对象点和图像点。我们已准备好进行相机校准。为了达到这个目的,我们使用函数 calibrateCamera()。此函数返回进行 3D 重建所需的所有参数——如相机矩阵、失真系数、旋转向量等。
在上一张图像中,我们在左侧看到输入图像,在右侧,我们看到上面绘制了轴的图像。
用例:自主机械臂
通过这些 2D-3D 投影,我们可以从图像中知道对象的空间坐标。所以我们决定实现这个 OpenCV 算法来制造一个自主的机械臂,但是如果我们想让它自主,我们需要使用一个对象检测模型,这样我们就可以知道我们要做的事情和在哪里抓住。
为此,我们使用 MASK r-cnn 模型在 Keras 和 TensorFlow 上进行对象检测和实例分割。
除了 MASK 模型,我们还使用 Arduino Mega 进行手臂控制,因为我们知道物体的位置,现在我们需要知道如何移动手臂来抓住它们。所以我们做了一个小 Arduino 函数来控制四个 arm 引擎中的每一个。
每个电机都有一个电位器作为测角器工作。这是通过计算电位器中的电压与发动机位置之间的关系来实现的。获得这种关系非常简单——它是一个线性回归。您可以在 Excel 或 OriginLab 上执行此操作。现在我们有了关系,我们将在 Arduino 中使用它,所以让我们准备一段代码:
在上图中,我们看到了一段用于 Arduino 编程的函数代码。每个引擎都有这些功能之一。
在上图中,我们看到了机械臂和棋盘的设置。我们使用手臂前的网络摄像头进行相机校准和 3D 重建。