OpenCV から得られる映像をDXライブラリ的に一番高速に描画するプログラムを組んでみました
#include <cv.h>
#include <highgui.h>
#include <ctype.h>
#include <string.h>
#include "DxLib.h"
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow )
{
CvCapture *capture ;
IplImage *image ;
int GrHandle ;
BASEIMAGE BaseImage ;
// ウインドウモードで起動
ChangeWindowMode( TRUE ) ;
// DXライブラリ初期化処理
if( DxLib_Init() == -1 )
return -1;
// 描画先を裏画面にする
SetDrawScreen( DX_SCREEN_BACK ) ;
// カメラからのビデオキャプチャを初期化する
capture = cvCreateCameraCapture( 0 ) ;
// BASEIMAGE 構造体を0で初期化
memset( &BaseImage, 0, sizeof( BASEIMAGE ) ) ;
// カラーフォーマットは変化しないので最初に設定
CreateFullColorData( &BaseImage.ColorData ) ;
// ミップマップではないので0
BaseImage.MipMapCount = 0 ;
// 空のグラフィックハンドルの値を初期化
GrHandle = -1 ;
// メインループ
while( ProcessMessage() == 0 )
{
// フレームを取得
image = cvQueryFrame( capture ) ;
// BASEIMAGE の要素を埋める
BaseImage.GraphData = image->imageData ;
BaseImage.Width = image->width ;
BaseImage.Height = image->height ;
BaseImage.Pitch = image->widthStep ;
// グラフィックハンドルを作成しているかどうかで処理を分岐
if( GrHandle == -1 )
{
// 最初の場合はグラフィックハンドルの作成と映像の転送を一度に行う
GrHandle = CreateGraphFromBaseImage( &BaseImage ) ;
}
else
{
// 2回目以降はグラフィックハンドルへ映像を転送
ReCreateGraphFromBaseImage( &BaseImage, GrHandle ) ;
}
// フレームの内容を画面に描画
DrawGraph( 0, 0, GrHandle, FALSE ) ;
// 裏画面の内容を表画面に反映
ScreenFlip() ;
}
// ビデオキャプチャの後始末
cvReleaseCapture( &capture ) ;
// DXライブラリ使用の終了処理
DxLib_End() ;
// ソフトの終了
return 0 ;
}
OpenCV から得られる映像情報を元にグラフィックハンドルを作成したり、グラフィックハンドルへ映像を転送する際には
BASEIMAGE という構造体を使用します、これはDXライブラリ内部で画像を扱うために使用している構造体で、
中身は以下のようになっています
// 基本イメージデータ構造体
struct BASEIMAGE
{
COLORDATA ColorData ; // ピクセルフォーマット情報
int Width, Height, Pitch ; // 幅、高さ、ピッチ
void *GraphData ; // 画像イメージへのポインタ
int MipMapCount ; // ミップマップの数
} ;
ColorData にピクセルフォーマットに関する情報を設定して、Width,Height に画像のサイズを
Pitch にメモリ上に存在する画像イメージの1ライン辺りのバイト数を、
GraphData に画像イメージが格納されているメモリ領域へのアドレスを
MipMapCount にミップマップを使用する場合のミップマップレベルを設定します( 通常は0でOK )
cvQueryFrame で取得できる構造体の中身から BASEIMAGE に当てはまるものを設定して、
後はグラフィックハンドルの作成を行う場合は CreateGraphFromBaseImage を( LoadGraph の BASEIMAGE 版みたいなもの )、
既に作成してあるグラフィックハンドルに映像情報のみを転送する場合は ReCreateGraphFromBaseImage( ReloadGraph みたいなもの ) を使用します
// 基本イメージデータからグラフィックハンドルを作成する
int CreateGraphFromBaseImage( BASEIMAGE *BaseImage ) ;
// 基本イメージデータから既存のグラフィックハンドルに画像データを転送する
int ReCreateGraphFromBaseImage( BASEIMAGE *BaseImage, int GrHandle ) ;
カラーフォーマットは BGR の順番に並んでいるものとしてそのフォーマットの情報を設定する関数
CreateFullColorData を使用していますが、もし他のフォーマットの場合は CreateARGBColorData 等の
関数を使用する必要があります( 見たところ、普通に使用している限り他のフォーマットになることは無さそうですが・・・ )
よろしければお試し下さい m(_ _)m
<2014/4/13 17:28 最新版で正常に動作しなくなっていたので、サンプルプログラムを修正>