• 締切済み

OpenCVでの動画処理(入出力)

 OpenCVを用いて動画処理を行っています。  動作環境はMacOS10.9で、MacPortsを用いて最新版(おそらく...)のOpenCVを入れています。開発環境はXCode4です。  USBカメラを接続し、cvQueryFrame(CvCapture*)の関数を用いて画像を取得しています。そのままこの関数の返り値をIplImage*に代入してはいけないようなことをどこかで聞いていたので、念のため... IplImage* cap = cvQueryFrame(capture); IplImage* img; if(cap) img = cvCloneImage(cap); else img = NULL; というようなコードを書いて、imgに対して処理を行っています。  しかし、頻度は少ないのですがたまにimgにNULLが代入されるときが有ります。頻度は5000フレームに一度あるかどうかで、再現性が低いのでなんだかよくわかりません。 これは仕様なのでしょうか?USBカメラがたまに画像を取得できない瞬間があるという理解でいいのでしょうか?  私のコードに間違いがある場合は指導お願いします。  あと、動作が正常なので、画像は取得できているのでしょうが... QTCaptureSession warning: Session received the following error while decompressing video: Error Domain=NSOSStatusErrorDomain Code=-12909 "The operation couldn’t be completed. (OSStatus error -12909.)". Make sure that the formats of all video outputs are properly configured. というような警告が標準出力される時があります。 この警告の頻度はなかなか多く、200フレームに一度ぐらいあります。 動作は正常ですが、この瞬間だけ処理速度が少し落ちる傾向があるようです。 ちなみに言語はC++を用いています。 よろしくお願いします。

みんなの回答

  • myuki1232
  • ベストアンサー率57% (97/170)
回答No.2

cvReleaseImage(cap) をやらないのは正しいです。 他に細かい点としては、cvCloneImage を毎フレームやるのは重いので、事前にサイズ・チャンネル数がわかっているのであれば、そのサイズの IplImage を用意して cvCopy したほうが負荷が軽いです。cvReleaseImage(img) を毎フレームする必要もなくなります。(アルゴリズムによっては、そもそもコピー自体不要かもしれませんが…) 他に問題があるかどうかは、ソース全体を見てみないとわかりません。

全文を見る
すると、全ての回答が全文表示されます。
  • myuki1232
  • ベストアンサー率57% (97/170)
回答No.1

私は Mac で OpenCV を使ったことはないですが、Windows でやっていた時はそのような現象は発生していなかったと思います。もしあるとすれば Mac 固有の不具合ではないでしょうか。 コードスニペットもその部分は問題なさそうに見えます。(もちろん、cvReleaseImage(img) などはちゃんとやっていますよね?)

hira_kazu
質問者

