【OpenCV-Python】教程:6-2 Pose Estimation (姿态估计)

news2025/1/12 21:02:43

OpenCV Python Pose Estimation (姿态估计)

【目标】

  • 利用calib3d模块在图像中创建一些3D效果。

【理论】

这是一小部分。在上一节中,已经找到了摄像机矩阵,失真系数等。给定一个图案图像,我们可以利用上面的信息来计算它的姿态,或者物体在空间中的位置,比如它是如何旋转的,它是如何位移的等等。对于平面物体,我们可以假设Z=0,这样,现在的问题是如何将相机放置在空间中以看到我们的模式图像。因此,如果我们知道物体在空间中的位置,我们就可以在其中绘制一些2D图来模拟3D效果。让我们看看怎么做。

我们的问题是,我们想要在棋盘的第一个角上绘制3D坐标轴(X, Y, Z轴)。X轴为蓝色,Y轴为绿色,Z轴为红色。所以实际上,Z轴应该是垂直于棋盘平面的。

【代码】

在上一章节中,以下代码可以用

############## 保存参数
np.savez("left.npz", mtx=mtx, dist=dist,rvecs=rvecs,tvecs=tvecs )

保存相机矩阵参数和失真参数等;

可以用以下代码提取保存的参数

npzfile = np.load("left.npz")
sorted(npzfile.files)

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

import numpy as np 
import cv2 
import glob

# 加载之前保存的参数
with np.load('left.npz') as X:
    mtx, dist, _, __ = [X[i] for i in ('mtx', 'dist', 'rvecs', 'tvecs')]
    # mtx, dist, rvecs, tvecs = [X[i] for i in ('mtx', 'dist', 'rvecs', 'tvecs')]


# 画 3D 坐标轴
def draw_line(img, corners, imgpts):
    corner = tuple(corners[0].ravel())
    ## 注意,此处的数据一定要转化成 int32 格式,否则 OpenCV 报错
    img = cv2.line(img, np.int32(corner), np.int32(tuple(imgpts[0].ravel())), (255, 0, 0), 5)
    img = cv2.line(img, np.int32(corner), np.int32(tuple(imgpts[1].ravel())), (0, 255, 0), 5)
    img = cv2.line(img, np.int32(corner), np.int32(tuple(imgpts[2].ravel())), (0, 0, 255), 5)
    return img

# 画 3D 立方体
def draw_cube(img, corners, imgpts):
    imgpts = np.int32(imgpts).reshape(-1,2)
    print(imgpts)
    # 绿色画棋盘面
    img = cv2.drawContours(img, [imgpts[:4]],-1,(0,255,0),-3)
  
    # 蓝色画柱子
    for i,j in zip(range(4),range(4,8)):
        img = cv2.line(img, tuple(imgpts[i]), tuple(imgpts[j]),(255),3)
  
    # 红色画顶
    img = cv2.drawContours(img, [imgpts[4:]],-1,(0,0,255),3)
    return img


criteria = (cv2.TERM_CRITERIA_EPS + cv2.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)

axis_cube = 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]])

for fname in glob.glob('assets/left/left*.jpg'):
    img = cv2.imread(fname)
    img_cube = cv2.imread(fname)
  
    print(fname)
  
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    ret, corners = cv2.findChessboardCorners(gray, (7, 6), None)
    if ret == True:
        corners2 = cv2.cornerSubPix(gray, corners, (11, 11), (-1, -1), criteria)
  
        # 找到旋转和平移向量
        ret, rvecs, tvecs = cv2.solvePnP(objp, corners2, mtx, dist)
  
        # 将3D点映射到平面上
        imgpts, jac = cv2.projectPoints(axis, rvecs, tvecs, mtx, dist)
        img = draw_line(img, corners2, imgpts)
  
        # cube point
        imgpts_cube, jac_cube = cv2.projectPoints(axis_cube, rvecs, tvecs, mtx, dist)  
        img_cube = draw_cube(img_cube, corners, imgpts_cube)
  
        cv2.imshow('img', img)  
        cv2.imshow('img_cube', img_cube)
        k = cv2.waitKey(0) & 0xFF
        if k == ord('s'):
            cv2.imwrite(fname[:-4]+'_result.jpg', img)
cv2.destroyAllWindows()

【接口】

  • solvePnP
cv.solvePnP(	objectPoints, imagePoints, cameraMatrix, distCoeffs[, rvec[, tvec[, useExtrinsicGuess[, flags]]]]	) ->	retval, rvec, tvec

寻找和求解目标点在3D空间里的位置到2D空间里的映射

