给定 4 个已知点的相机像素到平面世界点

2024-02-12

我假设我的问题很简单,但由于我不久前在线性代数方面的经验,我仍然无法解决它。我读过几所大学发表的演示文稿,但我似乎无法遵循有些不标准化的符号。如果有人有更好的例子,将不胜感激......

Problem:摄像机向下倾斜,面向地板。给定一个像素坐标,我希望能够获得地板平面上相应的 3D 世界坐标。

Known:

  • 地板上有 4 个点,我知道像素(x,y)坐标和关联的世界(X,Y,Z = 0)坐标。
  • 相机的位置是固定的,我知道相机在X、Y、Z方向上的位移。

Unknown:

  • 相机绕 x、y、z 轴的旋转。主要是,相机围绕 X 轴旋转,Y 和 Z 旋转最小,但我认为应该考虑在内。
  • 畸变系数,但是线条中的图像弯曲最小,并且更愿意不引入棋盘校准程序。由此产生的一些错误并不影响交易。

我调查过的内容发现了一个惊人的例子here. https://stackoverflow.com/questions/12299870/computing-x-y-coordinate-3d-from-image-point?rq=1本质上这是完全相同的问题,但有一些后续问题:

SolvePnP 看起来是我的朋友,但我不太确定如何处理相机矩阵或 distCoefficients。有什么方法可以避免相机矩阵和距离系数校准步骤,我认为这是通过棋盘过程完成的(可能会牺牲一些精度)?或者有一些更简单的方法可以做到这一点?

非常感谢您的投入!


尝试这种方法:

从 4 个点对应计算单应性,为您提供在图像平面和地平面坐标之间转换的所有信息。

这种方法的局限性在于它假设一个统一参数化的图像平面(针孔相机),因此镜头畸变会给您带来错误,如我的示例中所示。如果您能够消除镜头畸变效应,我想您会很好地采用这种方法。 另外,如果你给出的对应关系稍有错误,你会得到一些错误,如果你提供更多的对应关系,你可以获得更稳定的值。

使用此输入图像

我已经从图像处理软件中读取了一个国际象棋场的 4 个角,这将对应于您知道图像中的 4 个点的事实。我选择了这些点(标记为绿色):

现在我做了两件事:首先将棋盘图案坐标转换为图像 (0,0) 、 (0,1) 等,这给出了映射质量的良好视觉印象。第二,我从图像转变为世界。读取图像位置 (87,291) 中最左边的角位置,该位置对应于棋盘坐标中的 (0,0)。如果我变换该像素位置,您会期望得到 (0,0) 的结果。

cv::Point2f transformPoint(cv::Point2f current, cv::Mat transformation)
{
    cv::Point2f transformedPoint;
    transformedPoint.x = current.x * transformation.at<double>(0,0) + current.y * transformation.at<double>(0,1) + transformation.at<double>(0,2);
    transformedPoint.y = current.x * transformation.at<double>(1,0) + current.y * transformation.at<double>(1,1) + transformation.at<double>(1,2);
    float z = current.x * transformation.at<double>(2,0) + current.y * transformation.at<double>(2,1) + transformation.at<double>(2,2);
    transformedPoint.x /= z;
    transformedPoint.y /= z;

    return transformedPoint;
}

