OpenCV-Python姿势估计

在这一部分,我们会了解到如何利用 calib3d 模块在图像中实现 3D 效果。

姿势估计基础

这将仅是很小一部分。在上一章节(相机校准),你已经找到了相机矩阵,畸变系数等等参数。给出一个图案图像,我们便可以利用上面的信息用于计算其姿势,或者物体在空间中位于何处,比如如何旋转,如何移动等等问题。对于一个平面物体,我们可以假定 Z = 0,这样,问题现在便转化为了如何放置摄像机才能查看到我们的图案图像。所以如果我们知道物体在空间中的位置,我们便可以绘制一些 2D 图像用以模拟 3D 效果。让我们看一下如何做到这件事情。

我们的问题是,我们想在我们棋盘的第一个角上绘制 3D 坐标系(x, y, z 坐标系),其中 X 轴是蓝色,Y 轴是绿色,Z 轴是红色。所以从效果上讲,Z 轴应该感觉像是与棋盘垂直的。

首先,让我们读取从上一章节(相机校准)存储的结果中读取出相机矩阵与畸变参数。

import numpy as np
import cv2 as cv
import glob

# 读取事先存好的数据
with np.load('B.npz') as X:
    mtx, dist, _, _ = [X[i] for i in ('mtx','dist','rvecs','tvecs')]

现在让我们创建一个函数draw,用以利用棋盘角点(利用cv.findChessboardCorners()函数)和坐标轴点绘制 3D 坐标系。

def draw(img, corners, imgpts):
    corner = tuple(corners[0].ravel())
    img = cv.line(img, corner, tuple(imgpts[0].ravel()), (255,0,0), 5)
    img = cv.line(img, corner, tuple(imgpts[1].ravel()), (0,255,0), 5)
    img = cv.line(img, corner, tuple(imgpts[2].ravel()), (0,0,255), 5)
    return img

然后正如前面情况那样,我们创建了终止条件,物体点(棋盘上的 3D 角点)和坐标轴点。坐标轴点是 3D 空间中用于绘制轴的点。我们绘制长度为 3 的轴(单位是国际象棋的方形尺寸,我们会根据这个尺寸校准)。所以我们的 X 轴是从(0,0,0)到(3,0,0)绘制的,所以对于 Y 轴。对于 Z 轴,它是从(0,0,0)到(0,0,-3)绘制的。负数表示其接近摄像机。

criteria = (cv.TERM_CRITERIA_EPS + cv.TERM_CRITERIA_MAX_ITER, 30, 0.001)
objp = np.zeros((6*7,3), np.float32)
objp[:,:2] = np.mgrid[0:7,0:6].T.reshape(-1,2)

axis = np.float32([[3,0,0], [0,3,0], [0,0,-3]]).reshape(-1,3)

现在,像往常一样,我们读取一张图片。搜索 7x6 网格。如果我们找到了,我们用子角像素优化一下它,然后计算旋转和平移,我们使用cv.solvePnPRansac()函数。一旦我们计算完那些旋转矩阵后,我们便用它们来将我们的坐标轴点投影到平面图像上。简而言之,我们寻找到平面图象上的点对应 3D 空间里的(3,0,0), (0,3,0), (0,0,3)。一旦我们找到后,我们便可以从第一个角到每个我们找到的坐标轴点之间利用draw()函数连线。搞定!!!

for fname in glob.glob('left*.jpg'):
    img = cv.imread(fname)
    gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
    ret, corners = cv.findChessboardCorners(gray, (7,6),None)

    if ret == True:
        corners2 = cv.cornerSubPix(gray,corners,(11,11),(-1,-1),criteria)

        # 找到旋转和平移向量
        ret,rvecs, tvecs = cv.solvePnP(objp, corners2, mtx, dist)

        # 投射 3D 点到平面图像上
        imgpts, jac = cv.projectPoints(axis, rvecs, tvecs, mtx, dist)

        img = draw(img,corners2,imgpts)
        cv.imshow('img',img)
        k = cv.waitKey(0) & 0xFF
        if k == ord('s'):
            cv.imwrite(fname[:6]+'.png', img)

cv.destroyAllWindows()

