dポイントプレゼントキャンペーン実施中!

OpenCV初心者です。AVI形式の動画を再生しながら、Kinectからの映像を表示するというWindowsフォームアプリケーションを作っています。
開発環境はVisual C++ 2010 Express、OpenCV2.3.1で、KinectはOpenNIで動かしています。

現在、どちらか一方の映像が動いているとき、もう片方の映像が止まってしまうという問題が発生しています。AVI動画もKinectからの映像も同時に動いているようにするにはどうすればよいでしょうか。

以下にソースコードを示します。



#include "stdafx.h"
#include "Form1.h"
#include <stdio.h>
#include <opencv2\opencv.hpp>
#include <XnCppWrapper.h>

using namespace oni00;

#define CONFIG_PATH "Config00.xml"
#define WIN_WIDTH 640
#define WIN_HEIGHT 480

bool capFlag = false;
IplImage* img_camera = 0;
int g_slider_position = 0;
CvCapture* g_capture = NULL;

xn::Context context;
xn::ImageGenerator image;
xn::ImageMetaData imageMD;




//フォームを表示し、動画・カメラ映像用の画面を表示する
System::Void Form1::Form1_Load(System::Object^ sender, System::EventArgs^ e){
XnStatus nRetVal = XN_STATUS_OK;

nRetVal = context.InitFromXmlFile(CONFIG_PATH, NULL);
if (nRetVal != XN_STATUS_OK) {
MessageBox::Show("error - config.xml cannnot read");
return;
}

nRetVal = context.FindExistingNode(XN_NODE_TYPE_IMAGE, image);
if(nRetVal != XN_STATUS_OK) {
MessageBox::Show("error - Image Generator");
return;
}

img_camera = cvCreateImage(cvSize(WIN_WIDTH, WIN_HEIGHT),
IPL_DEPTH_8U,
3);

cvNamedWindow("Camera View");
cvNamedWindow("Movie View", CV_WINDOW_AUTOSIZE);



}



//Kinectの映像表示のボタン。ボタンを押すことでcapFlagが切り替わり、再生できる。

System::Void Form1::buttonstart_Click(System::Object^ sender, System::EventArgs^ e){
XnStatus nRetVal = XN_STATUS_OK;

buttonstop->Focus();

capFlag = true;
while (capFlag == true) {
context.WaitOneUpdateAll(image);

image.GetMetaData(imageMD);

memcpy(img_camera->imageData, imageMD.RGB24Data(), img_camera->imageSize);
cvCvtColor(img_camera, img_camera, CV_RGB2BGR);
cvShowImage("Camera View", img_camera);

Application::DoEvents();

}

}

//カメラ映像の一時停止ボタン
System::Void Form1::buttonstop_Click(System::Object^ sender, System::EventArgs^ e){
capFlag = false;
}


//以下のコードでAVI動画を表示する。http://itdiary.hatenablog.com/entry/2013/05/17/1 …を参考にしました。動画が複数あるために以下のように改良しました。

//スライドバー操作の際のコールバックルーチン定義のための関数
void onTrackbarSlide(int pos){
cvSetCaptureProperty(
g_capture,
CV_CAP_PROP_POS_FRAMES,
pos
);
}

//動画を表示する関数
void Showmovie(){
//bool isStop = false;
int frames = (int) cvGetCaptureProperty(
g_capture,
CV_CAP_PROP_FRAME_COUNT
);
if( frames!=0 ){
cvCreateTrackbar(
"Position",
"Movie View",
&g_slider_position,
frames,
onTrackbarSlide
);
}

IplImage* frame;

while(1){
frame = cvQueryFrame(g_capture);
if(!frame) {g_slider_position = 0;};
g_slider_position++;
cvShowImage("Movie View",frame);
cvSetTrackbarPos(
"Position",
"Movie View",
g_slider_position
);
char c = cvWaitKey(33);
if(c==27) break;
else if(c==32){
c = cvWaitKey(0); //スペースキーで一時停止
if(c==27) break;
}
}
cvReleaseCapture(&g_capture);
}

//動画を表示するボタン。このボタンは複数あり、それぞれ違う動画を表示できるようになっている。
System::Void Form1::button1_Click(System::Object^ sender, System::EventArgs^ e){
g_capture = cvCreateFileCapture( "link1.avi" );
Showmovie();

}

//フォームを閉じると、他の画面も閉じる
System::Void Form1::Form1_FormClosed(
System::Object^ sender, System::Windows::Forms::FormClosedEventArgs^ e){

capFlag = false;

context.Release();

cvReleaseImage(&img_camera);
cvDestroyAllWindows();
}

コードが多くて申し訳ありませんが、よろしくお願いします。

A 回答 (1件)

ソースをしっかり見ていないのですが、動画を再生するスレッドとキャプチャするスレッドを分けていますか?メインスレッドだけしかないのなら、おっしゃるような交互の動作になるのではないかと。


マルチスレッド化して、処理を並列化すれば、お望みの処理が行えると思います。
    • good
    • 0
この回答へのお礼

ありがとうございます。

お礼日時:2015/08/04 15:48

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!