将 std::vector<cv::P oint3f> 乘以 cv::Mat?
Multiply std::vector<cv::Point3f> by a cv::Mat?
如上所述,我有一个cv :: point3f的std ::向量。我有一个转换矩阵。我需要将向量乘以垫子的倒数。
我的垫子:( 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);
(断言错误(
正确的方法(如果有办法!(?
谢谢。
正如里克·M(Rick M.要执行仅使用一个矩阵乘法(即使用4x4组合的R-T矩阵(进行转换,您首先必须表示均匀坐标中的点,这基本上仅涉及将1作为您点的第四个元素固定。转换后,您将新点除以第四元素以保持其值为1。这是3D-3D变换的不错源,在幻灯片14上讨论了均匀的坐标。
由于OpenCV没有Point4F类,因此在创建点的垫子表格时必须添加此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);
基于DCSMITH的答案,我可以工作。我必须做出这个小的改变:
cv::Mat T(4, 4, cv::DataType<float>::type);
R.copyTo(T(cv::Rect(0, 0, 3, 3)));
tvec.copyTo(T(cv::Rect(3, 0, 1, 3)));
使整个功能看起来像:
std::vector<cv::Point3f> p3d;
cv::Mat R(3,3, cv::DataType<float>::type);
cv::Rodrigues(rvec, R); // R is 3x3
cv::Mat T(4, 4, cv::DataType<float>::type);
R.copyTo(T(cv::Rect(0, 0, 3, 3)));
tvec.copyTo(T(cv::Rect(3, 0, 1, 3)));
float *p = T.ptr<float>(3);
p[0] = p[1] = p[2] = 0; p[3] = 1;
std::vector<cv::Point3f> dstPoint;
for (int i = 0; i < objectPoints.size(); i++) {
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);
p3d.push_back(dst);
}
谢谢您的帮助!
相关文章:
- 将"打开的CV图像"中的"颜色"转换为整数格式
- 概念中的cv限定符需要表达式参数列表
- EASTL矢量<向量<int>>连续的
- 将CHW格式的浮点向量转换为cv::Mat
- 错误的cv::face FacemarkLBF实例化
- 如何检查给定的参数是否为 cv::noArray()?
- 开放 CV 中的动态内存分配,用于视频处理
- 如何在 opencv 中使用 cv::VideoCapture::waitAny()
- 错误:未定义对cv::cudacodec::createVideoReader的引用
- OpenCV 3.4.1 error readNetFromTensorflow 无法在 cv::d nn::ReadProtoFromBinaryFile 中打开 .pb
- C++:从GPU内存(cudaMemcpy2D)获取BGR图像(cv::Mat)
- 选择基于另一个垫子的非零像素的cv::Mat的一部分?
- 将 cv::mat 转换为 QImage
- Inference pytorch C++ with alexnet and cv::imread image
- OpenCV 3.4.3 中对 'cv::String::d eallocate()' 错误的未定义引用
- cv::Normalise() 中的 L2_NORM 和 NORM_MINMAX 实现有什么区别?
- 将 cv::Mat 转换为 std::vector 的通用函数
- OpenCV undefined reference to 'cv::imread(cv::String const&, int)'
- 在 QML VideoOutput 中将 cv::mat 显示为 QVideoFrame
- 如何应用带有cv::cuda和C++的Canny Edge检测器?