OpenCV-Python(43):姿势估计

目标

  • 学习了解calib3D 模块
  • 学习在图像中创建3D效果

calib3D模块

        OpenCV-Python的calib3D模块是OpenCV库中的一个重要模块,用于摄像头标定和三维重建等计算机视觉任务。该模块提供了一些函数和类,用于摄像头标定、立体视觉和三维重建等方面的操作。

下面是一些calib3D模块常用的函数和类的介绍:

1.findChessboardCorners():用于在一张图片中查找棋盘格角点的函数。可以用于摄像头标定。

2.calibrateCamera():用于摄像头标定的函数。根据一系列已知世界坐标和对应的图像坐标,计算出相机内参数和畸变系数。

3.undistort():用于去除图像畸变的函数。根据相机内参数和畸变系数,对图像进行去畸变处理。

4.stereoCalibrate():用于立体标定的函数。根据一系列已知的立体对应点对,计算出两个相机的内参数、外参数和立体校正参数。

5.stereoRectify():用于立体校正的函数。根据相机的内参数、外参数和立体校正参数,对两个输入图像进行立体校正,以便进行立体匹配。

6.stereoSGBM():用于立体匹配的函数。根据两个校正后的图像,进行视差计算并生成视差图。

 摄像头标定步骤

        使用calib3D模块进行摄像头标定的基本步骤如下:

  1. 准备一系列棋盘格图像,保证棋盘格在各个位置、角度和距离上都有充分的变化。
  2. 对每张图像,使用findChessboardCorners()函数查找棋盘格角点,并将角点的图像坐标和对应的世界坐标存储起来。
  3. 使用calibrateCamera()函数对所有的角点进行摄像头标定,得到相机的内参数和畸变系数。
  4. 使用undistort()函数对图像进行去畸变处理,得到校正后的图像。

立体视觉步骤

使用calib3D模块进行立体视觉的基本步骤如下:

  1. 准备一系列立体对应点对,包括左右图像的图像坐标和世界坐标。
  2. 使用stereoCalibrate()函数对立体对应点对进行立体标定,得到两个相机的内参数、外参数和立体校正参数。
  3. 使用stereoRectify()函数对输入图像进行立体校正,得到校正后的图像。
  4. 使用stereoSGBM()函数对校正后的图像进行立体匹配,得到视差图。

姿势估计基础

        在上一节的摄像机标定中,我们已经得到了摄像机矩阵,畸变系数等。有了这些信息我们就可以估计图像中图案的姿势,比如目标对象是如何摆放,如何旋转等。对一个平面来说,我们可以假 Z=0,这样问题就转化成摄像机在空间中是如何摆放(然后拍摄)的。所以,如果我们知道对象在空间中的姿势,我们就可以在图像中绘制一些2D 的线条来产生3D 的效果。我们来看一下怎么做吧。

        我们的问题是,在棋盘的第一个角点绘制3D 坐标(X,Y,Z轴)。X轴为蓝色,Y 轴为绿色,Z 轴为红色。在视觉效果上来看,Z 轴应该是垂直与棋盘平面的。

        首先我们要加载前面结果中摄像机矩阵和畸变系数。

import cv2
import numpy as np
import glob# Load previously saved data
with np.load('B.npz') as X:mtx, dist, _, _ = [X[i] for i in ('mtx','dist','rvecs','tvecs')]

        现在创建一个函数:draw,它的参数有棋盘上的角点(使用cv2.findChessboardCorners() 得到)和要绘制的3D 坐标轴上的点。 

def draw(img, corners, imgpts):corner = tuple(corners[0].ravel())img = cv2.line(img, corner, tuple(imgpts[0].ravel()), (255,0,0), 5)img = cv2.line(img, corner, tuple(imgpts[1].ravel()), (0,255,0), 5)img = cv2.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 = (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)

        很通常一样我们需要加载图像。搜寻7x6 的格子,如果发现,我们就把它优化到亚像素级。然后使用函数:cv2.solvePnPRansac() 来计算旋转和变换。当我们有了变换矩阵之后,我们就可以利用它们将这些坐标轴点映射到图像平面中去。简单来说,我们在图像平面上找到了与3D 空间中的点(3,0,0),(0,3,0),(0,0,3) 相对应的点。然后我们就可以使用我们的函数draw() 从图像上的第一个角点开始绘制连接这些点的直线了。搞定!!!

