You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调用cv::eigen2cv后cv::getPerspectiveTransform抛错的解决方案

问题根因

你的排查结论完全正确:cv::eigen2cv 不会复用输出参数预先分配的内存与类型设置。由于你的入参是Eigen::MatrixXd(双精度浮点型矩阵),转换后输出的OpenCV Mat会自动匹配为CV_64FC1(双精度浮点)类型,直接覆盖你之前初始化quad、warpedQuad时指定的CV_32FC1类型与尺寸。而cv::getPerspectiveTransform接口要求输入点集必须为CV_32F类型,因此触发类型断言报错。

报错断言的校验逻辑明确要求:输入的源、目标点集必须是2通道CV_32F类型、共4个点的向量,类型不匹配就会直接抛出异常。

标准解决方案

有两种合规实现,优先选择第一种避免不必要的类型转换开销:

  • 方案1(零额外开销,推荐):将函数入参的Eigen矩阵类型从双精度Eigen::MatrixXd改为单精度Eigen::MatrixXf,和OpenCV接口要求的CV_32F类型完全对齐,转换后可直接传入接口。
  • 方案2(兼容双精度入参场景):如果业务逻辑必须保留Eigen::MatrixXd作为入参,在cv::eigen2cv转换完成后,显式调用convertTo将Mat转换为CV_32FC1类型再传入计算接口。

修正后代码示例

方案1(推荐)

cv::Mat getPerspectiveTransform(Eigen::MatrixXf quadrangle, Eigen::MatrixXf warpedQuadrangle) {
    cv::Mat transMat;
    cv::Mat quad, warpedQuad;
    // 无需提前指定输出Mat的类型、尺寸,eigen2cv会自动匹配Eigen单精度类型输出CV_32FC1格式
    cv::eigen2cv(quadrangle, quad);
    cv::eigen2cv(warpedQuadrangle, warpedQuad);
    transMat = cv::getPerspectiveTransform(quad, warpedQuad);
    return transMat;
}

方案2(兼容双精度入参)

cv::Mat getPerspectiveTransform(Eigen::MatrixXd quadrangle, Eigen::MatrixXd warpedQuadrangle) {
    cv::Mat transMat;
    cv::Mat quad, warpedQuad;
    cv::eigen2cv(quadrangle, quad);
    cv::eigen2cv(warpedQuadrangle, warpedQuad);
    // 显式转换为接口要求的CV_32F类型
    quad.convertTo(quad, CV_32FC1);
    warpedQuad.convertTo(warpedQuad, CV_32FC1);
    transMat = cv::getPerspectiveTransform(quad, warpedQuad);
    return transMat;
}

注意事项

不要为cv::eigen2cv的输出参数提前预分配指定类型的内存,该函数执行时会重新分配输出Mat的内存,覆盖原有对象的所有属性,提前预分配的操作没有任何实际作用。


内容的提问来源于stack exchange,提问作者Ayushman Kumar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 14:57:20