1

OpenCV Mat ファイルを Matlab マトリックスに変換する 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);

    }

元の画像 結果はMatlabに表示されます

以下のコードがこの問題の原因であると思われますが、修正方法がわかりません。

memcpy((char*)mxGetPr(T), (char*)m.data, rows*cols*sizeof(char));
4

2 に答える 2

4

から Matlab の行列にデータをコピーするときcv::Matは、次の点に注意する必要があります。

  1. OpenCV では、すべての行列は行優先ですが、Matlab では列優先です。コピーする前に移調する必要があります。

  2. カラー画像をコピーする場合は、チャネルごとにデータを転送する必要があります。


カラー画像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

ここでは、画像に使用される Matlab の型UINT8と一致することに注意してください。uint8

于 2015-04-07T03:04:29.570 に答える