使用 OpenCVsolvePnP 在 OpenGL 中实现增强现实

2024-01-07

我正在尝试使用 Android 构建增强现实应用程序BoofCV http://boofcv.org/index.php?title=Main_Page(Java 的 OpenCV 替代品)和 OpenGL ES 2.0。我有一个标记,我可以使用 BoofCV 的solvePnP 函数获取图像点和“世界到凸轮”转换。我希望能够使用 OpenGL 在 3D 中绘制标记。这是我到目前为止所拥有的:

在相机的每一帧上,我调用solvePnP

Se3_F64 worldToCam = MathUtils.worldToCam(__qrWorldPoints, imagePoints);
mGLAssetSurfaceView.setWorldToCam(worldToCam);

这就是我定义的世界点

static float qrSideLength = 79.365f; // mm

private static final double[][] __qrWorldPoints = {
        {qrSideLength * -0.5, qrSideLength * 0.5, 0},
        {qrSideLength * -0.5, qrSideLength * -0.5, 0},
        {qrSideLength * 0.5, qrSideLength * -0.5, 0},
        {qrSideLength * 0.5, qrSideLength * 0.5, 0}
};

我给它提供一个原点位于中心、边长以毫米为单位的正方形。

我可以确认我从中返回的旋转向量和平移向量solvePnP都是合理的,所以不知道这里有没有问题。

我将solvePnP 的结果传递到渲染器中

public void setWorldToCam(Se3_F64 worldToCam) {

    DenseMatrix64F _R = worldToCam.R;
    Vector3D_F64 _T = worldToCam.T;

    // Concatenating the the rotation and translation vector into
    // a View matrix
    double[][] __view = {
        {_R.get(0, 0), _R.get(0, 1), _R.get(0, 2), _T.getX()},
        {_R.get(1, 0), _R.get(1, 1), _R.get(1, 2), _T.getY()},
        {_R.get(2, 0), _R.get(2, 1), _R.get(2, 2), _T.getZ()},
            {0, 0, 0, 1}
    };

    DenseMatrix64F _view = new DenseMatrix64F(__view);

    // Matrix to convert from BoofCV (OpenCV) coordinate system to OpenGL coordinate system
    double[][] __cv_to_gl = {
            {1, 0, 0, 0},
            {0, -1, 0, 0},
            {0, -1, 0, 0},
            {0, 0, 0, 1}
    };

    DenseMatrix64F _cv_to_gl = new DenseMatrix64F(__cv_to_gl);

    // Multiply the View Matrix by the BoofCV to OpenGL matrix to apply the coordinate transform
    DenseMatrix64F view = new SimpleMatrix(__view).mult(new SimpleMatrix(__cv_to_gl)).getMatrix();

    // BoofCV stores matrices in row major order, but OpenGL likes column major order
    // I transpose the view matrix and get a flattened list of 16,
    // Then I convert them to floating point
    double[] viewd = new SimpleMatrix(view).transpose().getMatrix().getData();

    for (int i = 0; i < mViewMatrix.length; i++) {
        mViewMatrix[i] = (float) viewd[i];
    }
}

我还使用从相机校准中获得的相机内在函数来输入 OpenGL 的投影矩阵

@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {

    // this projection matrix is applied to object coordinates
    // in the onDrawFrame() method

    double fx = MathUtils.fx;
    double fy = MathUtils.fy;
    float fovy = (float) (2 * Math.atan(0.5 * height / fy) * 180 / Math.PI);
    float aspect = (float) ((width * fy) / (height * fx));

    // be careful with this, it could explain why you don't see certain objects
    float near = 0.1f;
    float far = 100.0f;

    Matrix.perspectiveM(mProjectionMatrix, 0, fovy, aspect, near, far);

    GLES20.glViewport(0, 0, width, height);

}

我正在绘制的正方形是在此定义的正方形谷歌示例 https://android.googlesource.com/platform/development/+/master/samples/OpenGL/HelloOpenGLES20/src/com/example/android/opengl/Square.java.

@Override
public void onDrawFrame(GL10 gl) {

    // redraw background color
    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);

    // Set the camera position (View matrix)
    // Matrix.setLookAtM(mViewMatrix, 0, 0, 0, -3, 0f, 0f, 0f, 0f, 1.0f, 0.0f);


    // Combine the rotation matrix with the projection and camera view
    // Note that the mMVPMatrix factor *must be the first* in order
    // for matrix multiplication product to be correct

    // Calculate the projection and view transformation
    Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mViewMatrix, 0);

    // Draw shape
    mSquare.draw(mMVPMatrix);
}

我认为问题与谷歌示例代码中正方形的定义没有考虑现实世界的边长这一事实有关。我知道OpenGL坐标系有角点(-1, 1), (-1, -1), (-1, 1), (1, 1),它与我定义的毫米对象点不对应即使它们的顺序正确,也可以在 BoofCV 中使用。

static float squareCoords[] = {
        -0.5f,  0.5f, 0.0f,   // top left
        -0.5f, -0.5f, 0.0f,   // bottom left
        0.5f, -0.5f, 0.0f,   // bottom right
        0.5f,  0.5f, 0.0f }; // top right

None

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

使用 OpenCVsolvePnP 在 OpenGL 中实现增强现实 的相关文章