お礼

 回答ありがとうございます。  cvReleaseImage(img)は行っています。  cvReleaseImage(cap)はやらない方が良いらしいのでやっていないですが...  メモリリークは起こしていないようなので、解放はうまく出来ているようです。  画像が取得できなくてもエラーを起こさないように気をつけてみます><

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • opencvでの2枚の画像の差分のやり方

    opencvのc言語で2枚の画像の差分をとりたいのですが,最後の差分をとるところでエラーが出てしまいます. char *filename = "動画の名前.avi"; CvCapture* cap = cvCaptureFromAVI(filename);//filename:const char*型のファイル名 filenameの動画像を読み込む double framecount = (int)cvGetCaptureProperty(cap, CV_CAP_PROP_FRAME_COUNT);//フレーム数を数える IplImage *srcCur=NULL; IplImage *srcOld=NULL; cvSetCaptureProperty(cap, CV_CAP_PROP_POS_FRAMES, 1); srcOld = cvQueryFrame(cap);//1フレーム目の画像を読み込む cvSetCaptureProperty(cap, CV_CAP_PROP_POS_FRAMES, 2); srcCur = cvQueryFrame(cap);//2フレーム目の画像を読み込む cvAbsDiff(srcOld2,srcCur2,dst);←ここでエラーがでます。 エラー内容は多分,差分するためには,同じ画像サイズ同士で 同じ型どうしでないといけないと書かれていますが, 同じ動画から読み込まれているので,違うことはありえないと思います. どうしたらいいですか?

  • OpenCVによる動画の連続再生

    現在OpenCVを用いて1秒間の動画のを連続再生しているのですが、時間経過とともに、処理が遅くなってしまいます。 //処理ループの開始 for(;;){ //AVIファイルからフレーム画像を取り出す if(NULL==(src_img=cvQueryFrame(capture))){         capture = cvCaptureFromAVI(filename);     src_img=cvQueryFrame(capture); } 上記で再生の繰り返し処理を行っているのですが、解決方法がわかりません。 この問題の解決方法がわかる方がおられましたら、よろしくお願いいたします。

  • OpenCVで動画の指定したフレームをキャプチャ

    現在,動画像処理を勉強している者です. OpenCV 2.3.1を使って動画像から任意のフレームを切り出し,Bitmapに格納する方法がわからなくて困っています. cvWaitKeyを使ってプログラムをスリープさせながら,繰返しすれば動画っぽく表示することはできるのですが,「40フレーム目から処理したい」といったことをするためにはどうすればいいのでしょうか. 以下のコードでプロパティをいじって動画の真ん中のフレームを切り出すつもりだったのですが,無理でした... cvSetCaptureProperty(capture, CV_CAP_PROP_POS_FRAMES, frame_count / 2.0); この後にIplImage型の変数にcvQueryFrame(capture)を突っ込んでもnullでした...なぜ... ※なお,capture←動画ファイル frame_count←総フレーム数がそれぞれ格納されています.

  • OpenCVでの画像処理について

    OpenCVを用いて連続して画像処理を行おうとしています。 単にcvLoadImageを用いて画像処理を行うことはできるのですが、 if(k=1)IplImage *img = cvLoadImage( "gazou1.jpg", -1); if(k=2)IplImage *img = cvLoadImage( "gazou2.jpg", -1); とif文を用いて画像を取り込んで処理して破棄して、新しい画像を取り込んで…と連続して異なる画像を同じ処理をするプログラムを作ると error C2065: 'img' : 定義されていない識別子です。 error C2227: '->height' : 左側がクラス、構造体、共用体、ジェネリック型へのポインタではありません。型は ''unknown-type'' です。 error C2227: '->width' : 左側がクラス、構造体、共用体、ジェネリック型へのポインタではありません。型は ''unknown-type'' です … とたくさんのエラーがでてしまいます。 if文を使わずに同じ画像を何度も処理することはできるのですが… この解消法をわかる方は教えてください。 ぜひ、よろしくお願いします。

  • 【OpenCV】ハイビジョンaviファイル読み込み途中にファイルが終了してしまう問題

    現在、OpenCVを用いてハイビジョンのaviファイル(1440*1080)の画像処理を行うプログラミングを行っています。 aviファイルの読み込み・表示はOpenCVでは一般的な方法であるcvCaptureFromAVIとcvQueryFrameを用いて行っています。 この処理において最初の方はうまく処理が行えるのですが、処理が進むとファイルがまだ終わっていないのにも関わらず、cvQueryFrameでフレームが取得できず、処理が終了してしまいます。 ファイルが終了してしまうフレーム数も大体決まっており、mencoderで変換したファイルは約460フレーム目で、Adobe Media Encoderで変換したファイルは約910フレーム目でファイルが終了してしまいます。 メディアプレーヤーでaviファイルそのものを再生してみたところ、460フレーム目・910フレーム目以降のフレームも存在していることが確認されたので、本当にファイルが終了しているというわけではありません。 このままだと約30秒以上の動画は扱えず、非常に困っています。 確認として以下のプログラムで1000フレーム目から読み込むようにしてみたのですが、やはりすぐにファイルが終わってしまいます。 試しにハイビジョンでないaviファイル(640*480)で処理してみたところ正常に動作したのでエンコーダーの問題かプログラムの問題ではないかと思うのですが、何か少しでもお分かりの方がいらっしゃればご指導よろしくお願い致します。 <aviファイル読み込みプログラム> #include <stdio.h> #include <cv.h> #include <cxcore.h> #include <highgui.h> char input_name[] = "hogehoge.avi"; int main(int argc, char** argv) { int key, i = 0; CvCapture* capture = NULL; IplImage* img = NULL; char* captureWindow = "Capture"; double prop; if(NULL==(capture = cvCaptureFromAVI(input_name))){ printf("指定のaviファイルが見つかりませんでした.\n"); return -1; } cvNamedWindow(captureWindow, CV_WINDOW_AUTOSIZE); prop = 1000.0f;       cvSetCaptureProperty(capture, CV_CAP_PROP_POS_FRAMES, prop); for(;;) { if(NULL==(img=cvQueryFrame(capture))){ printf("movieファイルが終わりました。\n"); break; } cvShowImage(captureWindow, img); printf("No.%dframe\n", i); i++; key = cvWaitKey(1); if (key == 0x1b) { break; } } cvReleaseCapture(&capture); cvReleaseImage(&img); cvDestroyWindow(captureWindow); return 0; }

  • OpenCVを用いた動画処理

    OpenCVを用いてaviファイルの読み込み、および、書き込みをしようとしているのですが、 指定のaviファイルが見つかりませんでした. というエラー処理の表示しか行われず困っています。 教えていただけませんでしょうか? よろしくお願いします。 読み込もうとしているファイルはデスクトップ上のOpenCVというフォルダのinput.aviというファイルです。 プログラムは以下に残します。 #include "cv.h" #include "cxcore.h" #include "highgui.h" #include <stdio.h> //読み込む動画ファイル名 char* input_filename="input.avi"; //書き込む動画ファイル名 char* output_filename="output.avi"; //IplImage IplImage* src; IplImage* gray; IplImage* canny; int main(){ CvCapture* capture = NULL; int key; //キー入力 // Cannyオペレータのパラメータ------ double low_threshold=50.0; double high_threshold=200.0; int aperture_size=3; //--------------------------------- // ファイル書き込み設定-------------- CvVideoWriter *writer = 0; int isColor = 1; int fps = 30; // フレームレート int frameW = 320; // width int frameH = 240; // hight //----------------------------------- //指定したAVIファイルが見つからない場合は終了 if(NULL==(capture = cvCaptureFromAVI(input_filename))){ fprintf(stderr,"指定のaviファイルが見つかりませんでした."); return -1; } gray = cvCreateImage( cvSize(frameW,frameH), IPL_DEPTH_8U, 1 ); canny = cvCreateImage( cvSize(frameW,frameH), IPL_DEPTH_8U, 1 ); gray->origin = 1; //orginを入力側に合わせる canny->origin = 1; //orginを入力側に合わせる writer=cvCreateVideoWriter(output_filename,-1,fps,cvSize(frameW,frameH),isColor); //画像表示ウィンドウの準備 cvNamedWindow("Edge Image", CV_WINDOW_AUTOSIZE); //画像表示ウィンドウの出現位置指定 cvMoveWindow("Edge Image", 50, 50); //処理ループの開始 for(;;){ //AVIファイルからフレーム画像を取り出す if(NULL==(src=cvQueryFrame(capture))){ break; } //グレースケールに変換 cvCvtColor(src, gray, CV_BGR2GRAY); //Cannyオペレータによるエッジ検出 cvCanny(gray, canny, low_threshold, high_threshold, aperture_size); //フレーム書き込み cvWriteFrame(writer,canny); //画像表示 cvShowImage("Edge Image", canny); //キー入力 key = cvWaitKey(20); //ESCキーを押すと終了 if(key==0x1b) break; } //解放 cvReleaseVideoWriter(&writer); cvReleaseCapture(&capture); cvReleaseImage(&src); cvReleaseImage(&gray); cvReleaseImage(&canny); cvDestroyWindow("Edge Image"); return 0; } 以上です。 よろしくおねがいします。

  • OpenCVの実行エラー

    OpenCVで下記の用なテストプログラムを作成しました。 --------------------------------------- #include <stdio.h> #include <cv.h> #include <cxcore.h> #include <highgui.h> #pragma comment(lib, "cv.lib") #pragma comment(lib, "cxcore.lib") #pragma comment(lib, "highgui.lib") int main(void) { unsigned char *Image; IplImage* img = NULL; IplImage* clone = NULL; // 画像読み込み img = cvLoadImage("image.bmp", -1); // 画像コピー clone = cvCloneImage(img); return 0; } --------------------------------------- ところが、実行すると --------------------------------------- Bad argument(Bad image header) in function cvCloneImage, D:\User\VP\openCV\cxcore\src\cxarray.cpp --------------------------------------- というエラーメッセージがでて実行することができませんでした。 OpenCVに付属していたsampleプログラムは動作しました。 // 画像コピー clone = cvCloneImage(img); の一文をコメントアウトするとエラーはなぜかでません。 このエラーはどうしてでるのでしょうか? OSはwindowsXP コンパイルはC++6.0とVS2005の両方で試しましたが同じ結果がでます。

  • OPENCVの画像処理について

    現在OPENCVを使って画像処理の勉強をしているのですが画像を読み込む際 IplImage* cvLoadImage という関数?を使って画像を読み込んでいるのですが 例えばファイルAに10枚画像が入っていたとしてその10枚をIplImage* cvLoadImageで一枚ずつ読み込むのではなくまとめて読みこむ(配列のように読みこんだ画像の順から[1]などの番号が付くような)という関数はないのでしょうか? 画像を変えるたびに「名前.jpg」を変えないといけない手間を省きたいです。

  • Opencv画像処理 bmp処理

    常々自分の理解力の無さに呆れるyuki-yutoです。 今回はOpencvで作ったプログラムと別のプロジェクトで作ったプログラムをソースをコピーして一つにしたところ、オバーフロー?してしまうらしくプログラムが実行できません。 二つ別々なら動くので関数の受け渡しが悪いのでしょうか? 今回の処理の目的は Opencvでキャプチャ→bmpで保存→(書いていませんが)for文でRGBの量を求める→一定量のRが検出されればショートカットを起動する というものです。 RGBに関してはfor(i=0;i<width;i++)とかでまわしているソースを何処かで見た気がするのですが、bmp処理は疎いので正直RGBをどうやって出すかまだ良くわかっていません。 widthまでを使っているあたり1pixel毎配列にでも記録させているのでしょうか・・・? #include <stdio.h> #include <Windows.h> //bmp読み込み,ショトカ #include<iostream> #include <C:\OpenCV2.1\include\opencv\cv.h> #include <C:\OpenCV2.1\include\opencv\highgui.h> #ifdef _DEBUG //Debugモードの場合 #pragma comment(lib,"C:\\OpenCV2.1\\lib\\cv210d.lib") #pragma comment(lib,"C:\\OpenCV2.1\\lib\\cxcore210d.lib") #pragma comment(lib,"C:\\OpenCV2.1\\lib\\cvaux210d.lib") #pragma comment(lib,"C:\\OpenCV2.1\\lib\\highgui210d.lib") #else //Releaseモードの場合 #pragma comment(lib,"C:\\OpenCV2.1\\lib\\cv210.lib") #pragma comment(lib,"C:\\OpenCV2.1\\lib\\cxcore210.lib") #pragma comment(lib,"C:\\OpenCV2.1\\lib\\cvaux210.lib") #pragma comment(lib,"C:\\OpenCV2.1\\lib\\highgui210.lib") #endif #include <math.h> #include <stdlib.h> int main(void){ //画像保存用 char str[32];//大きさは多く取っておいたほうが良いかも?640*480対応できるように。 //キー入力用 int key; //カメラの用意 CvCapture *capture; IplImage *frame = NULL; //カメラ画像用 //カメラ・デバイスの先頭ポインタを取得 capture = cvCaptureFromCAM(-1); //カメラ画像のサイズ double height = 240; double width = 320; //カメラ初期化 if(capture == NULL){ //カメラが見つからなかった場合 printf("カメラが見つかりません\n"); return (0); } //カメラ画像を表示するウィンドウの生成 cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, height); cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, width); cvNamedWindow("CaptureFromCamera", CV_WINDOW_AUTOSIZE); //キー入力されたら画像をキャプチャ while(1){ //カメラ画像からフレーム画像を取り込む frame = cvQueryFrame(capture); if(frame == NULL) break; //画像の表示 cvShowImage("CaptureFromCamera", frame); //sキー入力で画像を保存、Escキー入力でループから抜ける key = cvWaitKey(10); if(key == '\x1b') break; else if(key == 's'){ sprintf_s(str, "Capture_Bitmap.bmp"); cvSaveImage(str, frame); } } //ウィンドウの破棄 cvDestroyWindow("CaptureFromCamera"); } //ここからキャプチャしたbmp処理。 int main( int argc, char *argv[] ){ FILE *fp; //ポインタ、読み込み専用 BITMAPFILEHEADER bfh; //ファイルヘッダ BITMAPINFOHEADER bmpinfo; //情報ヘッダ //BMPファイルがあるかどうかチェック if((fp=fopen("Capture_Bitmap.bmp","rb"))==NULL){ printf("ファイルが見つかりません"); exit(1); } //BMPファイルか確認 fread(&bfh, 14, 1, fp); //ファイルヘッダ読み込み,ってかファイルヘッダの1~14を読み込む if(memcmp(&bfh.bfType,"BM",2)) //BMPファイルかチェック、2バイト位置にBMがあるか printf("BMPファイルではありません"); fread(&bmpinfo, 40, 1, fp); //情報ヘッダ読み込み printf("データの大きさは%dMB\n",(bmpinfo.biSizeImage+bmpinfo.biSize)/1000000); //表示サイズ調節 //何色BMPファイルか返却値で判定 switch(bmpinfo.biBitCount){ case 1: printf("2色ビットマップ\n"); break; case 4: printf("16色ビットマップ\n"); break; case 8: printf("256色ビットマップ\n"); break; case 24: printf("1677色ビットマップ\n"); break; case 32: printf("1677色ビットマップ\n"); break; } //ココでRGBを抽出する、確かforを二回bmpの縦と横の最大値まで繰り返し、何か変数に入れるソースを見た気が・・・? printf("インターネット ショートカット を起動します。Enterを押してね"); getchar(); //ショトカ起動文。Windows.hでデスクトップにショートカットを指定。 fclose(fp); rewind(stdin); getchar(); }

  • Opencvで質問

     Opencv初心者です。  今日opencvとVC++2010を設定して今練習中なのですが   #include <stdexcept>   #include <opencv/cv.h>   #include <opencv/highgui.h>   int main (int argc, char* argv[]){   const char *fileName = "C:\\Program Files\\OpenCV2.3.1\\samples\\c\\lena.jpg";   const char *windowName = "lena";   ::IplImage* img = ::cvLoadImage(fileName);   ::cvNamedWindow(windowName);   ::cvShowImage(windowName,img);   ::cvWaitKey();   ::cvDestroyWindow(windowName);   ::cvReleaseImage(&img);   }  と言うサンプルをビルドしたら  1>------ ビルド開始: プロジェクト: 画像処理練習, 構成: Debug Win32 ------  1>LINK : fatal error LNK1104: ファイル 'opencv_core231.lib' を開くことができません。  ========== ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ ==========  エラーが出てしまい先に進めません。  もしかしたら他に設定が悪いのでしょうか?  インストールもC:\Program Files\OpenCV2.3.1に名前も変えインストールしました。  ttp://shiotani.cn/20110904vc2010opencv.html  ここを参考にさせていただきました。 よろしくお願いします。