C++ 为什么这个范围会爆炸

C++ 为什么这个范围会爆炸,c++,opencv,C++,Opencv,为什么下面的代码段可以工作 int sizearray[3] = {3,4,2}; Mat OneM = Mat::ones(3,4,CV_8UC1); Mat TwoM = Mat::ones(3,4,CV_8UC1)+1; Mat OneTwo3D = Mat::zeros(3,sizearray,CV_8UC1); Mat OneTwo3DPlaneM; Range OneTwo3DRanges[] = {Range(1,3),Range(1,4),Range(1,2)}; OneT

为什么下面的代码段可以工作

int sizearray[3] = {3,4,2};
Mat OneM = Mat::ones(3,4,CV_8UC1);  
Mat TwoM = Mat::ones(3,4,CV_8UC1)+1; 
Mat OneTwo3D = Mat::zeros(3,sizearray,CV_8UC1);
Mat OneTwo3DPlaneM;
Range OneTwo3DRanges[] = {Range(1,3),Range(1,4),Range(1,2)};
OneTwo3DPlaneM = OneTwo3D(OneTwo3DRanges);
但是如果我把范围改成

Range OneTwo3DRanges[] = {Range(1,4),Range(1,4),Range(1,2)};
它爆炸了

在工作模式中,
OneTwo3DPlaneM
显然是一个2x3x1矩阵,因为
范围的“结束”是独占的(通过查看工作代码/范围结果
OneTwo3DPlaneM.size.p
确认,即
[2,3,1]
)。但是,仅将第一个范围从
range(1,3)
增加到
range(1,4)
会在

OneTwo3DPlaneM = OneTwo3D(OneTwo3DRanges);
请注意,我最终要做的是将一个图像分配到三维阵列的一个切片中(我想是通过
OneM.copyTo(OneTwo3DPlaneM)
)。上面的代码只是一个测试。因此,我只想创建一个引用平面
OneTwo3D
的矩阵,这样,对于这个测试,我可以将矩阵
OneM
分配给第一个平面,并最终将
TwoM
分配给第二个平面(在我将第三个范围更改为指向
OneTwo3D
的第二个平面之后)


考虑到我对opencv没有太多经验,我认为我在做一些弱智的事情。提前道歉。

下面的代码似乎很有效,copyTo不喜欢将二维数组分配到三维数组的一部分。所以,如下图所示,我将OneM和TwoM从3x4矩阵更改为3x4x1,然后它工作了。我猜接下来的问题是给一个图像(2d),我能不能把它重塑成一个3d实体,用一个单一的三维空间来复制快乐。考虑到重塑只适用于二维阵列,我不确定如何实现这一点

int sizearray1[3] = {3,4,1};
int sizearray[3] = {3,4,2};
//      Mat OneM = Mat::ones(3,4,CV_8UC1);  
Mat OneM = Mat::ones(3,sizearray1,CV_8UC1);  
//      Mat TwoM = Mat::ones(3,4,CV_8UC1)+1;  
Mat TwoM = Mat::ones(3,sizearray1,CV_8UC1)+1;  
Mat OneTwo3D = Mat::zeros(3,sizearray,CV_8UC1);
Mat OneTwo3DPlaneM;
Range OneTwo3DRanges[] = {Range::all(),Range::all(),Range(0,1)};
OneTwo3DPlaneM = OneTwo3D(OneTwo3DRanges);
OneM.copyTo(OneTwo3DPlaneM);
OneTwo3DRanges[2] = Range(1,2);
OneTwo3DPlaneM = OneTwo3D(OneTwo3DRanges);
TwoM.copyTo(OneTwo3DPlaneM);

是的,范围的“结束”是独占的,只是不要期望它“钳制”你给它的任何有效值。正如您之前已经发现的,在您的案例中,3是最大合法值。如果OneWO3D创建为3x4x2矩阵,范围(1,4)==>1到3,那么它当然应该是有效的,如果不是,那不是一个错误吗?毕竟,如果我不能这样做,还有什么别的办法?这不是运算符
Mat Mat::operator()(const Range*ranges)const
的用法吗?作为旁注,在大多数情况下,最好使用Mat(3,4,CV_32FC(2))代替。更易于使用,并更好地支持大多数数学运算。
Range OneTwo3DRanges[]={Range::all(),Range::all(),Range(1,2)}几乎可以工作。我写这篇文章几乎是因为,根据调试器,它将前13个字节(elts 0-12,包括)w/r设置为OneTwo3DPlaneM.data,设置为1。它应该只有12个,因为复制源OneM是一个3x4矩阵???另外,我不知道如何在OneWo3dPlanem中索引第二个平面,因为我需要指定一个范围(2,3)来索引平面2,但是,考虑到@berak所写的,因为OneWo3dPlanem是一个3x4x2矩阵,应该会产生一个越界错误(正如第一个示例所做的那样)
Mat(3,4,cv32fc(2))是什么
这意味着什么?这对索引有什么影响?