随机推荐

  • 在 Typescript 的模块内使用 get/set 创建变量

    我想在模块内创建一个具有获取 设置属性的变量 我看到了一些在类中创建 get set 属性的工作示例 如下所示 class MyClass private view get View return this view set View va
  • 使用 jQuery 1.5 以 jsonp 形式发送请求,将响应解释为文本

    简短的问题 有没有办法向服务器发出 jsonp 请求 捕获请求 但不将其解析为 javascript 我在 jQuery 1 5 中使用 dataType jsonp text 但它不起作用 我正在尝试使用 jsonp 通过 AJAX 访问
  • 根据登录用户在运行时更改数据库架构

    我已经阅读了许多有关动态数据源路由的问题和答案 并使用以下方法实现了一个解决方案AbstractRoutingDataSource和另一个 见下文 这很好 但需要所有数据源的硬编码属性 随着使用该应用程序的用户数量的增加 这不再是合适的路由
  • 如何使用 VS2015 Preview 运行 xUnit 单元测试?

    我通过扩展管理器添加了 xUnit net runner for Visual Studio v0 99 8 但是当我打开 测试资源管理器 窗口时 它似乎没有拾取任何单元测试 此外 Resharper 9 EAP 是唯一支持 VS2015
  • R中将线性方程转换为矩阵形式的函数?

    我想知道 R 是否存在任何包或其他预构建的解决方案 能够将线性方程组转换为矩阵形式 例如 通过高斯赛德尔算法 https en wikipedia org wiki Gauss E2 80 93Seidel method 类似于equati
  • 如何将@mixin从一个sass文件包含到不同文件夹中的另一个sass文件

    我将一个 SASS 文件中的 mixin 包含到另一个文件中 但 ionic 出现错误serve命令 Error Sass Error Invalid CSS after include expected identifier was th
  • 找到给定图像的 Dockerfile

    我正在一台 Linux 机器上工作 我大约 3 4 周前构建了一个 Docker 镜像 但我不记得 Dockerfile 位于哪里 查找 Dockerfile 的最佳方式是什么 是否有可能以某种方式在给定图像的情况下获取其位置 我尝试使用
  • 他们为什么使用; Java/C++ 中的结束语句

    他们应该不会用过吧 结束声明 他们可以使用 gt 来调用方法 这只是一个疏忽吗 还是这里面有更深层次的原因 Java 选择分号是为了拥有与 C 和 C 类似的语法 C 选择它的语法与 C 类似 我猜 C 选择分号是因为 B ALGOL 和
  • Ruby 语法:突破 'each.. do..' 块

    我正在开发一个红宝石 on Rails应用程序 我的问题更多是关于Ruby句法 我有一个带有类方法的模型类self check class Cars lt ActiveRecord Base def self check name self
  • 在 Rails 中发表评论时显示用户名

    我有一个名为 Pins 的应用程序 用于用户发布专辑评论 我创建了一个评论模型 供其他用户对评论发表评论 我很难让评论说 发布者 然后显示发布它们的用户的姓名 这是一些代码 引脚型号has many comments用户模型has many
  • django - 获取多个时期的最大值

    我刚开始使用 django 我的模型非常简单 由时间戳和值 温度 每分钟更新 组成 我想检索过去 7 天中每一天的最大值 我需要查询7次还是有 捷径 您可以利用annotate https docs djangoproject com en
  • 如何从字符串中删除单词列表

    我想做的 在 Clojure 中 例如 我有一个需要删除的单词向量 def forbidden words the many more 和一个字符串向量 def strings the movie list this is a string
  • DataGridView 开头没有选定的行

    在我的 WinForms 中我有DataGridView 我想一次选择整行所以我设置SelectionMode as FullRowSelect 现在我遇到了问题 因为一开始我的表单在第一行下划线 所选行集为空 第一行未选择但只是下划线 我
  • PHP:数组中连续元素的数量[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我一直在研究一个问题 找出数组中最大的一组连续数字 假设我们有一个数组 5 43 4 56 3 2 44 57 58 1 该数组中最大
  • 扩展 Ascii 在控制台中不起作用!

    例如 System out println 显示为 同样适用于 System out println u255a 为什么这不起作用 标准输出确实支持这些字符 所以我不明白 See 这个问题 https stackoverflow com q
  • django admin内联多对多自定义字段

    您好 我正在尝试在 django admin 中自定义我的内联 这是我的模型 class Row models Model name models CharField max length 255 class Table models Mo
  • 没有 staticfiles 应用程序的 Django 1.4 管理静态文件

    Django 1 4 发行说明 https docs djangoproject com en dev releases 1 4 state 如果您隐式依赖管理静态文件的路径 在 Django 源代码中 您需要更新该路径 这 文件从 dja
  • 带参数的 get_absolute_url

    My urls py urlpatterns url r profile profile profile name profile My model class Reg models Model name models CharField
  • Django 管理模型ArrayField 更改分隔符

    我的模型看起来像这样 from django contrib postgres fields import ArrayField class Trigger models Model solutions ArrayField models
  • 使用 OpenCVsolvePnP 在 OpenGL 中实现增强现实

    我正在尝试使用 Android 构建增强现实应用程序BoofCV http boofcv org index php title Main Page Java 的 OpenCV 替代品 和 OpenGL ES 2 0 我有一个标记 我可以使