1、Mat与vector互转
reshape()函数返回的Mat,即是修改通道、行、列后的矩阵,是原矩阵,并没有进行矩阵的拷贝操作,这个在官方文档中介绍到了。
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
/***************** Mat转vector **********************/
template<typename _Tp>
vector<_Tp> convertMat2Vector(const Mat &mat)
{
return (vector<_Tp>)(mat.reshape(1, 1));//通道数不变,按行转为一行
}
/****************** vector转Mat *********************/
template<typename _Tp>
cv::Mat convertVector2Mat(vector<_Tp> v, int channels, int rows)
{
cv::Mat mat = cv::Mat(v).clone();//将vector变成单列的mat,这里需要clone(),因为这里的赋值操作是浅拷贝
cv::Mat dest = mat.reshape(channels, rows);
return dest;
}
int main()
{
/* char ->CV_8SC
* unsigned char,uchar ->CV_8UC
* unsigned short int,ushort->CV_16UC
* short int->CV_16SC
* int ->CV_32SC
* float ->CV_32FC
* double->CV_64FC
*/
uchar arr[4][3] = { { 1, 1,1 },{ 2, 2,2 },{ 3, 3,3 },{ 4,4, 4 } };
cv::Mat srcData(4, 3, CV_8UC1, arr);
cout << "srcData=\n" << srcData << endl;
vector<uchar> v = convertMat2Vector<uchar>(srcData);
cv::Mat dest = convertVector2Mat<uchar>(v, 1, 4);//把数据转为1通道,4行的Mat数据
cout << "dest=\n" << dest << endl;
system("pause");
waitKey();
return 0;
}
运行结果:
srcData=
[ 1, 1, 1;
2, 2, 2;
3, 3, 3;
4, 4, 4]
dest=
[ 1, 1, 1;
2, 2, 2;
3, 3, 3;
4, 4, 4]
Mat转vector还有两种方式:
- vector使用push_back()方式将Mat矩阵的每一个元素添加到集合中;
- 在vector初始化时赋值,示例代码如下:
vector<uchar> array;
if (dest.isContinuous())
{
array.assign(dest.datastart, dest.dataend);//重新分配vector
}
cout << endl;
for (int i = 0; i < dest.rows * dest.cols; i++)
{
cout << (int)array[i] << "\t";
}
输出结果:
1 1 1 2 2 2 3 3 3 4 4 4
2、Mat与数组互转
Mat来存储数据,避免使用数组等操作:
Mat dest= (cv::Mat_<float>(2, 1) << 0.4404, 0.3111);
cout << "dest=" << dest<< endl;
float a = (float)dest.at<float>(1,1);
数组 --> Mat:
uchar cbuf[height][width];
cv::Mat img(height, width, CV_8UC1, cbuf);
Mat --> 一维数组:
uchar *array=new uchar[mat.rows * mat.cols];
if (mat.isContinuous())
array = mat.data;
//输出
cout << endl;
for (int i = 0; i < mat.rows * mat.cols; i++)
{
cout << (int)array[i] << "\t";
}
Mat --> 二维数组:
uchar **array = new uchar*[mat.rows];
for (int i=0; i<mat.rows; ++i)
array[i] = new uchar[mat.cols];
for (int i = 0; i < mat.rows; ++i)
array[i] = mat.ptr<uchar>(i);
//输出
cout <<endl;
for (int i = 0; i < mat.rows; i++)
{
for (int j = 0; j < mat.cols; j++)
{
cout << (int)array[i][j] << "\t";
}
}
3、Vector与数组互转
1、数组 --> vector
uchar arr[] = { 1, 1,1 ,2 ,2 ,1 ,2 ,1 };
vector<uchar> vec(arr, arr + sizeof(arr) / sizeof(uchar));
2、vector --> 数组
由于vector内部的数据是存放在连续的存储空间,vector转数组事实上只需要获取vector中第一个数据的地址和数据的长度即可。如果仅仅是传参,无需任何操作,直接传地址即可,如果要进行数据复制,可以借用内存拷贝函数“memcpy”。
uchar*buffer = new uchar[vec.size()];
if (!vec.empty())
{
memcpy(buffer, &vec[0], vec.size() * sizeof(uchar));
}
注:以上所有代码,均亲测可用!
原文:https://blog.csdn.net/guyuealian/article/details/80253066