OpenCV中的图像数据格式为Mat类型,该数据结构中的数据存储为行优先,而Matlab中的图像数据存储时是列优先。而很多文献的开源代码是基于matlab完成,当我们需要将其转换为C/C++时,可能会牵涉到数据格式的匹配问题,因此初步实现了一个类,完成两者之间数据转换。
1.头文件
//Mat2Cell.h
#ifndef __MAT2CELL_H__
#define __MAT2CELL_H__
#include
using namespace cv;
class Mat2Cell
{
public:
Mat2Cell();
Mat2Cell(int _width, int _height, int _channel = 1);
Mat2Cell(const Mat &src);
Mat2Cell(const Mat2Cell &src);
Mat2Cell& operator=(const Mat2Cell &other);
~Mat2Cell();
void fromcvMat(const Mat &src);
Mat tocvMat() const;
uchar * chan(int k = 0);
uchar at(int row, int col, int channel);
void crop(int r1, int r2, int c1, int c2);
void create(int _width, int _height, int _channel = 1);
void release();
int total() const;
private:
void copyFromMatRawData(const uchar * pMat);
void copyToMatRawData(uchar * output) const;
public:
int width;
int height;
int channel;
uchar *pData;
};
inline int Mat2Cell::total() const
{
return width*height*channel;
}
inline uchar * Mat2Cell::chan(int k /* = 0 */)
{
return pData + k*width*height;
}
inline uchar Mat2Cell::at(int row, int col, int channel)
{
return pData[channel*width*height + col*height + row];
}
#endif
2.源文件
//Mat2Cell.cpp
#include "Mat2Cell.h"
Mat2Cell::Mat2Cell()
{
width = 0;
height = 0;
channel = 0;
pData = NULL;
}
Mat2Cell::Mat2Cell(int _width, int _height, int _channel /* = 1 */)
{
pData = NULL;
create(_width, _height, _channel);
}
Mat2Cell::Mat2Cell(const Mat &src)
{
pData = NULL;
create(src.cols, src.rows, src.channels());
copyFromMatRawData(src.data);
}
Mat2Cell::Mat2Cell(const Mat2Cell &src)
{
create(src.width, src.height, src.channel);
memcpy(pData, src.pData, total());
}
Mat2Cell& Mat2Cell::operator=(const Mat2Cell &other)
{
if (total() != other.total())
{
delete[]pData;
pData = new uchar[other.total()];
memset(pData, 0, other.total());
}
width = other.width;
height = other.height;
channel = other.channel;
if (other.pData == NULL)
{
pData = NULL;
}
else
{
memcpy(pData, other.pData, total());
}
return *this;
}
void Mat2Cell::fromcvMat(const Mat &src)
{
create(src.cols, src.rows, src.channels());
copyFromMatRawData(src.data);
}
Mat Mat2Cell::tocvMat() const
{
Mat result;
result.create(height, width, CV_8UC(channel));
copyToMatRawData(result.data);
return result;
}
void Mat2Cell::crop(int r1, int r2, int c1, int c2)
{
int tr = height, tc = width;
height = r2 - r1;
width = c2 - c1;
uchar *u = new uchar[height*width*channel];
for (int k = 0; k < channel; k++)
{
uchar *p = u + k*width*height;
for (int w = 0; w < width; w++)
{
memcpy(p, pData + k*tr*tc + (c1 + w)*tr + r1, height);
p += height;
}
}
delete[]pData;
pData = u;
}
void Mat2Cell::create(int _width, int _height, int _channel /* = 1 */)
{
release();
width = _width;
height = _height;
channel = _channel;
pData = new uchar[total()];
memset(pData, 0, total());
}
Mat2Cell::~Mat2Cell()
{
release();
}
void Mat2Cell::release()
{
if (pData == NULL) return;
delete[]pData;
width = 0; height = 0; channel = 0;
pData = NULL;
}
void Mat2Cell::copyFromMatRawData(const uchar* pMat)
{
for (int k = 0; k < channel; k++)
{
for (int w = 0; w < width; w++)
{
for (int h = 0; h < height; h++)
{
pData[k*width*height + w*height + h] = pMat[h*channel*width + w*channel + k];
}
}
}
}
void Mat2Cell::copyToMatRawData(uchar * output) const
{
for (int h = 0; h < height; h++)
{
for (int w = 0; w < width; w++)
{
for (int k = 0; k < channel; k++)
{
output[h*channel*width + w*channel + k] = pData[k*width*height + w*height + h];
}
}
}
}
#include
#include
#include
#include
#include "Mat2Cell.h"
using namespace std;
using namespace cv;
int main()
{
//用随机数构造一个Mat
vector matData;
srand((unsigned int)time(NULL));
for (int i = 0; i < 48; i++)
{
uchar temp = rand() % 255;
matData.push_back(temp);
}
Mat src = Mat(4, 4, CV_8UC3, matData.data());
Mat2Cell mat2cell(src); //数据转换
//验证结果
int width = mat2cell.width;
int height = mat2cell.height;
int channel = mat2cell.channel;
uchar *pData = mat2cell.pData;
for (int k = 0; k < channel; k++)
{
cout << "+++++++++++++++++++++++++++++++++++" << endl;
for (int w = 0; w < width; w++)
{
for (int h = 0; h < height; h++)
{
cout << (int)pData[k*width*height + w*height + h] << "\t";
}
cout << endl;
}
}
system("pause");
return 0;
}
1.随机数构造的Mat
2.打印结果