参考 Perspective-n-Point (PnP) pose computation
这个函数返回旋转和平移向量,将物体坐标框架中表示的3D点转换为相机坐标框架,使用不同的方法:

  • P3P methods (SOLVEPNP_P3P, SOLVEPNP_AP3P): need 4 input points to return a unique solution.
  • SOLVEPNP_IPPE Input points must be >= 4 and object points must be coplanar.
  • SOLVEPNP_IPPE_SQUARE Special case suitable for marker pose estimation. Number of input points must be 4. Object points must be defined in the following order:
    • point 0: [-squareLength / 2, squareLength / 2, 0]
    • point 1: [ squareLength / 2, squareLength / 2, 0]
    • point 2: [ squareLength / 2, -squareLength / 2, 0]
    • point 3: [-squareLength / 2, -squareLength / 2, 0]
  • for all the other flags, number of input points must be >= 4 and object points can be in any configuration.

参数

  • objectPoints:目标点数组, N × 3 N×3 N×3 1 通道的,或者是 1 × N / N × 1 1×N/N×1 1×N/N×1 3 通道的。其中 N N N 是点的个数
  • imagePoints: 图像中对应的点, N × 2 N×2 N×2 1 通道的,或者是 1 × N / N × 1 1×N/N×1 1×N/N×1 2 通道的。其中 N N N 是点的个数
  • cameraMatrix: 相机内参矩阵
    A = [ f x 0 c x 0 f y c y 0 0 1 ] A=\begin{bmatrix} f_x & 0 & c_x \\ 0 & f_y & c_y \\ 0 & 0 & 1 \end{bmatrix} A= fx000fy0cxcy1
  • distCoeffs: 失真系数 ( k 1 , k 2 , p 1 , p 2 [ , k 3 [ , k 4 , k 5 , k 6 [ , s 1 , s 2 , s 3 , s 4 [ , τ x , τ y ] ] ] ] ) (k_1,k_2,p_1,p_2[,k_3[,k_4,k_5,k_6[,s_1,s_2,s_3,s_4[,τ_x,τ_y]]]]) (k1,k2,p1,p2[,k3[,k4,k5,k6[,s1,s2,s3,s4[,τx,τy]]]]) ,个数为 4, 5, 8, 12 或14. 如果为空,则假设没有失真;
  • rvec: 输出的旋转矩阵
  • tvec: 输出的平移矩阵
  • useExtrinsicGuess: 用于SOLVEPNP_ITERATIVE.的参数。如果为true(1),则函数使用提供的rvec和tvec值分别作为旋转和平移向量的初始近似值,并进一步优化它们。
  • flags: SolvePnPMethod
    在这里插入图片描述
  • projectPoints
cv2.projectPoints(	objectPoints, rvec, tvec, cameraMatrix, distCoeffs[, imagePoints[, jacobian[, aspectRatio]]]	) ->	imagePoints, jacobian

将3D点转换为图像平面里的点

  • objectPoints:目标点数组, N × 3 N×3 N×3 1 通道的,或者是 1 × N / N × 1 1×N/N×1 1×N/N×1 3 通道的。其中 N N N 是点的个数
  • rvec: 旋转矩阵
  • tvec: 平移矩阵
  • cameraMatrix: 相机内参矩阵
    A = [ f x 0 c x 0 f y c y 0 0 1 ] A=\begin{bmatrix} f_x & 0 & c_x \\ 0 & f_y & c_y \\ 0 & 0 & 1 \end{bmatrix} A= fx000fy0cxcy1
  • distCoeffs: 失真系数 ( k 1 , k 2 , p 1 , p 2 [ , k 3 [ , k 4 , k 5 , k 6 [ , s 1 , s 2 , s 3 , s 4 [ , τ x , τ y ] ] ] ] ) (k_1,k_2,p_1,p_2[,k_3[,k_4,k_5,k_6[,s_1,s_2,s_3,s_4[,τ_x,τ_y]]]]) (k1,k2,p1,p2[,k3[,k4,k5,k6[,s1,s2,s3,s4[,τx,τy]]]]) ,个数为 4, 5, 8, 12 或14. 如果为空,则假设没有失真;
  • imagePoints: 图像中对应的点, N × 2 N×2 N×2 1 通道的,或者是 1 × N / N × 1 1×N/N×1 1×N/N×1 2 通道的。其中 N N N 是点的个数
  • jacobian: 可选输出 2 N × ( 10 + < n u m D i s t C o e f f s > ) 2N×(10+<numDistCoeffs>) 2N×(10+<numDistCoeffs>)图像点导数相对于旋转矢量、平移矢量、焦距、主点坐标和失真系数的分量的雅可比矩阵。在旧的接口中,雅可比矩阵的不同分量通过不同的输出参数返回。
  • aspectRatio: 可选“固定纵横比”参数。如果参数不为0,则函数假定纵横比(fx/fy)是固定的,并相应地调整雅可比矩阵。
  • findChessboardCorners