for fname in glob.glob('left*.jpg'):img = cv2.imread(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)# Find the rotation and translation vectors.rvecs, tvecs, inliers = cv2.solvePnPRansac(objp, corners2, mtx, dist)# project 3D points to image planeimgpts, jac = cv2.projectPoints(axis, rvecs, tvecs, mtx, dist)img = draw(img,corners2,imgpts)cv2.imshow('img',img)k = cv2.waitKey(0) & 0xffif k == 's':cv2.imwrite(fname[:6]+'.png', img)
cv2.destroyAllWindows()

        结果如下,看到了没,每条坐标轴的长度都是3 个格子的长度。 

渲染一个立方体 

         如果你想绘制一个立方体的话要对draw() 函数进行如下修改,修改后的draw() 函数:

def draw(img, corners, imgpts):imgpts = np.int32(imgpts).reshape(-1,2)# draw ground floor in greenimg = cv2.drawContours(img, [imgpts[:4]],-1,(0,255,0),-3)# draw pillars in blue colorfor i,j in zip(range(4),range(4,8)):img = cv2.line(img, tuple(imgpts[i]), tuple(imgpts[j]),(255),3)# draw top layer in red colorimg = cv2.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] ])

结果如下:

        如果你对计算机图形学感兴趣的话,为了增加图像的真实性,你可以使用OpenGL 来渲染更复杂的图形 。

 

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

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

相关文章

MySQL语句 | 使用WITH子句和临时表达式进行数据分析和筛选

MySQL支持使用WITH创建临时表达式,通常称为"Common Table Expressions"(CTE)。CTE 通常用于较复杂的查询,为复杂查询提供了一种更清晰、模块化的方式,以提高复杂查询的可读性和易维护性。 举个通用的例子 …

MySQL-索引的介绍和使用

