opencv之reshape和resize操作
[TOC]
Mat::reshape
该函数只是在逻辑上改变矩阵的行数或者通道数, 没有任何数据的复制和删减, 因此是$O(1)$操作, 要求矩阵是连续的.
Mat cv::Mat::reshape (int cn, int rows = 0) const
Changes the shape and/or the number of channels of a 2D matrix without copying the data.
The method makes a new matrix header for *this elements. The new matrix may have a different size and/or different number of channels. Any combination is possible if:
- No extra elements are included into the new matrix and no elements are excluded. Consequently, the product rows * cols * channels() must stay the same after the transformation.
- No data is copied. That is, this is an O(1) operation. Consequently, if you change the number of rows, or the operation changes the indices of elements row in some other way, the matrix must be continuous. See Mat::isContinuous .
std::vector<Point3f> vec;
...
Mat pointMat = Mat(vec). // convert vector to Mat, O(1) operation
reshape(1). // make Nx3 1-channel matrix out of Nx1 3-channel.
// Also, an O(1) operation
t(); // finally, transpose the Nx3 matrix.
// This involves copying all the elements
- cn: New number of channels. If the parameter is 0, the number of channels remains the same.
- rows: New number of rows. If the parameter is 0, the number of rows remains the same.
Mat::row
取矩阵某行, 该操作是个浅拷贝.
The method makes a new header for the specified matrix row and returns it. This is an O(1) operation, regardless of the matrix size. The underlying data of the new matrix is shared with the original matrix.
Mat cv::Mat::row(int y) const
注:
将矩阵A第i行的元素拷贝到第j行, 因为A.row(i)是软拷贝, 不能进行赋值.
Mat A;
...
A.row(i) = A.row(j); // will not work
// works, but looks a bit obscure.
A.row(i) = A.row(j) + 0;
// this is a bit longer, but the recommended method.
A.row(j).copyTo(A.row(i));
Mat::resize
该函数改变矩阵的行数, 会引起矩阵的重新分配.
void Mat::resize(size_t sz)
void Mat::resize(size_t sz, const Scalar& s)
- sz: New number of rows.
- s: Value assigned to the newly added elements.
cv::resize
这个是通过插值的方式来改变图像的尺寸,貌似不支持int型的元素,uchar,float和double都可以。
void resize( InputArray src, OutputArray dst, Size dsize, double fx=0, double fy=0, int interpolation=INTER_LINEAR )
src – input image.
dst – output image; it has the size
dsize
(when it is non-zero) or the size computed fromsrc.size()
,fx
, andfy
; the type ofdst
is the same as ofsrc
.dsize - output image size; if it equals zero, it is computed as:
\(dsize = Size(round(fx*src.cols), round(fy*src.rows))\)
Either
dsize
or bothfx
andfy
must be non-zero.fx–scale factor along the horizontal axis; when it equals 0, it is computed as
\((double)dsize.width/src.cols\)
fy–scale factor along the vertical axis; when it equals 0, it is computed as
$ dsize.height/src.rows$
interpolation–
interpolation method:
- INTER_NEAREST - a nearest-neighbor interpolation
- INTER_LINEAR - a bilinear interpolation (used by default)
- INTER_AREA - resampling using pixel area relation. It may be a preferred method for image decimation, as it gives moire’-free results. But when the image is zoomed, it is similar to the
INTER_NEAREST
method. - INTER_CUBIC - a bicubic interpolation over 4x4 pixel neighborhood
- INTER_LANCZOS4 - a Lanczos interpolation over 8x8 pixel neighborhood
If you want to resize src
so that it fits the pre-created dst
, you may call the function as follows:
// explicitly specify dsize=dst.size(); fx and fy will be computed from that.
resize(src, dst, dst.size(), 0, 0, interpolation);
If you want to decimate the image by factor of 2 in each direction, you can call the function this way:
// specify fx and fy and let the function compute the destination image size.
resize(src, dst, Size(), 0.5, 0.5, interpolation);