int main()
{
    // image from http://d20uzhn5szfhj2.cloudfront.net/media/catalog/product/cache/1/image/9df78eab33525d08d6e5fb8d27136e95/5/2/52440-chess-board.jpg

    cv::Mat chessboard = cv::imread("../inputData/52440-chess-board.jpg");

    // known input:
    // image locations / read pixel values
    //  478,358
    //  570, 325
    //  615,382
    //  522,417

    std::vector<cv::Point2f> imageLocs;
    imageLocs.push_back(cv::Point2f(478,358));
    imageLocs.push_back(cv::Point2f(570, 325));
    imageLocs.push_back(cv::Point2f(615,382));
    imageLocs.push_back(cv::Point2f(522,417));

    for(unsigned int i=0; i<imageLocs.size(); ++i)
    {
        cv::circle(chessboard, imageLocs[i], 5, cv::Scalar(0,0,255));
    }
    cv::imwrite("../outputData/chessboard_4points.png", chessboard);

    // known input: this is one field of the chessboard. you could enter any (corresponding) real world coordinates of the ground plane here.
    // world location:
    // 3,3
    // 3,4
    // 4,4
    // 4,3

    std::vector<cv::Point2f> worldLocs;
    worldLocs.push_back(cv::Point2f(3,3));
    worldLocs.push_back(cv::Point2f(3,4));
    worldLocs.push_back(cv::Point2f(4,4));
    worldLocs.push_back(cv::Point2f(4,3));


    // for exactly 4 correspondences. for more you can use cv::findHomography
    // this is the transformation from image coordinates to world coordinates:
    cv::Mat image2World = cv::getPerspectiveTransform(imageLocs, worldLocs);
    // the inverse is the transformation from world to image.
    cv::Mat world2Image = image2World.inv();


    // create all known locations of the chessboard (0,0) (0,1) etc we will transform them and test how good the transformation is.
    std::vector<cv::Point2f> worldLocations;
    for(unsigned int i=0; i<9; ++i)
        for(unsigned int j=0; j<9; ++j)
        {
            worldLocations.push_back(cv::Point2f(i,j));
        }


    std::vector<cv::Point2f> imageLocations;

    for(unsigned int i=0; i<worldLocations.size(); ++i)
    {
        // transform the point
        cv::Point2f tpoint = transformPoint(worldLocations[i], world2Image);
        // draw the transformed point
        cv::circle(chessboard, tpoint, 5, cv::Scalar(255,255,0));
    }

    // now test the other way: image => world
    cv::Point2f imageOrigin = cv::Point2f(87,291);
    // draw it to show which origin i mean
    cv::circle(chessboard, imageOrigin, 10, cv::Scalar(255,255,255));
    // transform point and print result. expected result is "(0,0)"
    std::cout << transformPoint(imageOrigin, image2World) << std::endl;

    cv::imshow("chessboard", chessboard);
    cv::imwrite("../outputData/chessboard.png", chessboard);
    cv::waitKey(-1);


}

结果图像是:

正如您所看到的,数据中存在大量错误。正如我所说,这是因为作为对应关系给出的像素坐标略有错误(并且在一个小区域内!),并且由于镜头畸变阻止了地平面在图像上显示为真实平面。

将(87,291)转换为世界坐标的结果是:

[0.174595, 0.144853]

预期/完美的结果是[0,0]

希望这可以帮助。

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

