質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

OpenCV

OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。

Q&A

0回答

1023閲覧

キャプチャ画像が取得できない

ShiiTakumi

総合スコア15

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

OpenCV

OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。

0グッド

0クリップ

投稿2018/11/28 04:37

「OpenCVプログラミングブック 第2版 OpenCV1.1対応」掲載サンプルを実行しながら画像処理について勉強しています。

現在、USB接続Webカメラによるライブ映像のキャプチャができなくて詰んでおります。
サンプルを実行してみるとwebカメラはちゃんと発見されているのですが、出現したウィンドウは真っ暗のままです。
画像が取得されているかどうか検証したところ「NULL」が返っており、ずっと取得出来ていない状態でした。
しかしARToolKit関係のサンプルではカメラは問題無く動作しておりました。

これはいったいどういうことなのでしょうか。
ネット検索したところwebカメラ性能に問題がありそうですが、どう対処すればよいのでしょうか。

ご教授いただければ幸いです。

(VisualStudio2017使用)
以下、掲載サンプル(s48/rockpaperscissors.cpp)に少し修正したコードです。
修正箇所:frameImageがNULLかどうかを追記

C

1//--------------------------------------------------------- 2// 概要 : ジャンケンの判定 3// File Name : rockpaperscissors.cpp 4// Library : OpenCV 1.1 5//--------------------------------------------------------- 6 7#include "rockpaperscissors.h" 8 9char windowNameCapture[] = "Capture"; // キャプチャした画像を表示するウィンドウの名前 10char windowNameSkin[] = "Skin"; // 肌色抽出画像を表示するウィンドウの名前 11char windowNameConvexHull[] = "ConvexHull"; // ConnvexHull画像を表示するウィンドウの名前 12 13// 14// ウィンドウを作成する 15// 16void createWindows() { 17 cvNamedWindow( windowNameCapture ); 18 cvNamedWindow( windowNameSkin ); 19 cvNamedWindow( windowNameConvexHull ); 20} 21 22// 23// 肌色を抽出する 24// 25// 引数: 26// frameImage : キャプチャした画像用IplImage 27// hsvImage : HSV画像用IplImage 28// skinImage : 肌色抽出画像用IplImage 29// 30void extractSkinColor( IplImage *frameImage, IplImage *hsvImage, IplImage *skinImage ) { 31 CvScalar color; // HSV表色系で表した色 32 unsigned char h; // H成分 33 unsigned char s; // S成分 34 unsigned char v; // V成分 35 36 // BGRからHSVに変換する 37 cvCvtColor( frameImage, hsvImage, CV_BGR2HSV ); 38 39 //肌色抽出 40 for( int x = 0; x < skinImage->width; x++ ) { 41 for( int y = 0 ; y < skinImage->height; y++ ) { 42 43 color = cvGet2D( hsvImage, y, x ); 44 h = color.val[0]; 45 s = color.val[1]; 46 v = color.val[2]; 47 48 if( h <= HMAX && h >= HMIN && 49 s <= SMAX && s >= SMIN && 50 v <= VMAX && v >= VMIN ) { 51 // 肌色の場合 52 cvSetReal2D( skinImage, y, x, 255 ); 53 } else { 54 cvSetReal2D( skinImage, y, x, 0 ); 55 } 56 } 57 } 58} 59 60// 61// 欠損領域を補間する 62// 63// 引数: 64// skinImage : 肌色抽出画像用IplImage 65// temp : 一時保存用IplImage 66// 67void interpolate( IplImage *skinImage, IplImage *temp ) { 68 //膨張をITERATIONS回行う 69 cvDilate( skinImage, temp, NULL, ITERATIONS ); 70 71 //収縮をITERATIONS回行う 72 cvErode( temp, skinImage, NULL, ITERATIONS ); 73} 74 75// 76// 最大領域(手領域)の抽出を行う 77// 78// 引数: 79// skinImage : 肌色抽出画像用IplImage 80// label : ラベリングした結果 81// convexHullImage : ConvexHull画像用IplImage 82// 83// 戻り値: 84// 手領域の面積 85// 86int pickupMaxArea(IplImage *skinImage, IplImage *label, IplImage *convexHullImage ) { 87 88 int handarea = 0; // 手領域の面積 89 90 for(int x = 0; x < skinImage->width; x++ ) { 91 for( int y=0; y < skinImage->height; y++ ) { 92 if( cvGetReal2D( label, y, x ) == 1 ) { 93 // 最大領域だった場合 94 handarea++; 95 cvSet2D( convexHullImage, y, x, CV_RGB( 255, 255, 255 ) ); 96 } else { 97 cvSetReal2D( skinImage, y, x, 0 ); 98 cvSet2D( convexHullImage, y, x, CV_RGB( 0, 0, 0 ) ); 99 } 100 } 101 } 102 return handarea; 103} 104 105// 106// ConvexHullを生成する 107// 108// 引数: 109// skinImage : 肌色抽出画像用IplImage 110// handarea : 手領域の面積(点の数) 111// handpoint : 手領域内の点の座標配列へのポインタ 112// hull : ConvexHullの頂点のhandpointにおけるindex番号へのポインタ 113// pointMatrix : 手領域用行列へのポインタ 114// hullMatrix : ConvexHull用行列へのポインタ 115// 116void createConvexHull(IplImage *skinImage, int handarea, CvPoint **handpoint, int **hull, 117 CvMat *pointMatrix, CvMat *hullMatrix ) { 118 int i=0; 119 120 // ConvexHullを計算するために必要な行列を生成する 121 *handpoint=( CvPoint * )malloc( sizeof( CvPoint ) * handarea ); 122 *hull = ( int * )malloc( sizeof( int ) * handarea ); 123 *pointMatrix = cvMat( 1, handarea, CV_32SC2, *handpoint ); 124 *hullMatrix = cvMat( 1, handarea, CV_32SC1, *hull ); 125 126 for( int x = 0; x < skinImage->width; x++ ) { 127 for( int y = 0; y < skinImage->height; y++ ) { 128 if( cvGetReal2D( skinImage, y, x ) == 255 ) { 129 ( *handpoint )[i].x = x; 130 ( *handpoint )[i].y = y; 131 i++; 132 } 133 } 134 } 135 136 // ConvexHullを生成する 137 cvConvexHull2( pointMatrix, hullMatrix, CV_CLOCKWISE, 0 ); 138} 139 140// 141// ConvexHullを描画する 142// 143// 引数: 144// convexHullImage : ConvexHull画像用IplImage 145// handpoint : 手領域内の点の座標配列 146// hull : ConvexHullの頂点のhandpointにおけるindex番号 147// hullcount : ConvexHullの頂点の数 148// 149void drawConvexHull(IplImage *convexHullImage, CvPoint *handpoint, int *hull, int hullcount ) { 150 CvPoint pt0 = handpoint[hull[hullcount-1]]; 151 for( int i = 0; i < hullcount; i++ ) { 152 CvPoint pt = handpoint[hull[i]]; 153 cvLine( convexHullImage, pt0, pt, CV_RGB( 0, 255, 0 ) ); 154 pt0 = pt; 155 } 156} 157 158// 159// ConvexHull内の面積を求める 160// 161// 引数: 162// convexHullImage : ConvexHull画像用IplImage 163// handpoint : 手領域内の点の座標配列 164// hull : ConvexHullの頂点のhandpointにおけるindex番号 165// hullcount : ConvexHullの頂点の数   166// 167// 戻り値: 168// ConvexHull内の面積 169// 170int calcConvexHullArea( IplImage *convexHullImage, CvPoint *handpoint, int *hull, int hullcount ) { 171 172 // ConvexHullの頂点からなる行列を生成 173 CvPoint *hullpoint = ( CvPoint * )malloc( sizeof( CvPoint ) * hullcount ); 174 CvMat hMatrix = cvMat( 1, hullcount, CV_32SC2, hullpoint ); 175 for( int i = 0; i < hullcount; i++ ) { 176 hullpoint[i]=handpoint[hull[i]]; 177 } 178 179 // ConvexHull内の点の数を数える 180 int hullarea = 0; 181 for( int x = 0; x < convexHullImage->width; x++ ) { 182 for( int y = 0;y < convexHullImage->height; y++ ) { 183 if( cvPointPolygonTest( &hMatrix, cvPoint2D32f( x, y ), 0 ) > 0) { 184 hullarea++; 185 } 186 } 187 } 188 189 free( hullpoint ); 190 return hullarea; 191} 192 193// 194// ジャンケンの判定を行う 195// 196// 引数: 197// handarea : 手領域の面積 198// hullarea : ConvexHull内の面積 199// 200void decide( int handarea, int hullarea ) { 201 double ratio; // ConvexHull内の面積に対する手領域の面積の割合 202 203 ratio=handarea / ( double )hullarea; 204 printf( "Ratio = %lf\n", ratio ); 205 206 if( ratio >= ROCKMIN && ratio <= ROCKMAX ) { 207 printf( "グー\n" ); 208 } else if( ratio >= SCISSORMIN && ratio <= SCISSORMAX ) { 209 printf( "チョキ\n" ); 210 } else if( ratio >= PAPERMIN && ratio <= PAPERMAX ) { 211 printf( "パー\n" ); 212 } 213} 214 215int main( int argc, char **argv ) { 216 int key; // キー入力用の変数 217 CvCapture *capture = NULL; // カメラキャプチャ用の構造体 218 219 // カメラを初期化する 220 if( ( capture = cvCreateCameraCapture( CV_CAP_ANY ) ) == NULL ) { 221 // カメラが見つからなかった場合 222 printf( "カメラが見つかりません\n" ); 223 return -1; 224 } 225 double w = 640, h = 480; 226 cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, w); 227 cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, h); 228 229 230 IplImage *frameImage = cvQueryFrame( capture ); // キャプチャ画像用IplImage 231 232 if (frameImage == NULL) { 233 printf("キャプチャに失敗しました。\n"); 234 } 235 236 IplImage *hsvImage; 237 IplImage *convexHullImage; 238 IplImage *skinImage; 239 IplImage *temp; 240 IplImage *label; 241 242 // 画像を生成する 243 hsvImage = cvCreateImage( cvGetSize( frameImage ),IPL_DEPTH_8U,3); // HSV画像用IplImage 244 convexHullImage = cvCreateImage( cvGetSize( frameImage ),IPL_DEPTH_8U,3 );// ConvexHull画像用IplImage 245 skinImage = cvCreateImage( cvGetSize( frameImage ),IPL_DEPTH_8U,1); // 肌色抽出画像用IplImage 246 temp = cvCreateImage( cvGetSize( frameImage ),IPL_DEPTH_8U,1); // 一時保存用IplImage 247 label = cvCreateImage( cvGetSize( frameImage ),IPL_DEPTH_16S,1); // ラベル結果保存用IplImage 248 249 // ウィンドウを生成する 250 createWindows(); 251 252 while( 1 ){ 253 254 frameImage = cvQueryFrame( capture ); 255 256 // 肌色を抽出する 257 extractSkinColor( frameImage, hsvImage, skinImage ); 258 259 // 欠損領域を補間する 260 interpolate( skinImage, temp ); 261 262 // ラベリングを行う 263 Label *labeling = createLabeling(); 264 exec( labeling, skinImage, label, true, IGNORE_SIZE ); 265 266 if( getNumOfResultRegions( labeling ) > 0 ) { 267 // IGNORE_SIZEよりも大きな領域があった場合 268 269 int handarea; // 手領域の面積 270 int hullarea; // ConvexHull内の面積 271 int hullcount; // ConvexHullの頂点の数 272 CvPoint *handpoint; // 手領域内の点の座標配列 273 int *hull; // ConvexHullの頂点のhandpointにおけるindex番号 274 CvMat pointMatrix; // 手領域用行列 275 CvMat hullMatrix; // ConvexHull用行列 276 277 // 最大領域(手領域)の抽出を行う 278 handarea = pickupMaxArea( skinImage, label, convexHullImage ); 279 280 // ConvexHullを生成する 281 createConvexHull( skinImage, handarea, &handpoint, &hull, &pointMatrix, &hullMatrix ); 282 283 hullcount = hullMatrix.cols; 284 285 // ConvexHullを描画する 286 drawConvexHull( convexHullImage, handpoint, hull, hullcount ); 287 288 // ConvexHull内の面積を求める 289 hullarea = calcConvexHullArea( convexHullImage, handpoint,hull, hullcount ); 290 291 // ジャンケンの判定を行う 292 decide( handarea, hullarea ); 293 294 // メモリを解放する 295 free( handpoint ); 296 free( hull ); 297 } else { 298 // 画像を初期化する 299 cvSetZero( convexHullImage ); 300 } 301 302 releaseLabeling( labeling ); 303 304 //if ( skinImage->origin == 0 ) { 305 // // 左上が原点の場合 306 // cvFlip( skinImage, skinImage, 0 ); 307 //} 308 //if ( convexHullImage->origin == 0 ) { 309 // // 左上が原点の場合 310 // ( convexHullImage, convexHullImage, 0 ); 311 //} 312 313 // 画像を表示する 314 cvShowImage( windowNameCapture, frameImage ); 315 cvShowImage( windowNameSkin, skinImage ); 316 cvShowImage( windowNameConvexHull, convexHullImage ); 317 318 // キー入力判定 319 key = cvWaitKey( 10 ); 320 if( key == 'q' ) { 321 // 'q'キーが押されたらループを抜ける 322 break; 323 } 324 } 325 326 // キャプチャを解放する 327 cvReleaseCapture( &capture ); 328 // メモリを解放する 329 cvReleaseImage( &hsvImage ); 330 cvReleaseImage( &skinImage ); 331 cvReleaseImage( &temp ); 332 cvReleaseImage( &label ); 333 cvReleaseImage( &convexHullImage ); 334 // ウィンドウを破棄する 335 cvDestroyWindow( windowNameCapture ); 336 cvDestroyWindow( windowNameSkin ); 337 cvDestroyWindow( windowNameConvexHull ); 338 339 return 0; 340}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tiitoi

