OpenCV中的Mat数据与Matlab中的数据的相互转换

一、概述

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];
			}
		}
	}
}

3.主函数
#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

OpenCV中的Mat数据与Matlab中的数据的相互转换_第1张图片

2.打印结果

OpenCV中的Mat数据与Matlab中的数据的相互转换_第2张图片











你可能感兴趣的:(OpenCV中的Mat数据与Matlab中的数据的相互转换)