C ++ / OpenCV - 如何重塑cv :: Mat?

时间:2014-03-09 21:18:39

标签: c++ opencv

我的cv::Mat尺寸为40 rows X 32 columns

但是,我需要对此cv::Mat进行重新整形,以使其100 rows X 32 columns,并且愿意使用0空白元素。

我尝试过使用代码:

cv::Mat mat1 = <from somewhere else>
mat1.reshape(mat1.cols, 100);

但它失败了,错误:

OpenCV Error: Bad argument (The total number of matrix elements is not divisible by the new number of rows) in reshape.

有没有人有重塑cv::Mat矩阵的经验?同样,我真的希望能够采用100 rows X 32 columns矩阵并返回40 rows X 32 columns矩阵(并且只是截断额外的行);但我假设如果我解决了一个问题,那么我会解决另一个问题。

2 个答案:

答案 0 :(得分:3)

使用Mat::copyTo()

可以轻松实现此目的
Mat padded = Mat(100, 32, CV_8UC1, Scalar(0));
mat1.copyTo(padded(Rect(0, 0, mat1.cols, mat1.rows)));

另一方面,如果您希望从40x32 100x32获取Mat,那么也很容易做到:

Rect roi(0, 0, 32, 40);
Mat mat1 = padded(roi);

请注意,此处Mat::reshape()不合适,因为新矩阵中不包含任何额外元素,也不会排除任何元素。

答案 1 :(得分:1)

您可以使用OpenCV中的Range类对Mat对象进行切片。范围是独占的,这意味着Range(0, 4)将引用第1,2和3行(它不会引用第4行)。

以下是将4x3矩阵复制到6x3矩阵的示例。您可以使用任意数量的行和列:

Mat onesMat = Mat::ones(4, 3, CV_8UC1);
Mat zerosMat = Mat::zeros(6, 3, CV_8UC1);

cout<<"Before copying:"<<endl;
cout<<onesMat<<endl<<zerosMat<<endl;

// Copy onesMat to zerosMat. Destination rows [0,4), columns [0,3)
onesMat.copyTo(zerosMat(Range(0,4), Range(0,3)));


cout<<"After copying:"<<endl;
cout<<onesMat<<endl<<zerosMat<<endl;

以下是该计划的输出:

Before copying:
[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]
After copying:
[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]