2018/11/28 04:55

OpenCV1は10年以上前のものですけど、なぜ古いバージョンを使っているのでしょうか? 今からつくるのであれば、OpenCV 3 に対応した書籍を買って勉強したほうがよいです。 IplImage、cvCreateImage 等は deprecated で OpenCV 4 からは削除されているので、勉強しても無駄になってしまう可能性があります。
ShiiTakumi

2018/11/28 05:07

ということは1.1のサンプルは遊べないのでしょうか。OpenCV4から削除されているのは初めて知りました、、、教えていただきありがとうございます。
tiitoi

2018/11/28 05:13 編集

その書籍が出た当時の OpenCV 1.1 を導入すれば動くとは思いますが、今の OpenCV 3 を入れて書籍のプログラムを動かそうとしているのだとしたら、当時からは API 等一部変わったりしているので動かない可能性もあります。(実際に確認したわけではないですが)
tiitoi

2018/11/28 05:14 編集

古いバージョン OpenCV を使わなければならない特殊な事情があるなら別ですが、そうでなく持っている書籍がたまたま OpenCV 1 のものだったからという理由であれば、その書籍で勉強するのではなく、OpenCV 3 に対応した書籍を購入されたほうがよいです。理由は上記 API は今は非推奨で OpenCV3までは互換性保持のためまだ残っていますが、今後のバージョンで削除されるからです。
ShiiTakumi

2018/11/28 05:17

遊びたいサンプルがあっただだで、特殊な事情はございません(;^ω^)手元には全てのバージョンがありますので、書籍については心配ございません。アドバイスありがとうございます。また、 OpenCV 1.1を導入してサンプルを実行しているのですが、投稿通りでダメでした。もうあきらめようかなと思っているところです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問