引言
模式识别中,经常需要将所有样本导入一个矩阵中,涉及到将矩阵转为一行数据然后复制到大矩阵中。这里以练习中遇到的情况举例:200个图片样本。vector $ <cv::Mat> trainImages; 自己备忘。
1、Mat::reshape( )
C++: Mat Mat::reshape(int cn, int rows=0 const)
cn:目标通道数,如果是0则保持和原通道数一致;
rows:目标行数,同上是0则保持不变;
应用:在提取特征时,往往需要把特征矩阵变成一个行向量
return feature.reshape(0,1).clone();
2. Mat::Resize( )
是改变矩阵的行数,会引起矩阵的重新分配。
C++: void Mat::resize(size_t sz)
C++: void Mat::resize(size_t sz, const Scalar& s)
sz:目标行数
s :如果sz大于原来函数,可以选择填充值
3.cv::resize( )
这个是通过插值的方式来改变图像的尺寸,貌似不支持int型的元素,uchar,float和double都可以。
C++: void resize( InputArray src, OutputArray dst, Size dsize, double fx=0, double fy=0, int interpolation=INTER_LINEAR )
dst的尺寸是由dsize,fx和fy决定的,与dst本身的type和size都没有关系。
当size不为0时,可以直接确定dst的大小,这时的fx和fy可以设为0;
当size为0时,fx代表宽度(列)的缩放系数,fy代表高度(行)的缩放系数,这时dsize可以写成Size(),它将默认设置为
dsize = Size(round(fx*src.cols), round(fy*src.rows));
normol: cv::resize(src, src, cv::Size(64, 128));
4.Rect::Rect(INT,INT,INT,INT)
创建一个矩形对象,通过使用四个整数来初始化矩形左上角的横坐标、纵坐标以及矩形的高度、宽度。
法一
Mat sampleFeatureMat;
Mat src;
for (int num = 0; num < 200; num++)
{
src = trainImages[num];
if (0 == num)
{
//提前定义矩阵大小,不然内存报错
sampleFeatureMat = Mat::zeros(trainImages.size(), src.rows*src.cols, CV_32FC1);
}
sampleFeatureMat.row(num) = src.reshape(1, 1).clone();
}
法二
Mat sampleFeatureMat;
Mat src;
for (int num = 0; num < 200; num++)
{
src = trainImages[num];
//动态行扩展
src.copyTo(sampleFeatureMat(Rect(0, 0, src.rows*src.cols, 1)));//师姐
// trainImages[num].copyTo(sampleFeatureMat(Rect(0, 0, src.rows*src.cols, 1)));
}
法三
Mat sampleFeatureMat;
Mat src;
Mat dst;
for (int num = 0; num < 200; num++)
{
src = trainImages[num];
dst = src.reshape(1, 1);
//动态行扩展
sampleFeatureMat.push_back(dst);//住你家
//sampleFeatureMat.push_back( trainImages[num].reshape(1, 1));
}
速查链接:
基本矩阵操作、图像加减乘除以及通道分离与融合、Rect类1、Rect类2。