【OpenCV-Python】教程:6-1 相机标定_黄金旺铺的博客-CSDN博客

  • cornerSubPix

【OpenCV-Python】教程:4-2 Harris角点检测_黄金旺铺的博客-CSDN博客

【参考】

  1. OpenCV: Pose Estimation
  2. OpenCV: Camera Calibration and 3D Reconstruction
  3. Eric Marchand, Hideaki Uchiyama, and Fabien Spindler. Pose Estimation for Augmented Reality: A Hands-On Survey. IEEE Transactions on Visualization and Computer Graphics , 22(12):2633 – 2651, December 2016.
  4. OpenCV: Perspective-n-Point (PnP) pose computation
  5. Python numpy.savez用法及代码示例 - 纯净天空 (vimsky.com)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/94413.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【云原生进阶之容器】第一章Docker核心技术1.5.2节——cgroups原理剖析

2 cgroups原理解析 上面是说的cgroups 是内核提供的功能,但现在我们在用户空间想使用的是cgroup的功能。其原理是:linux 内核有一个很强大的模块叫做VFS(vritual File System),VFS 把具体的文件系统的细节隐藏起来,给用户态进程提供一个完备的文件系统API接口。linux 也是通…

昆仑万维重磅发布AIGC全系列算法与模型,领跑未来

2022年12月15日&#xff0c;昆仑万维在北京举行AIGC技术发布会&#xff0c;会上昆仑万维CEO方汉正式发布了「昆仑天工」AIGC全系列算法与模型&#xff0c;并宣布模型开源。「昆仑天工」旗下模型包括天工巧绘SkyPaint、天工乐府SkyMusic、天工妙笔SkyText、天工智码SkyCode&…

