OpenCV投影矩阵分解重构:convertPointsFromHomogeneous断言失败求助
问题分析与解决方案
你遇到的断言失败问题,核心是用错了cv::convertPointsFromHomogeneous的使用场景——这个函数是用来处理点集的,而非单个的齐次平移向量。
为什么会触发断言?
cv::decomposeProjectionMatrix返回的Td是一个4x1的单通道Mat,形式为[s*t₁, s*t₂, s*t₃, s]^T(其中s是缩放因子)。而cv::convertPointsFromHomogeneous的设计目标是处理多个齐次点组成的集合:
- 它期望输入是
N×D或D×N的矩阵,每个行/列对应一个D维的齐次点(比如3D齐次点是4维)。 - 当你直接传入4x1的单通道Mat时,函数会把它解析为4个1维的点,这完全不符合齐次点的最低维度要求(至少2维),因此触发断言检查失败。
正确的处理方式
其实根本不需要用convertPointsFromHomogeneous,我们可以直接从Td中计算出3x1的非齐次平移向量:
- 取出
Td的前3个元素(对应缩放后的平移分量) - 除以第4个元素(缩放因子
s),得到真实的平移向量
代码示例:
cv::Mat T(3, 1, cv::DataType<float>::type); // 直接计算非齐次平移向量 T.at<float>(0, 0) = Td.at<float>(0, 0) / Td.at<float>(3, 0); T.at<float>(1, 0) = Td.at<float>(1, 0) / Td.at<float>(3, 0); T.at<float>(2, 0) = Td.at<float>(2, 0) / Td.at<float>(3, 0); // 调用重构函数 MatFunc->projectionFromKRt(Kd, Rd, T, newP1);
额外验证(非必要)
如果你非要用convertPointsFromHomogeneous(完全没必要,只是验证逻辑),需要把Td转换成1x4的行向量(代表1个4维齐次点),让函数能正确识别:
cv::Mat Td_row = Td.t(); // 转置成1x4的行向量 cv::Mat T; cv::convertPointsFromHomogeneous(Td_row, T); // 此时T是1x3的行向量,再转置成3x1即可 T = T.t();
但这种方式属于绕远路,直接计算的方式更高效清晰。
内容的提问来源于stack exchange,提问作者anti
相关产品推荐
相关产品推荐

