画面に表示されてる画像をOpenCVに食わせようとしてハマった

まず、CBitmap インスタンスからビットマップデータを取り出す CBitmapT::GetBitmapBits が定義されてない。
Win32 APIだけど、CEでは使えないのだ。

これはデータから直接抽出できる。CBitmap bmpImage に画像が入ってるとして、

DIBSECTION dibsection;
::GetObject(bmpImage, sizeof(dibsection), &dibsection);
BITMAP bitmap = dibsection.dsBm;
BITMAP * data = (BITMAP *)bitmap.bmBits;

この data をOpenCV の IplImage に与えればいいかと思うけれど、そうはいかない。

IplImage * image = cvCreateImage(size, IPL_DEPTH_8S, 3);
cvSetData(image, data, step);
CAtlStringA bmpfile = _T("\\Storage Card\\bmp.jpg");
cvSaveImage(bmpfile, image);

cvSaveImage を実行したところで、エラーが出た。

Data Abort: Thread=97add8a0 Proc=80096f40 'ImageView.exe'
AKY=00004001 PC=00fd8dd8(cxcore200d.dll+0x00058dd8) RA=00fbb0a0(cxcore200d.dll+0x0003b0a0) BVA=1e1eb000 FSR=00000407

data をファイルに書き出してみると、ずいぶん小さいファイルになった。想定の2/3のサイズ……というところでオチが読めたあなたは、同じことでハマったことがすでにあると見た。

bitmap.bmWidthHeight が、bitmap.bmWidth の2倍の値しかない……つまり、24ビットカラーを期待してたのに16ビットカラーだった。
そしてOpenCV は16ビットカラーをサポートしていないし、減色されたデータを与えてもしょうがない。

CBitmap から取ってくるなんて横着をせずに、画像ファイルは別途 IplImage に読み込んでおくべきだ。

WM6 用にコンパイルした OpenCV というか libpng が、なぜかちゃんと動かない*1という問題が別にあったりするけれど。

*1:png_default_read_dataという関数で、ちゃんとCE用にReadFile API を使っているはずなのにファイルを読み込めてない。