Opencv 矩阵范围 L 值:这是一个错误吗?

Posted

技术标签:

【中文标题】Opencv 矩阵范围 L 值:这是一个错误吗?【英文标题】:Opencv Matrix Range L value : Is this a bug? 【发布时间】:2015-06-17 14:44:13 【问题描述】:

在我看来,使用带有 Ranges 的 Matrix 作为 L 值(赋值目标)应该可以工作(如果不是编译器错误会很好),但不能两者都取决于合法 r 值的细节。

cout << "hi mom" <<  endl;
Mat Img0=Mat::zeros(7,7,CV_8UC1);
Mat Img1=Mat::ones(7,7,CV_8UC1);
cout << Img0 << endl;
cout << Img1 << endl;
Img0(Range::all(), Range::all()) = Img1;
cout << Img0 << endl;
Img0(Range::all(), Range::all()) = 1;
cout << Img0 << endl;

下面是上面的输出。前两个矩阵打印输出为Img0Img1,分别由Mat::zerosMat::ones 初始化。

第三个矩阵打印出来又是Img0,但在

Img0(Range::all(), Range::all()) = Img1;

我预计会将Img0 设置为Img1;即所有的; 但事实并非如此。它仍然是全零。

第四个/最后一个矩阵打印出来的结果是

Img0(Range::all(), Range::all()) = 1;

与第三个赋值具有相同的 L 值,但它在标量是右值时起作用(与第三个作为矩阵的右值不同)。

我想念这件事有什么意义吗?是否应该允许这种 r 值区分行为?这对我来说似乎不一致。

[0, 0, 0, 0, 0, 0, 0;   
0, 0, 0, 0, 0, 0, 0;   
0, 0, 0, 0, 0, 0, 0;   
0, 0, 0, 0, 0, 0, 0;   
0, 0, 0, 0, 0, 0, 0;   
0, 0, 0, 0, 0, 0, 0;   
0, 0, 0, 0, 0, 0, 0]

[1, 1, 1, 1, 1, 1, 1;   
1, 1, 1, 1, 1, 1, 1;   
1, 1, 1, 1, 1, 1, 1;   
1, 1, 1, 1, 1, 1, 1;   
1, 1, 1, 1, 1, 1, 1;   
1, 1, 1, 1, 1, 1, 1;   
1, 1, 1, 1, 1, 1, 1] 

[0, 0, 0, 0, 0, 0, 0;   
0, 0, 0, 0, 0, 0, 0;   
0, 0, 0, 0, 0, 0, 0;   
0, 0, 0, 0, 0, 0, 0;   
0, 0, 0, 0, 0, 0, 0;   
0, 0, 0, 0, 0, 0, 0;   
0, 0, 0, 0, 0, 0, 0] 

[1, 1, 1, 1, 1, 1, 1;   
1, 1, 1, 1, 1, 1, 1;   
1, 1, 1, 1, 1, 1, 1;   
1, 1, 1, 1, 1, 1, 1;   
1, 1, 1, 1, 1, 1, 1;   
1, 1, 1, 1, 1, 1, 1;   
1, 1, 1, 1, 1, 1, 1]

【问题讨论】:

【参考方案1】:

不,这不是错误。

这行Img0(Range::all(), Range::all()) = Img1; 没有按预期工作,因为Img0(Range::all(), Range::all()) 形成了一个临时标头,该标头进一步分配给另一个标头,即Img1。请记住,这些操作中的每一个都是 O(1),即不会复制任何数据。 因此,不会发生真正的分配。

这样做可以更清楚地实现这种效果:

(Img0(Range::all(), Range::all()) = Img1) = 2;
cout << Img0 << endl;
cout << Img1 << endl;

如果你已经理解了我上面的描述,你应该知道代码只会改变Img1的值。输出是:

[0, 0, 0, 0, 0, 0, 0;
  0, 0, 0, 0, 0, 0, 0;
  0, 0, 0, 0, 0, 0, 0;
  0, 0, 0, 0, 0, 0, 0;
  0, 0, 0, 0, 0, 0, 0;
  0, 0, 0, 0, 0, 0, 0;
  0, 0, 0, 0, 0, 0, 0]
[2, 2, 2, 2, 2, 2, 2;
  2, 2, 2, 2, 2, 2, 2;
  2, 2, 2, 2, 2, 2, 2;
  2, 2, 2, 2, 2, 2, 2;
  2, 2, 2, 2, 2, 2, 2;
  2, 2, 2, 2, 2, 2, 2;
  2, 2, 2, 2, 2, 2, 2]  

延伸阅读:查看Mat::row()发生的类似效果。

【讨论】:

1) 这仍然使左值的基本效果完全依赖于右值。 2)什么;这个语法的重点是什么? Img0(Range::all(), Range::all()) = Img1; 有什么可能的好处?鉴于它实际上做了什么?据我了解,Img0(Range::all(), Range::all()) = Img1 与 img1=Img0(Range::all(), Range::all()) 相同。 Img1 成为 Img0 的标头。

以上是关于Opencv 矩阵范围 L 值:这是一个错误吗?的主要内容,如果未能解决你的问题,请参考以下文章

详解OpenCV的矩阵规范化函数normalize()范围化矩阵的范数或值范围(归一化处理),并附NORM_MINMAX情况下的示例代码

Opencv:用imwrite保存一个双矩阵

打印 CV_32F opencv 矩阵值

OpenCV 的构建出现错误,这些严重吗?

(opencv) 调试断言失败,向量下标超出范围

OpenCV逐元素矩阵乘法