C++の配列クラスからCの配列構造体への変換で嵌ったのでメモ。
正常ケース
OpenCVでは以下のような方法で、
cv::MatからCvMatに変換できます。
cv::Mat eye = cv::Mat::eye(3,3,CV_8UC1); CvMat eyeC = eye; std::cout << cv::Mat(&eyeC) << std::endl;
出力結果
[1, 0, 0; 0, 1, 0; 0, 0, 1]
問題ケース
しかし、次のような記載をすると、
eyeCが期待した結果になりません。
CvMat eyeC = cv::Mat( cv::Mat::eye(3,3,CV_8UC1) ); std::cout << cv::Mat(&eyeC) << std::endl;
出力結果
[221, 221, 221; 221, 221, 221; 221, 221, 221]
問題ケースの原因
原因は、eyeCの参照するデータ領域が解放されていることでした。
今回のようにcv::MatからCvMatに変換した場合、
CvMatはcv::Matで確保されたデータ領域を参照します。
しかし、問題ケースの“cv::Mat( cv::Mat::eye(3,3,CV_8UC1) )”は1行目が終わった時点で解放されます。
なので、2行目以降ではeyeCの参照するデータ領域は既に解放されていることになります。
ちなみに、今回の問題ケースはVisual StudioのDebugビルドで実行しており、
eyeCの出力結果はeye行列ではありません。
しかし、Releaseビルドの場合だと、
問題ケースにおけるeyeCの出力結果がeye行列になる場合があります。
気付きにくく、放っておくとひどいバグの原因になりそう。