我创建了一个Matlab引擎,将OpenCV Mat文件转换为Matlab矩阵。但是,我得到了错误的结果。我附上了我的代码,以便您可以直接测试它。
#pragma comment (lib, "libmat.lib")
#pragma comment (lib, "libmx.lib")
#pragma comment (lib, "libmex.lib")
#pragma comment (lib, "libeng.lib")
void cvLoadMatrixToMatlab(const Mat& m, const string name, Engine *m_pEngine)
{
int rows=m.rows;
int cols=m.cols;
string text;
mxArray *T=mxCreateDoubleMatrix(cols, rows, mxREAL);
memcpy((char*)mxGetPr(T), (char*)m.data, rows*cols*sizeof(char));
engPutVariable(m_pEngine, name.c_str(), T);
text = name + "=" + name + "'"; // Column major to row major
engEvalString(m_pEngine, text.c_str());
mxDestroyArray(T);
}
int main(int argc, char **argv)
{
/*Open Matlab Engine*/
Engine *m_pEngine;
m_pEngine = engOpen("null");
cv::Mat img = imread("panda.jpg",0);
cvLoadMatrixToMatlab(img,"imgMatlab", m_pEngine);
engEvalString(m_pEngine, "imshow(imgMatlab)");
cv::waitKey(0);
}
我怀疑下面的代码导致了这个问题,但我不知道如何修复它。
memcpy((char*)mxGetPr(T), (char*)m.data, rows*cols*sizeof(char));
答案 0 :(得分:3)
将数据从cv::Mat
复制到Matlab的矩阵时,您应该注意:
在OpenCV中,所有矩阵都是行主要的,而对于Matlab来说是col-major。您应该在复制之前进行转置。
要复制彩色图像,您应该逐个频道传输数据。
当您要将彩色图像cv::Mat
复制到Matlab时,您应该执行以下操作:
mwSize dims[] = {rows, cols, 3};
mxArray *T = mxCreateNumericArray(3, dims, mxUINT8_CLASS, mxREAL);
UINT8 *ptr = (UINT8 *) mxGetData(T);
std::vector<cv::Mat> channels; // B, G, R channels
cv::split(m, channels);
// remember to transpose first because MATLAB is col-major!!!
cv::transpose(channels[0], channels[0]);
cv::transpose(channels[1], channels[1]);
cv::transpose(channels[2], channels[2]);
memcpy(ptr, channels[2].ptr(), rows*cols*sizeof(UINT8));
memcpy(ptr+rows*cols, channels[1].ptr(), rows*cols*sizeof(UINT8));
memcpy(ptr+2*rows*cols, channels[0].ptr(), rows*cols*sizeof(UINT8));
engPutVariable(m_pEngine, name.c_str(), T); // put into matlab
已更新:如果您要复制灰度图像,则应该是
mwSize dims[] = {rows, cols};
mxArray *T = mxCreateNumericArray(2, dims, mxUINT8_CLASS, mxREAL);
UINT8 *ptr = (UINT8 *) mxGetData(T);
cv::transpose(m, m); // remember to tranpose first because MATLAB is col-major!!!
memcpy(ptr, m.ptr(), rows*cols*sizeof(UINT8));
engPutVariable(m_pEngine, name.c_str(), T); // put into matlab
请注意,UINT8
此处应与用于图片的Matlab uint8
类型保持一致。
答案 1 :(得分:0)
好。我使用for循环来复制数据,最后它工作。
int rows=m.rows;
int cols=m.cols;
mwSize dims[] = {rows, cols};
mxArray *T = mxCreateNumericArray(2, dims, mxUINT8_CLASS, mxREAL);
char *ptr = (char *) mxGetData(T);
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
ptr[j*rows + i] = (* m.row(i).col(j).data);
}
}
engPutVariable(m_pEngine, name.c_str(), T); // put into matlab
对于上面发布的答案,我仍在努力。感谢@herohuyongtao的帮助提及转置问题。