使用OpenCV和Python进行3D重建

网友投稿 2019-08-04 14:58

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); 第三个是角落,在这种情况下我们不想检测它们,所以我们把无。下一步是使用cornerSubPix()函数细化角点位置。然后我们在棋盘上绘制角落。下一张图显示了我们找到棋盘角落的位置以及我们绘制它们的图像。

https://cdn.china-scratch.com/timg/190806/145PT132-0.jpg

所以我们只找到了我们的物点和图像点。我们准备好进行相机校准。为了达到这个目的,我们使用了calibrateCamera()函数。此函数返回进行3D重建所需的所有参数 - 如相机矩阵,失真系数,旋转矢量等。ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1],None,None)

我们现在有相机参数,所以我们将它们用于3D重建。

corners2 = cv2.cornerSubPix(gray,corners,(11,11),(-1,-1),criteria)
_, rvecs, tvecs, inliers = cv2.solvePnPRansac(objp, corners2, mtx, dist)
axis = np.float32( [ [0,0,0], [0,6,0], [6,6,0], [6,0,0], [0,0,-3],[0,6,-3],[6,6,-3],[6,0,-3] ] )
imgpts, jac = cv2.projectPoints(axis, rvecs, tvecs, mtx, dist)因此,在第一行中,我们进行了改进以改善角落的位置,然后应用我们之前获得的相机参数。在函数solvePnRansac()中,OpenCV使用迭代方法从3D-2D点对应中找到对象姿势,以从包含异常值的一组观察数据估计数学模型的参数。在第三行中,我们定义了我们的轴,以便在图片中创建一个框并在框中投影。下一步是投影点,然后使用draw()函数绘制它们。

https://cdn.china-scratch.com/timg/190806/145Pa025-1.jpg

在上一张图像中,我们在左侧看到输入图像,在右侧,我们看到了在其上绘制轴的图像。

使用案例:自主机器人手臂通过这些2D-3D投影,我们可以从图像中了解对象的空间坐标。所以我们决定实现这个OpenCV算法以制作一个自主的机器人手臂,但是如果我们想让它自主,我们需要使用一个对象检测模型,这样我们才能知道我们要去的东西是什么以及在哪里抓。为此,我们使用MASK r-cnn模型在Keras和TensorFlow上进行对象检测和实例分割。请查看此  GitHub  以获取有关该模型的更多具体信息。除了MASK模型,我们使用Arduino Mega进行手臂控制,因为我们知道物体的位置,现在我们需要知道如何移动手臂来抓住它们。所以我们制作了一个小的Arduino功能来控制四个臂引擎中的每一个。每个电机都有一个电位计作为测角仪。这是通过计算电位计中的电压和发动机位置之间的关系来实现的。获得这种关系非常简单 - 它是一种线性回归。您可以在Excel或OriginLab上执行此操作。现在我们已经建立了关系,我们将在Arduino中使用它,所以让我们准备一段代码:

https://cdn.china-scratch.com/timg/190806/145P91911-2.jpg

在上一张图中,我们看到了一段用于Arduino编程的函数代码。每个引擎都具有这些功能之一。

https://cdn.china-scratch.com/timg/190806/145P915P-3.jpg

在上图中,我们看到了机器人手臂和棋盘的设置。我们使用手臂前面的网络摄像头进行相机校准和3D重建。

--end--

声明:本文章由网友投稿作为教育分享用途,如有侵权原作者可通过邮件及时和我们联系删除:freemanzk@qq.com