MySQL 支持哪些类型的索引? 主键索引(Primary Key Index) 唯一索引(Unique Index) 普通索引(Normal Index) 全文索引(Full-text Index) 组合索引(Composite …

apache seatunnel web 安装部署

下载文件 apache-seatunnel-2.3.3-bin.tar.gz apache-seatunnel-web-1.0.0-bin.tar.gz download_datasource.sh 准备工作 解压文件tar -zxvf apache-seatunnel-2.3.3-bin.tar.gz tar -zxvf apache-seatunnel-web-1.0

《动手学深度学习》学习笔记 第10章 注意力机制

文章目录 本系列为《动手学深度学习》学习笔记10.1 注意力提示10.1.1 生物学中的注意力提示10.1.2 查询、键和值10.1.3 注意力的可视化 10.2 注意力汇聚:Nadaraya-Watson 核回归10.2.1 生成数据集10.2.2 平均汇聚10.2.3 非参数注意力汇聚10.2.4 带参数注意力汇聚10.…

Python用selenium实现自动登录和下单的项目实战

前言 学python对selenium应该不陌生吧 Selenium 是最广泛使用的开源 Web UI(用户界面)自动化测试套件之一。Selenium 支持的语言包括C#,Java,Perl,PHP,Python 和 Ruby。目前,Selenium Web 驱动…

openssl3.2 - 官方demo学习 - test - certs

文章目录 openssl3.2 - 官方demo学习 - test - certs概述笔记.sh的执行语句打印的方法要修改的实际函数备注END openssl3.2 - 官方demo学习 - test - certs 概述 官方demos目录有证书操作的例子 已经做了笔记 openssl3.2 - 官方demo学习 - certs 但是这个demos/certs目录的脚…

安卓屏幕自动息屏时亮度突然变亮

自然息屏流程 USER_ACTIVITY_SCREEN_BRIGHT(亮屏) → USER_ACTIVITY_SCREEN_DIM(DIM) → USER_ACTIVITY_SCREEN_DREAM(灭屏)变化,最终进入ASLEEP后。在息屏时会执行一个变暗的动画 frameworks\…

鸿蒙应用开发-请求语音合成服务获取音频文件

功能介绍: 请求语音合成服务,通过上传语音合成文本,返回音频数据,并保存到本地。这里要说明一下,由于HttpResponse接口给问题,服务的响应类型必须是application/octet-stream,才能正确获取音频…

C# 数据类型与类型转换:包含教程与示例

C# 数据类型 C# 中的变量必须是指定的数据类型: int myNum 5; // 整数(整数) double myDoubleNum 5.99D; // 浮点数 char myLetter D; // 字符 bool myBool true; // 布尔 string myText "Hello…

【知识---如何进行图像数据的归一化呢(normalize)】

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言范围归一化均值和标准差归一化&引申总结 前言 在做基于图像的目标检测遇到了图像的归一化操作,为此展开了一定的探讨: 图像归一化…

虚拟机扩容教程

一、打开虚拟机主界面 二、右键鼠标进入设置模式 三、选择扩展 等待扩展结束 4、打开虚拟机,搜索工具GParted 5、接下来根据提示操作即可(已经扩容,不方便再次扩容演示,方法可行)

vue学习,使用provide/inject通信

提示&#xff1a;组件的provide&#xff0c;可以被其内所有层级的组件&#xff0c;通过inject引用 文章目录 前言一、通信组件二、效果三、参考文档总结 前言 需求&#xff1a;使用provide/inject通信 一、通信组件 1、AA.vue <template><div class"test"…

vue2 省市区联动组件封装

在element ui中有级联选择器el-cascader,其实已经够用了,但是在实际需求中,发现el-cascader如果有三级,数据数组必须得三个才能完全展示,所以不符合实际需求,还是自定义封装吧 需求:省市区联动数组,有多少个显示多少个 这里使用element ui得el-select组件,思路是使用…

反射计数 - 华为OD统一考试

OD统一考试 分值&#xff1a; 200分 题解&#xff1a; Java / Python / C 题目描述 给定一个包含 0 和 1 的二维矩阵, 给定一个初始位置和速度。 一个物体从给定的初始位置触发, 在给定的速度下进行移动, 遇到矩阵的边缘则发生镜面反射无论物体经过 0 还是 1&#xff0c;都不…

css 边框渐变

需求&#xff1a; 普通的div 边框不好看&#xff0c;做一个渐变色 进程&#xff1a; 最简单的当然是做一个内部是白色的边框是渐变色的图&#xff0c;然后使用 background: url("back.jpg")&#xff0c;这样看起来就像是做了一个渐变的边框如果做不了图&#xff0…

美摄视频SDK的HDR格式编辑方案

在当今的视觉媒体时代&#xff0c;高动态范围&#xff08;HDR&#xff09;技术已成为高质量视频内容的标配。为了满足企业对高效、高质量视频处理的需求&#xff0c;美摄科技推出了业界领先的视频SDK&#xff0c;全面支持多种HDR标准的图像视频进行处理。 一、核心优势 HDR全…

Android 13.0 Recent列表不显示某个app

1.概述 在13.0 的系统产品rom定制化开发中,在点击导航栏最近任务列表时,如果做到不显示某个app 呢 一种做法是在app中直接处理 一种做法是在framework中处理 接下来看这两种处理方法 1, app中处理 为该应用AndroidManifest xml文件中主MainActivity设置属性 android:exclu…

重拾计网-第一弹

&#x1f389;欢迎您来到我的MySQL基础复习专栏 ☆* o(≧▽≦)o *☆哈喽~我是小小恶斯法克&#x1f379; ✨博客主页&#xff1a;小小恶斯法克的博客 &#x1f388;该系列文章专栏&#xff1a;重拾计算机网络 &#x1f379;文章作者技术和水平很有限&#xff0c;如果文中出现错…

vue+springboot的文件上传处理

目录 1.前端&#xff1a; 2.说明 1.示例&#xff1a; 使用前端框架中的上传组件&#xff0c;例如element plus及arco design&#xff0c;要使用自定义的上传属性或者change属性&#xff0c;获取上传的文件信息。 <template><a-drawer :width"600" :visi…

四款坚固耐用、小尺寸、1EDB9275F、1EDS5663H、1EDN9550B、1EDN7512G单通道栅极驱动器IC

1、1EDB9275F 采用DSO-8 150mil封装的单通道隔离栅极驱动器&#xff08;PG-DSO-8&#xff09; EiceDRIVER™ 1EDB 产品系列 单通道栅极驱动器IC具有3 kVrms的输入输出隔离电压额定值。 栅极驱动器系列具有6/-4 ns传输延迟精度&#xff0c;可针对具有高系统级效率的快速开关应…