这个答案说明如何将一行矩阵复制到另一行:如何将一行Mat复制到OpenCv中的另一个Mat's列?然而,如果我试图复制一行矩阵到列向量的程序是突然结束。例子:
Mat A(640,480,CV_64F);
Mat B(480,1,CV_64F);
A.row(0).copyTo(B.col(0));
一个可能的解决方法是:
Mat A(640,480,CV_64F);
Mat B;
A.row(0).copyTo(B);
B = B.t();
但是如果A
是不同的类型,我怎么能在B
中得到CV_64F
类型呢?数据类型也被复制了吗?最重要的是,为什么我需要这个变通方法?
copyTo()函数只能在相同大小(宽度和高度)和相同类型的矩阵之间复制数据。由于这个原因,你不能直接用它来将矩阵的行复制到矩阵的列。通常,OpenCV会重新分配目标矩阵,使其大小和类型与原始图像匹配,但调用col()函数返回无法重新分配的常量临时对象。结果你的程序崩溃了。
其实这个问题是可以解决的。可以将行复制到列(如果它们具有相同数量的元素),也可以在不同类型的矩阵之间复制数据。Mat为它的数据提供了一个迭代器,这意味着您可以使用所有与迭代器一起工作的c++函数。Copy()函数示例
Mat A(640, 480, CV_64F);
Mat B(480, 1, CV_32S); // note that the type don't have to be the same
Mat tmp = A.row(0); // no data is copied here. it is needed only because taking iterator to temporary object is really bad idea
copy(tmp.begin<double>(), tmp.end<double>(), B.begin<int>());
由于API不支持以下代码(仅调换行):
A.row(0).t().copyTo( B.col(0) );
解决方法是从行创建一个临时矩阵,转置它,然后复制到目标矩阵
Mat temp = A.row(0);
temp = temp.t();
temp.copyTo( B.col(0) );
我宁愿这样做:
Mat A( 640, 480,CV_64F );
Mat B( 1, 480, CV_64F ); /* rather than 480 x 1, make a 1 x 480 first */
A.row(0).copyTo( B.row(0) );
B = B.t(); /* transpose it afterwards */
我认为这只是因为API还不支持它。