显示 cv2 Mat 的差异

Posted

技术标签:

【中文标题】显示 cv2 Mat 的差异【英文标题】:Difference in displaying cv2 Mat 【发布时间】:2018-11-06 06:06:32 【问题描述】:

为什么将整个矩阵 Mat 和矩阵显示为单个元素时会有区别?

cv::Point2f sour[4] = Point(530,430), Point(670, 320), Point(870,430), Point(980, 320);
cv::Point2f dest[4] = Point(450,530), Point(450,420), Point(550,530), Point(550,420);

cv::Mat hom(3, 3, CV_32F);
hom=getPerspectiveTransform(sour,dest);

cout << "hom: " <<hom << endl;

打印

hom: [0.4489795918367541, 1.122448979591883, -33.67346938776892;
  5.034167527284694e-15, 2.040816326530671, -68.48979591837563;
  1.505685767039244e-17, 0.001224489795918431, 1]

同时

for (int i1=0; i1<3; i1++)
    for (int i2=0; i2<3; i2++)
            cout << hom.at<float>(i1,i2) << " ";
        
        cout <<endl;
    

打印:

-1.32615e+23 1.72449 1.70011e-29 
0 0.0301113 -2.30304e-37 
0 0.0147314 -3.2706e+24 

【问题讨论】:

你在给hom.type() == cv::DataType&lt;float&gt;::type 分配了单应性之后检查了它。也许数据类型默默地更改为双精度? 如果是这种情况,那么解决方案是将hom.at&lt;float&gt; 替换为hom.at&lt;double&gt;。如果您想确保有一个正确类型的矩阵,您可以将hom 的声明替换为cv::Matx&lt;float, 3, 3&gt; hom; 【参考方案1】:

我看到的可能性是矩阵类型在分配后从float 更改为double (hom=getPerspectiveTransform(sour,dest);)。如果是这样,那么CV_Assert(hom.type() == cv::DataType&lt;float&gt;::type); 会抛出异常。

要解决这个问题,您需要通过正确的类型引用矩阵元素,可能是double。因此,当您打印矩阵时,请将hom.at&lt;float&gt; 替换为hom.at&lt;double&gt;,看看是否有帮助。

顺便说一句,我认为没有理由首先声明像cv::Mat hom(3, 3, CV_32F); 这样的矩阵。你可以直接做cv::Mat hom = getPerspectiveTransform(sour, dest);

这个问题的另一个解决方案是使用静态类型矩阵,即 cv::Matx&lt;float, 3, 3&gt; hom = getPerspectiveTransform(sour, dest);。 OpenCV 会自动将getPerspectiveTransform 返回的值转换为赋值中的正确类型。然后,当您打印元素时,您可以将hom.at&lt;float&gt;(i1, i2) 替换为hom(i1, i2),因为元素类型现在是静态已知的。

更新: &lt;&lt; 运算符似乎以大约 16 个十进制数字打印 hom 矩阵的元素这一事实表明精度为 double。对于单精度 (float),它将是大约 7 个十进制数字。

【讨论】:

以上是关于显示 cv2 Mat 的差异的主要内容,如果未能解决你的问题,请参考以下文章

虽然找到2张图片之间的差异,但OpenCV差异大于预期

MATLAB:.mat 版本之间的差异

为啥 cv::Mat 的 RAM 和硬盘大小总是有 4.5 倍的差异?

如何获得 2 个 cv::Mat 对象之间的绝对差异

创建视频前后的帧大小差异

行优先与列优先遍历opencv中Mat数据类型的效率差异