请看下面的一些结果。注意,每个轴长 3 个方格:

OpenCV姿势估计

渲染立方体

如果你想要绘制一个立方体,你需要根据如下步骤改进draw()函数和坐标轴点。

改进draw()函数:

def draw(img, corners, imgpts):
    imgpts = np.int32(imgpts).reshape(-1,2)

    # 将底面绘制为绿色
    img = cv.drawContours(img, [imgpts[:4]],-1,(0,255,0),-3)

    # 将支柱绘制为蓝色
    for i,j in zip(range(4),range(4,8)):
        img = cv.line(img, tuple(imgpts[i]), tuple(imgpts[j]),(255),3)

    # 将顶面绘制为红色
    img = cv.drawContours(img, [imgpts[4:]],-1,(0,0,255),3)

    return img

改进坐标轴点。它们是 3D 空间中立方体的 8 个角:

axis = np.float32([ [0,0,0], [0,3,0], [3,3,0], [3,0,0],
                   [0,0,-3],[0,3,-3],[3,3,-3],[3,0,-3] ])

然后看上去就像下面这样:

OpenCV姿势估计

如果你对图形渲染,增强现实等感兴趣,你可以使用 OpenGL 来渲染更加复杂的图像。

赞(2)
未经允许不得转载:极客笔记 » OpenCV-Python姿势估计

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
OpenCV-Python介绍
OpenCV-Python 教程在Windows安装OpenCV-Python在Fedora上安装OpenCV-Python在Ubuntu系统中安装OpenCV—Python
OpenCV-Python GUI功能
OpenCV-Python图像入门OpenCV-Python视频入门OpenCV-Python绘图功能OpenCV-Python鼠标作为画笔OpenCV-Python作为调色板的跟踪栏
OpenCV-Python 核心操作
OpenCV-Python图像基本操作OpenCV-Python图像的算术运算OpenCV-Python性能测量和改进技术
OpenCV-Python 图像处理
OpenCV-Python改变颜色空间OpenCV-Python图像的几何变换OpenCV-Python图像阈值OpenCV-Python平滑图像OpenCV-Python形态转换OpenCV-Python图像梯度OpenCV-Python Canny边缘检测OpenCV-Python图像金字塔OpenCV-Python轮廓入门OpenCV-Python轮廓特征OpenCV-Python轮廓属性OpenCV-Python更多轮廓功能OpenCV-Python轮廓层次结构OpenCV-Python直方图-查找,绘图,分析OpenCV-Python直方图均衡OpenCV-Python 2D直方图OpenCV-Python直方图反投影OpenCV-Python图像转换OpenCV-Python模板匹配OpenCV-Python霍夫线变换OpenCV-Python霍夫圆变换OpenCV-Python基于分水岭算法的图像分割OpenCV-Python基于 GrabCut 算法的交互式前景提取
OpenCV-Python 特征检测
OpenCV-Python理解特征OpenCV-Python Harris 角点检测OpenCV-Python Shi-Tomasi 角点检测和追踪的良好特征OpenCV-Python SIFT 简介(尺度不变特征变换)OpenCV-Python SURF 简介(加速鲁棒特性)OpenCV-Python角点检测的 FAST 算法OpenCV-Python BRIEF(二进制鲁棒独立基本特征)OpenCV-Python ORB算法OpenCV-Python特征匹配OpenCV-Python特征匹配+单应性查找对象
OpenCV-Python 视频分析
OpenCV-Python Meanshift 和 CamshiftOpenCV-Python光流OpenCV-Python背景减法
OpenCV-Python 相机校准和3D重建
OpenCV-Python相机校准OpenCV-Python姿势估计OpenCV-Python线性几何OpenCV-Python立体图像的深度图
OpenCV-Python 机器学习
OpenCV-Python K-最近邻算法OpenCV-Python 使用 kNN 进行手写识别OpenCV-Python 理解 SVMOpenCV-Python 使用 SVM 进行手写数据识别OpenCV-Python 理解 K-Means 聚类OpenCV-Python 中的 K-Means 聚类
OpenCV-Python 计算摄影
OpenCV-Python 图像去噪OpenCV-Python 图像修复OpenCV-Python 高动态范围(HDR)