[附源码]Python计算机毕业设计高校学科竞赛报名系统Django(程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程 项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等…

四、移动手机自动化测试

移动手机自动化测试4.1 Appium 介绍4.1.1 Appium 中的常用术语1. Session2. Desired Capabilities3. Appium Server4.1.2 Appium 服务关键字Appium 服务相关参数的说明4.1 Appium 介绍 Appium 是一个开源、跨平台的自动化测试工具&#xff0c;可以用来测试 Native 及混合的移动…

Web3中文|Reddit用户在Polygon上铸造了超500万个NFT

Reddit用户通过Collectible Avatars 计划&#xff0c;已经铸造了超过 500 万个NFT。 Reddit的NFT头像是在以太坊扩展网络Polygon上铸造的&#xff0c;大多数都是免费赠送给Reddit用户。 在NFT销量下滑和加密货币市场动荡的情况下&#xff0c;Reddit对NFT头像的推动是一个罕见…

Spring 之类元数据封装—MetadataReader

在 Spring 中最喜欢干的事情就是将多个参数封装到一个对象&#xff0c;这里就挑选一个例子讲讲——MetadataReader&#xff0c;这个对象是将一个类封装成了三部分&#xff1a;File 文件本身&#xff0c;类元数据&#xff0c;注解元数据。 MetadataReader 元数据对象 先看下这…

架构设计(四):CDN

架构设计&#xff08;四&#xff09;&#xff1a;CDN 作者&#xff1a;Grey 原文地址&#xff1a; 博客园&#xff1a;架构设计&#xff08;四&#xff09;&#xff1a;CDN CSDN&#xff1a;架构设计&#xff08;四&#xff09;&#xff1a;CDN CDN 全称 Content delivery…

Redis面试准备

1. redis网站 Redis Redis文档中心 -- Redis中国用户组&#xff08;CRUG&#xff09; 数据库排名网站&#xff1a;DB-Engines - Knowledge Base of Relational and NoSQL Database Management Systems 2. 基础知识 磁盘中的寻址速度是毫秒级&#xff0c;内存中寻址速度是纳…

[ vulhub漏洞复现篇 ] struts2远程代码执行漏洞s2-048(CVE-2017-9791)

一、漏洞编号 s2-048 CVE-2017-9791二、影响范围 Apache Struts 2.3.x系列中启用了struts2-struts1-plugin插件的版本三、漏洞描述 Apache Struts2 2.3.x 系列启用了struts2-struts1-plugin 插件并且存在 struts2-showcase 目录,其漏洞成因是当ActionMessage接收客户可控的参…

【论文精读】Focal Inverse Distance Transform Maps for Crowd Localization

文章目录摘要主要贡献主要内容一、FIDT二、LMDS三。I-SSIM loss摘要 在本文中&#xff0c;我们关注人群定位任务&#xff0c;这是人群分析的一个重要课题。基于回归的方法大多使用卷积神经网络( CNN )对密度图进行回归&#xff0c;在极度稠密的场景中无法准确定位实例&#xf…

跨境卖家如何以最少量的预算建立品牌知名度?

关键词&#xff1a;跨境卖家、品牌知名度 什么是品牌知名度&#xff1f; 品牌知名度反映了您的目标受众对您的品牌的了解、认可和记忆程度。 为什么品牌知名度至关重要&#xff1f; 当您的目标受众需要您提供的产品或服务时&#xff0c;您希望他们考虑您的品牌。为此&#xf…

windows下nginx隐藏HTTP 请求头文件中的Server信息

简介 本文主要是隐藏HTTP 请求头文件中的Server信息 解决问题主要分下面几步 一、准备编译所需要的环境 二、修改nginx源码改变配置 三、编译nginx源码生成新的nginx.exe 四、替换nginx.exe&#xff0c;重新启动nginx 1. 准备所需环境 环境都需要准备好&#xff0c;因为编译是…

精品spring boot+MySQL线上点餐系统vue

《spring bootMySQL线上点餐系统》该项目含有源码、论文等资料、配套开发软件、软件安装教程、项目发布教程等 使用技术&#xff1a; 操作系统&#xff1a;Windows 10、Windows 7、Windows 8 开发语言&#xff1a;Java 使用框架&#xff1a;spring boot 前端技术&#xff…

大数据毕业设计人体跌倒检测系统

文章目录前言1 实现方法传统机器视觉算法基于机器学习的跌倒检测SVM简介SVM跌倒检测原理算法流程算法效果实现代码深度学习跌倒检测最终效果网络原理最后前言 背景和意义 在美国&#xff0c;每年在65岁以上老人中&#xff0c;平均每3人中就有1人发生意外跌倒&#xff0c;每年…

[附源码]Node.js计算机毕业设计关于人脸识别的实验教学管理系统Express

项目运行 环境配置&#xff1a; Node.js最新版 Vscode Mysql5.7 HBuilderXNavicat11Vue。 项目技术&#xff1a; Express框架 Node.js Vue 等等组成&#xff0c;B/S模式 Vscode管理前后端分离等等。 环境需要 1.运行环境&#xff1a;最好是Nodejs最新版&#xff0c;我…

嵌入式分享合集122

一、分析电容降压电路工作原理 电容降压电路&#xff0c;因其成本低廉、体积小而被广泛地使用&#xff0c;此一优点足以掩盖其它所有缺点&#xff1a;输出电流小&#xff08;一般控制在100mA以内&#xff09;&#xff0c;与市电直通非隔离而存在安全隐患&#xff0c;输出电压波…

饥荒服务器搭建(windows)

文章目录1. 获取服务器票据2. 新建游戏存档3. 饥荒服务器配置1. 获取服务器票据 步骤1&#xff1a;登录Klei官网 步骤2&#xff1a;点击菜单栏游戏——选择饥荒服务器 步骤3&#xff1a;创建服务器获取票据&#xff0c;后面将会用到。 2. 新建游戏存档 步骤1&#xff1a;下载…

Python开发游戏?也太好用了吧

程序员宝藏库&#xff1a;https://gitee.com/sharetech_lee/CS-Books-Store 当然可以啦&#xff01; 现在日常能够用到和想到的场景&#xff0c;绝大多数都可以用Python实现。 效果怎么样暂且不提&#xff0c;但是得益于丰富的第三方工具包&#xff0c;的确让Python能够很容易…

二进制包安装公有云版k8s

目录公有云版k8s的架构是怎样的公有云中创建k8s实例的过程如下二进制法创建k8s的一般过程Kubernetes的重要性check nodes每台服务器执行基线配置CA rootetcd HA cluster根据CA根证书创建etcd的专有CA证书将etcd注册成为systemd服务配置各master节点的etcd.confansible配置各个m…

4线SPI驱动OLED常规操作

拿到一块点阵屏幕&#xff0c;首先找卖家拿驱动例程 步骤 目录 1.void LCD_IO_Cfg(void) 2.void wr_cmd(u8 wrcmd) 3.void wr_data(u8 wrdata) 4.void init_lcd(void) 5.void disp_all(void) 6.void Fresh(void) 注&#xff1a;根据商家的时序图可以知道数据在上升沿/下降…