gpt4 book ai didi

c++ - 将 std::vector 乘以 cv::Mat?

转载 作者:太空宇宙 更新时间:2023-11-03 22:09:36 29 4
gpt4 key购买 nike

如上所述,我有一个 cv::Point3f 的 std::vector。我有一个变换矩阵。我需要将 vector 乘以 Mat 的倒数。

我的垫子:(T 是生成的转换)

cv::Mat R(3,3,rvec.type());
cv::Rodrigues(rvec, R); // R is 3x3
cv::Mat T(4, 4, R.type()); // T is 4x4
T(cv::Range(0, 3), cv::Range(0, 3)) = R * 1; // copies R into T
T(cv::Range(0, 3), cv::Range(3, 4)) = tvec * 1; // copies tvec into T
float *p = T.ptr<float>(3);
p[0] = p[1] = p[2] = 0; p[3] = 1;

我的载体:

std::vector<cv::Point3f> objectPoints;

我试过:

cv::Mat V = T.inv() * cv::Mat(objectPoints, false) 
V.copyTo(cv::Mat(objectPoints, false));

(断言失败,类型错误)

for (int i = 0; i < objectPoints.size(); i++)
{
cv::Mat dst = cv::Mat(objectPoints[i], false);
dst = -T*dst; //USE MATRIX ALGEBRA
// cv::Point3f tmp3 = cv::Point3f(dst(0, 0), dst(1, 0), dst(2, 0));

}

(断言失败)

    std::vector<cv::Point3f> p3d;
perspectiveTransform(objectPoints, p3d, -T);

(运行,但值非常不正确)

cv::transform(objectPoints, p3d, -T);

(断言错误)

执行此操作的正确方法是什么(如果有的话!)?

谢谢。

最佳答案

正如 Rick M. 指出的,您正在尝试将 4x4 矩阵与长度为 3 的点相乘。要仅使用一个矩阵乘法(即使用 4x4 组合 R-T 矩阵)执行转换,您首先必须在齐次坐标中表示该点,这实际上只涉及将 1 作为您点的第 4 个元素;转换后,将新点除以第 4 个元素以保持其值为 1。Here's一个很好的 3D-3D 转换来源,在幻灯片 14 上讨论了齐次坐标。

由于 OpenCV 没有 Point4f 类,因此在创建点的 Mat 形式时必须添加此 1。这未经测试但可能有效:

std::vector<cv::Point3f> dstPoint;
for (int i = 0; i < objectPoints.size(); i++) {
// Convert Point3f to 4x1 Mat (in homogeneous coordinates, with 1 as 4th element)
cv::Point3f pt = objectPoints[i];
cv::Mat ptMat = (cv::Mat_<float>(4,1) << pt.x, pt.y, pt.z, 1);

// Perform matrix multiplication and store as Mat_ for easy element access
cv::Mat_<float> dstMat(T.inv() * ptMat);

// Divide first three resulting elements by the 4th (homogenizing
// the point) and store as Point3f
float scale = dstMat(0,3);
cv::Point3f dst(dstMat(0,0)/scale, dstMat(0,1)/scale, dstMat(0,2)/scale);
dstPoints.push_back(dst)
}

会测试,但我在工作并且这台计算机上没有 OpenCV。

更新:

复制到 T 时,试试这个:

cv::Mat T(4, 4, cv::DataType<float>::type);
cv::Mat rot = T(cv::Range(0, 3), cv::Range(0, 3));
cv::Mat trans = T(cv::Range(0, 3), cv::Range(3, 4));
R.copyTo(rot);
tvec.copyTo(trans);

关于c++ - 将 std::vector<cv::Point3f> 乘以 cv::Mat?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44804820/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com