python图像坐标系_世界坐标系、相机坐标系和图像坐标系的转换(Python)
世界坐标系,相机坐标系和图像坐标系的转换(Python)
1.世界坐标->相机坐标
2.相机坐标系->图像坐标系
此时投影点p的单位还是mm,并不是pixel,需要进一步转换到像素坐标系。
3.图像坐标系与像素坐标系
像素坐标系和图像坐标系都在成像平面上,只是各自的原点和度量单位不一样。图像坐标系的原点为相机光轴与成像平面的交点,通常情况下是成像平面的中点或者叫principal point。图像坐标系的单位是mm,属于物理单位,而像素坐标系的单位是pixel,我们平常描述一个像素点都是几行几列。所以这二者之间的转换如下:其中dx和dy表示每一列和每一行分别代表多少mm,即1pixel=dx mm
那么通过上面四个坐标系的转换就可以得到一个点从世界坐标系如何转换到像素坐标系的。
python代码shi实现:
# -*- coding: utf-8 -*-
"""
# --------------------------------------------------------
# @Project: prpject
# @Author : panjq
# @E-mail : pan_jinquan@163.com
# @Date : 2020-02-04 16:03:01
# @url : https://www.jianshu.com/p/c5627ad019df
# --------------------------------------------------------
"""
import sys
import os
from tools import image_processing
sys.path.append(os.getcwd())
import numpy as np
from modules.utils_3d import vis
camera_intrinsic = {
# R,旋转矩阵
"R": [[-0.91536173, 0.40180837, 0.02574754],
[0.05154812, 0.18037357, -0.98224649],
[-0.39931903, -0.89778361, -0.18581953]],
# t,平移向量
"T": [1841.10702775, 4955.28462345, 1563.4453959],
# 焦距,f/dx, f/dy
"f": [1145.04940459, 1143.78109572],
# principal point,主点,主轴与像平面的交点
"c": [512.54150496, 515.45148698]
}
class Human36M(object):
@staticmethod
def convert_wc_to_cc(joint_world):
"""
世界坐标系 -> 相机坐标系: R * (pt - T)
:return:
"""
joint_world = np.asarray(joint_world)
R = np.asarray(camera_intrinsic["R"])
T = np.asarray(camera_intrinsic["T"])
joint_num = len(joint_world)
# 世界坐标系 -> 相机坐标系
# [R|t] world coords -> camera coords
joint_cam = np.zeros((joint_num, 3)) # joint camera
for i in range(joint_num): # joint i
joint_cam[i] = np.dot(R, joint_world[i] - T) # R * (pt - T)
return joint_cam
@staticmethod
def __cam2pixel(cam_coord, f, c):
"""
相机坐标系 -> 像素坐标系: (f / dx) * (X / Z) = f * (X / Z) / dx
cx,ppx=260.166; cy,ppy=205.197; fx=367.535; fy=367.535
将从3D(X,Y,Z)映射到2D像素坐标P(u,v)计算公式为:
u = X * fx / Z + cx
v = Y * fy / Z + cy
D(v,u) = Z / Alpha
=====================================================
camera_matrix = [[428.30114, 0., 316.41648],
[ 0., 427.00564, 218.34591],
[ 0., 0., 1.]])
fx = camera_intrinsic[0, 0]
fy = camera_intrinsic[1, 1]
cx = camera_intrinsic[0, 2]
cy = camera_intrinsic[1, 2]
=====================================================
:param cam_coord:
:param f: [fx,fy]
:param c: [cx,cy]
:return:
"""
# 等价于:(f / dx) * (X / Z) = f * (X / Z) / dx
# 三角变换, / dx, + center_x
u = cam_coord[..., 0] / cam_coord[..., 2] * f[0] + c[0]
v = cam_coord[..., 1] / cam_coord[..., 2] * f[1] + c[1]
d = cam_coord[..., 2]
return u, v, d
@staticmethod
def convert_cc_to_ic(joint_cam):
"""
相机坐标系 -> 像素坐标系
:param joint_cam:
:return:
"""
# 相机坐标系 -> 像素坐标系,并 get relative depth
# Subtract center depth
# 选择 Pelvis骨盆 所在位置作为相机中心,后面用之求relative depth
root_idx = 0
center_cam = joint_cam[root_idx] # (x,y,z) mm
joint_num = len(joint_cam)
f = camera_intrinsic["f"]
c = camera_intrinsic["c"]
# joint image,像素坐标系,Depth 为相对深度 mm
joint_img = np.zeros((joint_num, 3))
joint_img[:, 0], joint_img[:, 1], joint_img[:, 2] = Human36M.__cam2pixel(joint_cam, f, c) # x,y
joint_img[:, 2] = joint_img[:, 2] - center_cam[2] # z
return joint_img
if __name__ == "__main__":
joint_world = [[-91.679, 154.404, 907.261],
[-223.23566, 163.80551, 890.5342],
[-188.4703, 14.077106, 475.1688],
[-261.84055, 186.55286, 61.438915],
[39.877888, 145.00247, 923.98785],
[-11.675994, 160.89919, 484.39148],
[-51.550297, 220.14624, 35.834396],
[-132.34781, 215.73018, 1128.8396],
[-97.1674, 202.34435, 1383.1466],
[-112.97073, 127.96946, 1477.4457],
[-120.03289, 190.96477, 1573.4],
[25.895456, 192.35947, 1296.1571],
[107.10581, 116.050285, 1040.5062],
[129.8381, -48.024918, 850.94806],
[-230.36955, 203.17923, 1311.9639],
[-315.40536, 164.55284, 1049.1747],
[-350.77136, 43.442127, 831.3473],
[-102.237045, 197.76935, 1304.0605]]
joint_world = np.asarray(joint_world)
kps_lines = ((0, 7), (7, 8), (8, 9), (9, 10), (8, 11), (11, 12), (12, 13), (8, 14), (14, 15),
(15, 16), (0, 1), (1, 2), (2, 3), (0, 4), (4, 5), (5, 6))
# show in 世界坐标系
vis.vis_3d(joint_world, kps_lines, coordinate="WC", title="WC")
human36m = Human36M()
# show in 相机坐标系
joint_cam = human36m.convert_wc_to_cc(joint_world)
vis.vis_3d(joint_cam, kps_lines, coordinate="CC", title="CC")
joint_img = human36m.convert_cc_to_ic(joint_cam)
# show in 像素坐标系
kpt_2d = joint_img[:, 0:2]
image_path = "/media/dm/dm1/git/python-learning-notes/modules/utils_3d/s_01_act_02_subact_01_ca_02_000001.jpg"
image = image_processing.read_image(image_path)
image = image_processing.draw_key_point_in_image(image, key_points=[kpt_2d], pointline=kps_lines)
image_processing.cv_show_image("image", image)
python图像坐标系_世界坐标系、相机坐标系和图像坐标系的转换(Python)相关推荐
- 我国常用的投影坐标系_【干货】arcgis中坐标系问题详解
地理空间的数学基础是空间分析的基准,在GIS中,所有的空间数据都要划归到统一的空间参考下才可以进行进一步的空间分析.地球空间参考解决的是地球的空间定位和数学描述问题,投影解决的是将地球曲面信息映射到二 ...
- python鱼眼图像识别_图像变换之矫正---鱼眼图像的矫正简介
概论: ZD鱼眼图像变形校正算法,理论上相对比较简单,各种具体典型算法也 存在一定的不足.球面坐标定位展开算法是一种粗略的校正方法,最终的处理效 果不够理想.多项式坐标变换算法是一种典型的校正算法,针 ...
- python房价预测_您的选房系统已上线——利用python和R如何进行房价预测
本文约1500字,阅读需要5分钟.讲述了如何使用python进行房价信息获取,如何利用R构建回归模型以达到预测上海某个地区房价的目的. 关键词:买房 Python 选房 R 定价 本文讲述了借助Pyt ...
- python手把手入门_新手必看:手把手教你入门 Python
首先,Python是什么?据它的创始人Guido van Rossum而言, "Python是一种高级编程语言,它的核心设计思想是代码可读性和允许程序员用几行代码来表达观点的语法." ...
- python装逼_能够让你装逼的10个Python小技巧
列表推导式 你有一个list: bag = [1, 2, 3, 4, 5] 现在你想让所有元素翻倍,让它看起来是这个样子: [2, 4, 6, 8, 10] 大多初学者,根据之前语言的经验会大概这样来 ...
- python 儿童 游戏_少儿编程分享:手把手教你用Python编写战斗机游戏(完)
原标题:少儿编程分享:手把手教你用Python编写战斗机游戏(完) 加入图像 现在我们已经能够玩游戏了,但这个游戏丑确实有点丑 .接下来,我们要把单调的白色矩形换成好看的图片. 在前面的代码中,我们用 ...
- 420集的python教程视频_阿里达摩院推的420集的python教程高清版,据说懂中文就能入门...
阿里达摩院推的400集的python教程高清版,据说懂中文就能入门 小编的内心是强大的,网友虐我千百遍,我待网友如初恋,因为今天又给大家带来了干货,Python入门教程完整版,完整版啊!完整版! 为了 ...
- python简单编程语言_功能强大而又简单易学的编程语言Python
Python是一种面向对象.直译式计算机程序设计语言,也是一种功能强大的通用型语言(维基百科).自从上次写那个批量Blast小程序的时候接触了Python,发现这个玩意儿真是好用,后来还用它弄了个动态 ...
- 虚拟机python建站_搭建本地虚拟服务器linux(CentOS 7)的python虚拟环境(Hyper-V演示)...
新建虚拟机->安装CentOS7->新建虚拟交换机:内部网络->CentOS7设置->网络适配器:虚拟交换机:新建虚拟交换机->进入CentOS #cd /etc/sys ...
- python 字符串操作速度_强者一出,谁与争锋?与Python相比,C+的运行速度究竟有多快?|python|编程语言|字符串|示例|算法...
对于数据科学家而言,热爱Python的理由数不胜数.但你是否也曾问过这样的问题:Python和C或C++等更专业的低级编程语言究竟有何不同呢?我想这是很多数据科学家或者Python用户曾经问过或者将来 ...
最新文章
- 题目1460:Oil Deposit
- 以太网控制芯片DM9000在2440裸机上终于能正确接收数据了(源代码工程已经上传)...
- Java基础10:全面解读Java异常
- 轻芒王俊煜:我是如何设计信息流的?
- 翠香猕猴桃 和 薄皮核桃,快来下单
- HDU5322 - cdq分治FFT加速dp
- linux怎么编译sharedptr,如何使用智能指针(例如auto_ptr r shared_ptr)在Linux上使用C++生成链接列表数据结构?...
- 调度失败:执行器地址为空_三千字带你搞懂XXL-JOB任务调度平台
- net执行oracle的存储过程
- php设置路径别名,设置别名php = / bin / php56,但今天它已恢复为原始路径:/ bin / php...
- 深入理解Java的反射与动态代理
- 【外星眼halcon教程】机器视觉测量消费电子显示屏的颜色
- C语言正交表测试用例,用正交表设计测试用例
- windbg调试和断点学习总结2
- 深度对话:系统学习还是野路子?
- 黑马程序员中的简单网页制作
- python识别汉字笔画_Python识别图片中的文字
- 【算法-初级-数组】两数之和(JavaScript实现)
- Python 实现 淘宝秒杀 聚划算 自动提醒 源码
- 技术派-epoll和IOCP之比较
热门文章
- 为博聆网用户编写的userscript
- VIRTUALBOX无法加载USB移动设备的解决方法
- 6取余11c语言,中国剩余定理“大衍求一术”手算方法及四个习题
- 【历史上的今天】9 月 26 日:硅晶体管先驱出生;黑客盗取雅虎用户信息;“生物圈 2 号”实验室
- 深入理解kafka 电子版
- .Net5使用Sqlsugar操作加密Sqlite数据库
- luminex细胞因子检测
- 滑动切换下一个视频,点击暂停视频,再次点击播放视频,很多案列pc预览正常,真机调试就不能用了;此案例我手机是可以用的,废话不多说直接上源码
- 速读原著-TCP/IP(网络文件系统)
- 就想了解服务器为什么1M带宽网速却达不到1M