给定 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 个已知点的相机像素到平面世界点 的相关文章

  • 使用 K 均值聚类 OpenCV 进行交通标志分割

    I used K Means Clustering to perform segmentation on this traffic sign as shown below 这些是我的代码 读取图像并模糊 img cv imread 000
  • 使用 Azure 机器学习检测图像中的符号

    4年前我发帖这个问题 https stackoverflow com q 6999920 411094不幸的是 得到的一些答案超出了我的技能水平 我刚刚参加了一次构建巡演会议 他们在会上谈论了机器学习 这让我想到了使用 ML 来解决我的问题
  • 跟踪白色背景中的白球(Python/OpenCV)

    我在 Python 3 中使用 OpenCV 来检测白场上的白 黑球 并给出它的精确 x y 半径 和颜色 我使用函数 cv2 Canny 和 cv2 findContours 来找到它 但问题是 cv2 Canny 并不总是检测到圆的完整
  • 有没有办法检测图像是否模糊? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我想知道是否有一种方法可以通过分析图像数据来确定图像是否模糊 估计图像清晰度的另一种非常简单的方法是使用拉普拉斯 或 LoG 滤波器并
  • 使用纽厄尔方法在 Python 中计算表面法线

    我正在尝试实现 Newell 方法来计算 Python 中的表面法向量 基于以下伪代码here https www opengl org wiki Calculating a Surface Normal Begin Function Ca
  • Pyinstaller“无法执行脚本 pyi_rth_pkgres”并且缺少软件包

    这是我第一次在这里发布问题 因为我的大部分问题已经被其他人回答了 我正在 python 中开发 GUI 应用程序 并尝试使用 pyinstaller 将其打包到单个文件夹和 exe 中 以便于移植 目前 我使用 Windows 10 和 a
  • 如何将 opencv mat 图像转换为 gdi 位图

    我想将 openCV Mat 文件转换为 GDI 位图图像 我找不到任何有关如何执行此操作的信息 我认为没有直接的方法可以做到这一点 但我希望它不涉及将其写入文件并读回 http opencv users 1802565 n2 nabble
  • 从 2 个摄像头捕获(OpenCV、Python)[重复]

    这个问题在这里已经有答案了 所以我试图从 openCV 中的两个摄像头 python 和 windows 7 进行捕获 我用一台相机拍摄的效果很好 你也会注意到我正在对图像做一些时髦的事情 但这并不重要 这是尝试使用两个的代码 import
  • 在 Android 中使用 OpenCV 查找图像匹配

    我正在尝试构建一个 Android 应用程序 该应用程序可以比较设备相机拍摄的照片 以在一组图像中找到匹配项 我已经在 Android Studio 上配置了 OpenCV 但仅此而已 有人可以通过链接到资源或建议教程来提供帮助吗 Open
  • OpenCV,捕获的视频比原始相机视频运行得更快!

    我正在使用 openCV 从相机捕获视频并将其存储到 avi 文件 问题是当我完成捕获并运行 avi 文件时 视频流看起来速度很快 这是代码 void main CvCapture capture cvCaptureFromCAM 0 in
  • 使用 OpenCV VideoWriter 将 RTSP 流存储为视频文件

    我正在使用 OpenCV 开发一个 Python 模块 该模块连接到 RTSP 流以对视频执行一些预处理 主要是降低 fps 和分辨率 然后将其存储在文件系统中 但是 即使在尝试了几种编解码器 寻找类似的开发之后 我总是得到一个空的视频 我
  • OpenCV 旋转图像而不裁剪澄清

    我想扩展这个主题 参考用户 Lars Schillingmann 给出的这个 SO 问题和接受的答案 在 C 中的 OpenCV 中旋转图像而不裁剪 https stackoverflow com questions 22041699 ro
  • opencv如何使用鼠标事件不规则地选择图像区域? c/c++ [关闭]

    Closed 这个问题需要细节或清晰度 help closed questions 目前不接受答案 最近在学习opencv 有没有办法使用鼠标事件选择图像区域 我已经尝试过三角形的了 如果我想选择特定区域而不是三角形怎么办 谢谢你 我对此进
  • 使用 OpenCV 和 Python 叠加两个图像而不丢失颜色强度

    如何叠加两个图像而不损失两个图像的颜色强度 我有图像1和图像2 2 我尝试使用 0 5 alpha 和 beta 但它给我的合并图像的颜色强度只有一半 dst cv2 addWeighted img1 0 5 img2 0 5 0 但是当我
  • Android API人脸检测与OpenCV/JavaCV人脸检测

    我在 Android 设备上使用了本地 Android 人脸检测 但它似乎很慢 而且我不太确定其可靠性 我还使用了 OpenCV 的人脸检测 但仅限于 PC 而不是 Android 设备 对于 Android 我猜我必须使用 JavaCV
  • 从凸点获取角点

    我编写了算法来提取图像中显示的点 它们形成凸形 我知道它们的顺序 如何从这些点中提取角点 顶部 3 个和底部 3 个 我正在使用opencv 如果你已经有了物体的凸包 并且该包包含角点 那么你需要做的就是简化包直到它只有 6 个点 有很多方
  • 类型错误:只有长度为 1 的数组可以转换为 Python 标量

    我是 openCV 的初学者 正在尝试分析数独求解器的现有代码 有这一段代码会引发错误 samples np float32 np loadtxt feature vector pixels data responses np float3
  • 如何识别与我的对象相关的轮廓并找到它们的几何质心

    问题陈述和背景信息 EDIT 约束 法兰上的红色会随着时间的推移而变化 所以我此时不会尝试使用颜色识别来识别我的对象 除非它足够强大 此外 外部照明也可能是一个因素 因为将来这将是在室外区域 我有 RGB 深度相机 有了它 我就能捕捉到这个
  • OpenCV:将垫子除以标量的最简单方法是什么

    我认为标题中已经包含了很多内容 显然我可以迭代和划分 但我认为有一种内置的方法 我看见cvConvertScale但这不适用于类型cv Mat 我知道标量乘法的缩放运算 cv Mat M float alpha cv Mat Result
  • 将图像分割成多个网格

    我使用下面的代码将图像分割成网格的 20 个相等的部分 import cv2 im cv2 imread apple jpg im cv2 resize im 1000 500 imgwidth im shape 0 imgheight i

随机推荐

  • 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 摄像机向下倾斜 面向地板 给定一个像素坐标 我希