在python opengl中使用图像中的2d点获取空间中的3d点

2024-03-13

我正在尝试模拟房间中的深度相机,我的相机能够在世界中移动和旋转,并且房间被模拟为围绕 (0,0,0) 的 3d 立方体 单击按钮时,我想对图像中的 N 个随机点进行采样,并获取这些点与相机的距离(“现实世界”中的距离)。到目前为止,我已经成功创建了移动相机和立方体的场景 (Example https://i.stack.imgur.com/01SGm.png)

我尝试 gluUnProject 来获取 3d 点

model_view = np.array(glGetDoublev(GL_MODELVIEW_MATRIX))
proj = np.array(glGetDoublev(GL_PROJECTION_MATRIX))
view = np.array(glGetDoublev(GL_VIEWPORT))

3d_point = gluUnProject(x,y, 0.0)

其中 x,y 是图像中像素的坐标,但是当我检查像素时我知道它们的位置(立方角),我得到的感觉像是随机结果。

我对 openGL 很陌生,所以我可能会遗漏一些东西,从数学角度来说,我想做的就是在像素坐标上应用投影和视图矩阵的逆,但这不起作用。

我在下面附上了房间模拟的代码。

提前致谢。

import pygame
from pygame.locals import *
import numpy as np
import random
from OpenGL.GL import *
from OpenGL.GLU import *
display = (800, 600)
import math

def get_cube_information():

    vertices = (
        (1, -1, -1),
        (1, 1, -1),
        (-1, 1, -1),
        (-1, -1, -1),
        (1, -1, 1),
        (1, 1, 1, ),
        (-1, -1, 1),
        (-1, 1, 1),
        )

    edges = (
        (0,1),
        (0,3),
        (0,4),
        (2,1),
        (2,3),
        (2,7),
        (6,3),
        (6,4),
        (6,7),
        (5,1),
        (5,4),
        (5,7),
        )

    surfaces = (
        (0,1,2,3),
        (3,2,7,6),
        (6,7,5,4),
        (4,5,1,0),
        (1,5,7,2),
        (4,0,3,6),
        )

    colors = (
        (1.000, 0.920, 0.000),
        (0.000, 0.860, 0.000),
        (1.000, 0.480, 0.000),
        (1.000, 1.000, 1.000),
        (0.900, 0.000, 0.000),
        (0.000, 0.000, 0.950)
    )
    return vertices, edges, surfaces, colors


def Cube():
    glBegin(GL_QUADS)

    (vertices, edges, surfaces, colors) = get_cube_information()
    for i, surface in enumerate(surfaces):
        x = 0
        color = colors[i]
        for vertex in surface:
            x += 1
            glColor3fv(color)
            glVertex3fv(vertices[vertex])


    glEnd()

    glBegin(GL_LINES)
    for edge in edges:
        for vertex in edge:
            glVertex3fv(vertices[vertex])

    glEnd()


def main():
    pygame.init()
    tx = 0
    ty = 0
    tz = 0
    ry = 0
    rx = 0
    pygame.display.set_mode(display, DOUBLEBUF|OPENGL|RESIZABLE)

    glMatrixMode(GL_PROJECTION)
    gluPerspective(45, (display[0] / display[1]), 0.1, 50.0)

    view_mat = np.matrix(np.identity(4), copy=False, dtype='float32')

    glMatrixMode(GL_MODELVIEW)
    glLoadIdentity()
    glTranslatef(0, 0, 0)
    glGetFloatv(GL_MODELVIEW_MATRIX, view_mat)
    glLoadIdentity()

    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                quit()
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    pygame.quit()
                    quit()
                if event.key == pygame.K_a:
                    tx = 0.05
                elif event.key == pygame.K_d:
                    tx = -0.05
                elif event.key == pygame.K_w:
                    tz = 0.05
                elif event.key == pygame.K_s:
                    tz = -0.05
                elif event.key == pygame.K_RIGHT:
                    ry = 1.0
                elif event.key == pygame.K_LEFT:
                    ry = -1.0
                elif event.key == pygame.K_UP:
                    rx = -1.0
                elif event.key == pygame.K_DOWN:
                    rx = 1.0
                elif event.key == pygame.K_SPACE:
                    continue
            elif event.type == pygame.KEYUP:
                if event.key == pygame.K_a and tx > 0:
                    tx = 0
                elif event.key == pygame.K_d and tx < 0:
                    tx = 0
                elif event.key == pygame.K_w and tz > 0:
                    tz = 0
                elif event.key == pygame.K_s and tz < 0:
                    tz = 0
                elif event.key == pygame.K_RIGHT and ry > 0:
                    ry = 0.0
                elif event.key == pygame.K_LEFT and ry < 0:
                    ry = 0.0
                elif event.key == pygame.K_DOWN and rx > 0:
                    rx = 0.0
                elif event.key == pygame.K_UP and rx < 0:
                    rx = 0.0
            elif event.type == pygame.MOUSEBUTTONDOWN:
                #here I want to sample the points and return their (x,y) in the image and their distance from the camera.
                continue

        glPushMatrix()
        glLoadIdentity()
        glTranslatef(tx, ty, tz)
        glRotatef(ry, 0, 1, 0)
        glRotatef(rx, 1, 0, 0)

        glMultMatrixf(view_mat)
        glGetFloatv(GL_MODELVIEW_MATRIX, view_mat)
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
        Cube()
        glPopMatrix()
        pygame.display.flip()
        pygame.time.wait(10)
main()

要找到视口上某个点的世界位置,您必须知道该点的深度值。

x 和 y 屏幕位置以及深度已转换为 [-1, 1] 范围内的标准化设备坐标。为此,必须知道视口矩形:

ndc = [2.0* x/vp_width - 1.0, 1.0 - 2.0*y/vp_height, depth*2.0 - 1.0]; 

归一化的设备空间坐标必须通过逆投影矩阵转换到视图空间(最后必须执行透视划分)。

通过逆视图矩阵,可以将视图空间坐标变换到世界空间。

gluUnProject https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/gluUnProject.xml为您完成所有这一切,但您必须知道片段的深度。 片段的深度可以通过以下方式读取glReadPixels https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glReadPixels.xml:

# get mouse position
x, y = pygame.mouse.get_pos()

# get the fragment depth
depth = glReadPixels(x, y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT)

# get projection matrix, view matrix and the viewport rectangle
model_view = np.array(glGetDoublev(GL_MODELVIEW_MATRIX))
proj = np.array(glGetDoublev(GL_PROJECTION_MATRIX))
view = np.array(glGetIntegerv(GL_VIEWPORT))

# unproject the point
point = gluUnProject(x, y, depth, model_view, proj, view)
print( point )

请注意,您必须启用深度测试 https://www.khronos.org/opengl/wiki/Depth_Test否则深度缓冲区将不会被设置。这也带来了好处,前面的多边形覆盖了它们“后面”的多边形:

glEnable(GL_DEPTH_TEST)
Cube()

当然,当读取值时,必须正确设置投影矩阵和模型视图矩阵glGetDoublev(GL_PROJECTION_MATRIX)分别glGetDoublev(GL_MODELVIEW_MATRIX).

这意味着视图矩阵的读取应该在设置之后完成:

glPushMatrix()
glLoadIdentity()
glTranslatef(tx, ty, tz)
glRotatef(ry, 0, 1, 0)
glRotatef(rx, 1, 0, 0)

glMultMatrixf(view_mat)
glGetFloatv(GL_MODELVIEW_MATRIX, view_mat)

model_view = np.array(glGetDoublev(GL_MODELVIEW_MATRIX))

注意,如果对于第四个参数(model) of gluUnProject使用单位矩阵,则gluUnProject不计算世界坐标,但计算视图坐标。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在python opengl中使用图像中的2d点获取空间中的3d点 的相关文章

  • 3D 图形批处理

    很多网站 文章都说 批量 批 批 有人可以解释一下着色器中的 批处理 代表什么吗 即 是否 改变纹理 更改任意着色器变量 意味着某些东西不能 批处理 最简单的总结方法就是尝试尽可能少地调用 API 来绘制您需要绘制的内容 使用顶点数组或 V
  • 如何使用固定的 pandas 数据框进行动态 matplotlib 绘图?

    我有一个名为的数据框benchmark returns and strategy returns 两者具有相同的时间跨度 我想找到一种方法以漂亮的动画风格绘制数据点 以便它显示逐渐加载的所有点 我知道有一个matplotlib animat
  • 如何生成给定范围内的回文数列表?

    假设范围是 1 X 120 这是我尝试过的 gt gt gt def isPalindrome s check if a number is a Palindrome s str s return s s 1 gt gt gt def ge
  • Pycharm Python 控制台不打印输出

    我有一个从 Pycharm python 控制台调用的函数 但没有显示输出 In 2 def problem1 6 for i in range 1 101 2 print i end In 3 problem1 6 In 4 另一方面 像
  • Python 多处理示例不起作用

    我正在尝试学习如何使用multiprocessing但我无法让它发挥作用 这是代码文档 http docs python org 2 library multiprocessing html from multiprocessing imp
  • Spark的distinct()函数是否仅对每个分区中的不同元组进行洗牌

    据我了解 distinct 哈希分区 RDD 来识别唯一键 但它是否针对仅移动每个分区的不同元组进行了优化 想象一个具有以下分区的 RDD 1 2 2 1 4 2 2 1 3 3 5 4 5 5 5 在此 RDD 上的不同键上 所有重复键
  • keras加载模型错误尝试将包含17层的权重文件加载到0层的模型中

    我目前正在使用 keras 开发 vgg16 模型 我用我的一些图层微调 vgg 模型 拟合我的模型 训练 后 我保存我的模型model save name h5 可以毫无问题地保存 但是 当我尝试使用以下命令重新加载模型时load mod
  • 使用 Pycharm 在 Windows 下启动应用程序时出现 UnicodeDecodeError

    问题是当我尝试启动应用程序 app py 时 我收到以下错误 UnicodeDecodeError utf 8 编解码器无法解码位置 5 中的字节 0xb3 起始字节无效 整个文件app py coding utf 8 from flask
  • 如何连接重叠的圆圈?

    我想在视觉上连接两个重叠的圆圈 以便 becomes 我已经有部分圆的方法 但现在我需要知道每个圆的重叠角度有多大 但我不知道该怎么做 有人有主意吗 Phi ArcTan Sqrt 4 R 2 d 2 d HTH Edit 对于两个不同的半
  • NameError:名称“urllib”未定义”

    CODE import networkx as net from urllib request import urlopen def read lj friends g name fetch the friend list from Liv
  • Python:字符串不会转换为浮点数[重复]

    这个问题在这里已经有答案了 我几个小时前写了这个程序 while True print What would you like me to double line raw input gt if line done break else f
  • Geopandas 设置几何图形:MultiPolygon“等于 len 键和值”的 ValueError

    我有 2 个带有几何列的地理数据框 我将一些几何图形从 1 个复制到另一个 这对于多边形效果很好 但对于任何 有效 多多边形都会返回 ValueError 请指教如何解决这个问题 我不知道是否 如何 为什么应该更改 MultiPolygon
  • 循环中断打破tqdm

    下面的简单代码使用tqdm https github com tqdm tqdm在循环迭代时显示进度条 import tqdm for f in tqdm tqdm range 100000000 if f gt 100000000 4 b
  • Python - 在窗口最小化或隐藏时使用 pywinauto 控制窗口

    我正在尝试做的事情 我正在尝试使用 pywinauto 在 python 中创建一个脚本 以在后台自动安装 notepad 隐藏或最小化 notepad 只是一个示例 因为我将编辑它以与其他软件一起使用 Problem 问题是我想在安装程序
  • 如何将 PIL 图像转换为 NumPy 数组?

    如何转换 PILImage来回转换为 NumPy 数组 这样我就可以比 PIL 进行更快的像素级转换PixelAccess允许 我可以通过以下方式将其转换为 NumPy 数组 pic Image open foo jpg pix numpy
  • 在Python中重置生成器对象

    我有一个由多个yield 返回的生成器对象 准备调用该生成器是相当耗时的操作 这就是为什么我想多次重复使用生成器 y FunctionWithYield for x in y print x here must be something t
  • 检查所有值是否作为字典中的键存在

    我有一个值列表和一本字典 我想确保列表中的每个值都作为字典中的键存在 目前我正在使用两组来确定字典中是否存在任何值 unmapped set foo set bar keys 有没有更Pythonic的方法来测试这个 感觉有点像黑客 您的方
  • glpk.LPX 向后兼容性?

    较新版本的glpk没有LPXapi 旧包需要它 我如何使用旧包 例如COBRA http opencobra sourceforge net openCOBRA Welcome html 与较新版本的glpk 注意COBRA适用于 MATL
  • 用于运行可执行文件的python多线程进程

    我正在尝试将一个在 Windows 上运行可执行文件并管理文本输出文件的 python 脚本升级到使用多线程进程的版本 以便我可以利用多个核心 我有四个独立版本的可执行文件 每个线程都知道要访问它们 这部分工作正常 我遇到问题的地方是当它们
  • 在 Python 类中动态定义实例字段

    我是 Python 新手 主要从事 Java 编程 我目前正在思考Python中的类是如何实例化的 我明白那个 init 就像Java中的构造函数 然而 有时 python 类没有 init 方法 在这种情况下我假设有一个默认构造函数 就像

随机推荐

  • 安装新版本 XCode 15.0 后无法运行应用程序 XCode

    我已经安装了新版本的 Xcode 15 0 此后我无法运行我的 flutter 应用程序 它向我显示以下错误 Error Xcode DT TOOLCHAIN DIR cannot be used to evaluate LIBRARY S
  • 如何矢量化在较大矩阵的子集上运行函数的代码?

    假设我有以下 9 x 5 矩阵 myArray 54 7 8 1 81 7 55 0 22 5 29 6 92 9 79 4 62 2 17 0 74 4 77 5 64 4 58 7 22 7 18 8 48 6 37 8 20 7 43
  • C 中的释放字符串

    如果我写 char a malloc sizeof char 4 a abc char b abc 我是否需要释放该内存 还是由我的系统完成 在您的情况下 您将无法释放动态分配的内存 因为您正在丢失对它的引用 试试这个 include
  • 通过 Android 共享时 Google+ 应用程序显示错误的图片

    我已以编程方式将 Google 共享添加到我的应用程序中 我有一组照片 我将其包含在我的帖子中并使用以下代码共享 private void shareToGooglePlus Launch the Google share dialog w
  • Python-UDP客户端

    我目前正在阅读Pythonbook https www nostarch com blackhatpython并遇到了以下示例 import socket target host 127 0 0 1 target port 80 creat
  • LD_PRELOAD __libc_start_main 的 Makefile

    我想做的事情很简单 当我启动猫鼬服务器时 我想创建一个额外的线程来完成一些额外的工作 为了做到这一点 我想我需要LD PRELOAD the libc start main服务器的 This is spec hooks cpp typede
  • 与邮递员的 CORS

    这个问题已经被问过几次了 但我还是不明白 当我读到有关的答案时 没有 Access Control Allow Origin 标头 问题 它说应该在请求的服务器上设置一个设置以允许跨域 add header Access Control A
  • 适用于 Windows 的 Composer 安装 -

    所以我尝试在我的 Windows 操作系统上安装 Composer 并设置 Laravel 但是当我运行安装时 我不断收到相同的错误 首先 我选择了 php exe 因为它从目录中询问C wamp bin php php5 4 16 我单击
  • JIT 编译的代码驻留在哪里?

    所以我有这个方法 用Java编写 public void myMethod int y int x 5 y doSomething x 并假设我的应用程序多次调用此函数 当在Java虚拟机上运行该方法的编译代码时 JVM将首先解释该方法 然
  • 如何使用 IF EXIST 条件检查目录或文件是否存在?

    如何检查目录或文件是否存在IF EXIST健康 状况 Such as If exist C Windows OR C Windows2 rem Do something else rem Something else 我该怎么做 简单例子1
  • 应该在带花括号的 return 语句中调用哪个构造函数?

    考虑以下代码 struct NonMovable NonMovable default NonMovable const NonMovable default NonMovable NonMovable delete NonMovable
  • 调度程序 BeginInvoke 语法

    我一直在尝试遵循一些 WCF 数据服务示例并具有以下代码 private void OnSaveCompleted IAsyncResult result Dispatcher BeginInvoke gt context EndSaveC

  • 元素可以有结束标签吗?

    我的同事并不真正了解或理解 html 她的工作是向 CMS 输入信息 我注意到她一直关闭她 hr 像这样的标签 hr 我有谷歌 但我找不到任何地方说这是不允许的或可能会导致问题 我知道它应该是 hr 但值得我告诉她还是这是不必要但有效的标记
  • Apollo重新获取不重新渲染组件

    我正在使用 graphql 从网络服务获取数据 我的客户端代码是这样的 import React Component from react import Platform StyleSheet Text ActivityIndicator
  • React - 加载外部脚本的问题

    我正在从事我的第一个 React 项目 并且对 JS 有点陌生 我正在努力解决一个非常基本的问题 我想知道调试这个的最佳实践是什么 我确实创建了我的应用程序create react app我没有成功加载外部脚本 令人惊讶的是 到目前为止 我
  • Aiohttp、Asyncio:运行时错误:事件循环已关闭

    我有两个脚本 scraper py 和 db control py 在 scraper py 我有这样的东西 def scrape category field pages search use proxy proxy file loop
  • JavaScript YUI3 使用全局变量?

    我不知道如何从 YUI3 中更新全局变量 考虑以下代码 window myVariable data one var yuiWrap YUI use node function Y console log window myVariable
  • Spring - 如何正确使用@Autowired来防止controller / MockMvc为空?

    我正在尝试运行一些单元测试并遇到一个问题 我确信该问题源于对自动装配的误解 我有一个单元测试类 我正在尝试使用 Autowired在 MockMvc 和 REST 控制器上 两者最终都为 null 我看到一些消息来源试图解释为什么会发生这种
  • 局部变量和寄存器变量可以声明为 extern 吗?

    我一直想知道是否可以在本地声明 extern 和寄存器变量 如果可以的话 会受到什么限制 在某些情况下 局部变量可以声明为 extern 让我们来读一下C99 N1256标准草案 http www open std org JTC1 SC2
  • 在python opengl中使用图像中的2d点获取空间中的3d点

    我正在尝试模拟房间中的深度相机 我的相机能够在世界中移动和旋转 并且房间被模拟为围绕 0 0 0 的 3d 立方体 单击按钮时 我想对图像中的 N 个随机点进行采样 并获取这些点与相机的距离 现实世界 中的距离 到目前为止 我已经成功创建了