给定 4 个已知点的相机像素到平面世界点 的相关文章

  • cv2.cv.BoxPoints(rect) 返回什么?

    rect cv2 minAreaRect largest contour rect rect 0 0 self scale down rect 0 1 self scale down rect 1 0 self scale down rec
  • 将四边形(四边形)拟合到斑点

    应用不同的过滤和分割技术后 我最终得到如下图像 我可以访问一些轮廓检测函数 这些函数返回该对象边缘上的点列表 或者返回一个拟合的多边形 尽管有很多边 远多于 4 个 我想要一种将四边形适合该形状的方法 因为我知道它是应该是四边形的鞋盒的正面
  • C++ OpenCV 2.3 中缺少 MoveWindow()

    我正在使用 OpenCV 2 3 的 C 版本 并且正在努力完成一项基本任务 我想做的是创建一个窗口并将其移动到屏幕上的特定位置 例如使用 cv namedWindow My Window 1 cv MoveWindow My Window
  • 如何解决 Python 'Pyzbar' 库的导入错误?

    我刚刚开始熟悉 Pyzbar 库 但是当使用decode方法我得到一个错误 这是代码 import cv2 import numpy as np import pyzbar code image cv2 imread C Users Ace
  • OpenCV findContours 破坏源图像

    我编写了一个在单通道空白图像中绘制圆形 直线和矩形的代码 之后 我只需找出图像中的轮廓 就可以正确获取所有轮廓 但找到轮廓后 我的源图像变得扭曲 为什么会出现这种情况 任何人都可以帮我解决这个问题 我的代码如下所示 using namesp
  • 查找彼此接近的对象边界

    我正在研究一个计算机视觉问题 其中问题的第一步是找到物体彼此靠近的位置 例如 在下图中 我感兴趣的是找到灰色标记的区域 Input Output 我目前的方法是首先反转图像 然后通过侵蚀进行形态梯度跟随 然后删除一些不感兴趣的轮廓 脚本如下
  • opencv中矩阵的超快中值(与matlab一样快)

    我正在 openCV 中编写一些代码 想要找到一个非常大的矩阵数组 单通道灰度 浮点数 的中值 我尝试了几种方法 例如对数组进行排序 使用 std sort 和选择中间条目 但与 matlab 中的中值函数相比 它非常慢 准确地说 在 ma
  • 相机标定(OpenCV 2.3)-如何使用畸变参数?

    我有一组带有一些附加标记的刚体图像 我在这些标记之一中定义了一个原点坐标系 我想获得该坐标系与在相机原点定义的坐标系之间的旋转和平移 我尝试了一段时间 POSIT 以下this http goo gl cUYYt 但从未获得可接受的结果 直
  • 如何在给定目标大小的情况下在 python 中调整图像大小,同时保留纵横比?

    首先 我觉得这是一个愚蠢的问题 对此感到抱歉 目前 我发现计算最佳缩放因子 目标像素数的最佳宽度和高度 同时保留纵横比 的最准确方法是迭代并选择最佳缩放因子 但是必须有更好的方法来做到这一点 一个例子 import cv2 numpy as
  • OpenCV的拼接模块可以拼接平行运动相机拍摄的图像吗?

    我想知道是否缝合 http docs opencv org modules stitching doc stitching html http docs opencv org modules stitching doc stitching
  • 在 QtCreator 中将 OpenCV 2.3 与 Qt 结合使用

    随着 OpenCV 2 3 版本终于发布 我想在我的系统上编译并安装这个最新版本 由于我经常使用 Qt 和 QtCreator 我当然希望能够在我的 Qt 项目中使用它 我已经尝试了几种方法几个小时 但总是出现错误 第一次尝试 使用WITH
  • 曲线/路径骨架二值图像处理

    我正在尝试开发一个可以处理图像骨架的路径 曲线的代码 我想要一个来自两点之间骨架的点向量 该代码在添加一些点后结束 我没有找到解决方案 include opencv2 highgui highgui hpp include opencv2
  • 来自连接到远程机器的相机的 Opencv 流

    我正在用 python 开发一个 wx 应用程序 用于流式传输和显示来自两个不同网络摄像头的视频 这工作正常 但现在我需要在不同的场景中执行此操作 其中两个摄像头连接在通过网络连接的 Windows 上运行的单独计算机中 我的应用程序将在机
  • 无法在 Windows 7 机器中使用 OpenCV 2.4.3、Python 2.7 打开“.mp4”视频文件

    我目前正在进行一个涉及读取 mp4 视频文件的项目 我遇到的问题是它在Windows 7机器上使用Python 2 7 32位 OpenCV 2 4 3 cv2 pyd 代码片段如下 try video cv2 VideoCapture v
  • opencv 2.3.* 读取不工作

    我无法让 imread 工作 与这个人有同样的问题 OpenCV imwrite 2 2 在 Windows 7 上导致异常 并显示消息 OpenCV 错误 未指定错误 无法找到指定扩展名的编写器 https stackoverflow c
  • OpenCV C++ 如何知道每行的轮廓数进行排序?

    我有一个二值图像 https i stack imgur com NRLVv jpg在这张图片中 我可以使用重载的函数轻松地对从上到下 从左到右找到的轮廓进行排序std sort 我首先通过以下方式从上到下排序 sort contours
  • 仅获取图像中的外部轮廓

    我有这段代码 可以在图像中绘制轮廓 但我只需要外部轮廓 import cv2 import numpy as np camino C Users Usuario Documents Deteccion de Objetos 123 jpg
  • 创建 OpenCV 的 mouseCallback 函数的基于类的实现时遇到问题

    正如标题所示 我在基于类的 C 结构中实现 OpenCV 的 mouseCallback 函数时遇到了一些麻烦 请允许我解释一下 我定义了一个名为 BriskMatching 的类 在其中创建了一个名为 mouseCallback 的成员函
  • OpenCV IP 相机应用程序崩溃 [h264 @ 0xxxxx] 访问单元中缺少图片

    我在 cpp 中有一个 opencv 应用程序 它使用 opencv 的简单结构捕获视频流并将其保存到视频文件中 它与我的网络摄像头完美配合 但是 当我运行它从 IP 摄像机捕获流时 它可能会在大约十秒后崩溃 我的编译命令是 g O3 IP
  • 使用 OpenCV 和/或 Numpy 对两个图像进行 Alpha 混合 [重复]

    这个问题在这里已经有答案了 我想将一个填充纯色的半透明矩形添加到已加载的半透明 PNG 中 这是我正在使用的输入图像示例 该图像加载了标准cv2 IMREAD UNCHANGED标志 以便完美保留 alpha 通道 该输入图像存储在imag

