I would like to declare an cv::Mat object and somewhere else in my code, change its dimension (nrows and ncols). I couldn't find any method in the documentation of OpenCV. They always suggest to include the dimension in the constuctor.
4 Answers
An easy and clean way is to use the create()
method. You can call it as many times as you want, and it will reallocate the image buffer when its parameters do not match the existing buffer:
Mat frame;
for(int i=0;i<n;i++)
{
...
// if width[i], height[i] or type[i] are != to those on the i-1
// or the frame is empty(first loop)
// it allocates new memory
frame.create(height[i], width[i], type[i]);
...
// do some processing
}
Docs are available at https://docs.opencv.org/3.4/d3/d63/classcv_1_1Mat.html#a55ced2c8d844d683ea9a725c60037ad0

- 19,708
- 4
- 59
- 82
-
4doesn't create() ruin the original image? I thought you had to use resize – john k Dec 21 '12 at 05:17
-
You are right Mat::create de-references the previous data http://docs.opencv.org/modules/core/doc/basic_structures.html#mat-create while Mat::resize preserves it just as the STL vector class http://docs.opencv.org/modules/core/doc/basic_structures.html#mat-resize – Andres Felipe Nov 24 '13 at 18:48
-
For reasons I'm too lazy to explain, resize() does not work as the STL containers' functions, and create() does the job in this case. It only re-allocates if new size does not match the original. – Sam Nov 25 '13 at 08:43
-
You mixed up the arguments. It's void create (int rows, int cols, int type). Thus, frame.create(height, width, type). – Sep 30 '16 at 16:17
If you mean to resize the image, check resize()
!
Create a new Mat dst
with the dimensions and data type you want, then:
cv::resize(src, dst, dst.size(), 0, 0, cv::INTER_CUBIC);
There are other interpolation methods besides cv::INTER_CUBIC
, check the docs.

- 1,809
- 3
- 18
- 32

- 92,053
- 36
- 243
- 426
-
Thanks karl, but my problem is that I want to define the type, and dimension of the cv::Mat object dynamically. resize() might be one solution, but it is not exactly what I am looking for. – Rasoul Dec 22 '11 at 16:28
-
Well, I've used `resize()` for that purpose (as far as I could understand you) more times than I can count. Whenever you need to change the dimensions of your `src` Mat , all you need to do is declare a new Mat with the dimensions and type you want, and execute `resize()` so it scales the data to the new dimension. And if you want, you can still perform `src = dst.clone();` to copy redimensioned data to the original Mat. – karlphillip Dec 22 '11 at 16:38
Do you just want to define it with a Size
variable you compute like this?
// dynamically compute size...
Size dynSize(0, 0);
dynSize.width = magicWidth();
dynSize.height = magicHeight();
int dynType = CV_8UC1;
// determine the type you want...
Mat dynMat(dynSize, dynType);

- 13,911
- 4
- 55
- 72
-
Thanks! I think I found the solution, declare cv::Mat image; and somewhere else dynamically change its properties by calling create() as image.create(magicWidth(), magicHeight(), dynType); – Rasoul Dec 22 '11 at 17:15
-
1Yeah, `create()` should definitely do the same thing as the constructor just after you have declared the `Mat` object. – mevatron Dec 22 '11 at 17:36
If you know the maximum dimensions and only need to use a subrange of rows/cols from the total Mat use the functions cv::Mat::rowRange and/or cv::Mat::colRange
http://docs.opencv.org/modules/core/doc/basic_structures.html#mat-rowrange

- 2,695
- 34
- 29