ドナドナされるプログラマのメモ

Windows用アプリのプログラミングメモ

CImageからcv::Matへの画像コピー

MFCで画像をお手軽に使えるクラスCImageから、画像処理の定番OpenCV用のクラスcv::Matへ画像をコピーするのは、一見簡単だが罠がある。CImageが保持している画像データへのポインタはCImage::GetBits()で取得できるのだが、このポインタ、データの先頭を指す場合と、最後の行の先頭を指す場合があるのだ。そのため、GetBits()で取得したポインタと画像サイズを元にmemcpyするとアクセス違反が発生しうる。

また、CImageはメモリアクセスを効率化するためか、行末にビットスタッフを行う。例えば、1行あたりのデータ量が405バイトの場合、実際には408バイトが使われる。一方、cv::Matはcreate()で作成したオブジェクトならば常に全データが連続する(ビットスタッフなし)(cv::Mat::isContinuous()のドキュメントに記載)。そのため、そもそもコピーするデータが異なっている。

以上を踏まえると、以下のようなコードが必要となる。