随机推荐

  • ActiveAdmin:如何保持用户密码不变?

    我在 Rails 应用程序中使用 ActiveAdmin 作为管理后端 基本上 我有一个admin user and a user模型 当我从管理员帐户创建新用户时 我指定了电子邮件和密码 这是可以的 假设我想修改用户的电子邮件而不是密码
  • R:绘图未完全加载

    我正在使用 R 编程语言 我试图在这里遵循本教程 https plotly com r parallel coordinates plot https plotly com r parallel coordinates plot 我正在尝试
  • Ant + Vista 64:“无法找到tools.jar”(jre/jdk 冲突?)

    我正在尝试在 vista 64 环境中使用 ant 来构建一些 docbook xml 文件 但是 我无法解决此错误消息 有人有建议吗 C Users 罗伯特管理员 gt ant 无法找到tools jar 预计在 C Program Fi
  • 在 WPF 中自定义上下文菜单

    我这里有一个项目 需要在 WPF 应用程序中自定义上下文菜单 其中一个按钮将放置在所有菜单项的底部 但是 如果我通过 XAML 添加按钮 它将显示为上下文菜单中集合中的另一个项目 并且鼠标悬停突出显示将对其进行操作 我希望将上下文菜单调整为
  • Foreach 语句无法对“object”类型的变量进行操作,因为“object”不包含“GetEnumerator”的公共定义

    我试图弄清楚如何通过 API 访问对象中的值 但运气不佳 有一些文档 但不多 我可以访问一些信息 但我要查找的信息存在于该软件正在使用的数据库的关键字字段中 我可以打印出对象类型 但不能打印出实际对象中的值 这是我的代码 public cl
  • 如何向 JTextArea 添加拼写检查?

    我有一个小型 Java 应用程序 它有一个 JTextArea 用户可以在其中输入文本 我想向该组件添加拼写检查功能 类似于 Microsoft Word 的方式 即拼写错误的单词带有下划线 当用户右键单击带下划线的单词时 会显示带有更正的
  • 如何在 zip 文件中找到“中央目录”的开头?

    维基百科对 ZIP 文件格式有很好的描述 http en wikipedia org wiki ZIP file format 但 中央目录 结构让我感到困惑 具体来说是这样的 这种顺序允许一次创建 ZIP 文件 但通常通过首先在最后读取中
  • 如何在 Flutter 中发送或接收 xml 文件?

    我可以使用 Flutter 发送和接收 JSON 字符串数据 但我找不到任何如何使用 Flutter 发送和接收 xml 文件的信息 我正在寻找很好的文档和基本的实践示例 有什么帮助吗 感谢 G nterZ chbauer 我设法在 Flu
  • 从 QT5 中的 QPixmap 获取 HBITMAP (Windows)

    现在 QPixmap toWinHBITMAP 已被弃用 我找不到从 QPixmap 或 QImage 获取 HBITMAP 的方法 谷歌搜索 我发现有一个名为 qt pixmapToWinHBITMAP 的函数 它似乎可以满足我的需要 但
  • 是否无法检查案例陈述条件中的列表项目?

    我正在尝试检查 Oracle 10g 中 case 语句的条件部分中的项目列表是否包含特定数字 我明白了ORA 00936 missing expression虽然错误 我正在尝试做类似以下的事情 Select case some colu
  • Git包文件入口格式

    My understanding of the Git pack file format is something like 其中表是32位宽 前三个32位字是包文件头 最后一行 32 位是条目的前 4 个字节 据我了解 条目的大小由带有
  • 在堆表上,非聚集索引使用什么作为指向行的指针?

    选择您的 SQL Server 版本 如果版本之间发生了更改 请注明 如果您知道 建一个表 在 1 列或多列上添加非聚集索引 如果我可以转储叶块 我会找到什么作为指向表中包含数据的行的指针 它使用行 ID 它基本上是数据库中行的物理地址 位
  • 在 pytorch 中绘制训练和验证损失图

    我正在使用 pytorch 来训练我的 CNN 网络 我想绘制训练和验证损失曲线以可视化模型性能 如何绘制两条曲线 我有下面的代码 create a function this my favorite choice def RMSELoss
  • PHP 中最快的 XML 解析器是什么?

    对于某个项目 我需要某种方法来解析 XML 并从中获取数据 所以我想知道哪一个内置解析器是最快的 另外 如果解析器能够接受 XML 字符串作为输入 那就太好了 我有自己的线程安全处理文件的实现 我不希望一些讨厌的非线程安全库让我的努力变得毫
  • Keras 未在整个数据集上进行训练

    因此 我一直在关注 Google 的官方张量流指南 并尝试使用 Keras 构建一个简单的神经网络 但在训练模型时 它并没有使用整个数据集 包含 60000 个条目 而是仅使用 1875 个条目进行训练 有什么可能的解决办法吗 import
  • Django 找不到我的模板

    我在 Windows XP SP3 上运行 Python 2 6 1 和 Django 1 2 1 我正在使用 JetBrains PyCharm 1 0 创建和部署我的 Django 应用程序 我对 Python 相对缺乏经验 并且我开始
  • 非 JSF 组件的条件呈现(普通 HTML 和模板文本)

    我正在尝试有条件地渲染 tr 因此我不能使用 tr
  • 如何获得linq中最高价和最低价商品的数量总和

    我试图编写的实际查询比标题所示的要稍微棘手一些 我有一个这样的订单列表 List
  • 如何删除重复项并保留 pandas 上的第一个值?

    我想删除重复项并保留第一个值 想要删除的重复项是 A df 这是我的数据 A B C D E qw 1 3 1 1 er 2 4 2 6 ew 4 8 44 4 df 34 34 34 34 df 2 5 2 2 df 3 3 7 3 df
  • 给定 4 个已知点的相机像素到平面世界点

    我假设我的问题很简单 但由于我不久前在线性代数方面的经验 我仍然无法解决它 我读过几所大学发表的演示文稿 但我似乎无法遵循有些不标准化的符号 如果有人有更好的例子 将不胜感激 Problem 摄像机向下倾斜 面向地板 给定一个像素坐标 我希