c++
1#include <opencv2/opencv.hpp> 2#include <iostream> 3 4using namespace std; 5using namespace cv; 6 7int main(int argc, char *argv[]){ 8 //カメラの設定 9 VideoCapture cap(0); // 環境に応じて0や1を入れる 10 if(!cap.isOpened()){ 11 cout << "Camera not Found!" << endl; 12 return -1; 13 } 14 // 取り込む画像サイズの指定 15 cap.set(CV_CAP_PROP_FRAME_HEIGHT, 480); 16 cap.set(CV_CAP_PROP_FRAME_WIDTH, 640); 17 18 // ムービーの読み込み 19 cv::VideoCapture movie("/Users/k16105kk/Desktop/じゃんけんアプリ/videos/janken.mp4"); 20 if(!movie.isOpened()){ 21 cout << "Movie not found!" << endl; 22 return -1; 23 } 24 25 Mat frame, src, hsv, skin; 26 27 while(true){ 28 // sキーが押されるまで待機 29 while(true) { 30 cap >> src; 31 imshow("camera", src); 32 int key = waitKey(33) % 256; 33 if (key == 's') break; 34 if (key == 'q') return -1; 35 } 36 // ムービーの再生 37 movie.set(CV_CAP_PROP_POS_FRAMES, 0); 38 while(true) { 39 movie >> frame; 40 if (frame.empty()) break; 41 imshow("movie", frame); 42 imshow("camera", src); 43 waitKey(33); // 30fpsなので 44 } 45 46 int hand; 47 if(hand == 0) 48 frame = imread("rock.png"); 49 else if(hand == 1) 50 frame = imread("paper.png"); 51 else 52 frame = imread("scissors.png"); 53 imshow("movie", frame); 54 waitKey(1000); 55 56 // 10フレームの平均で判定 57 int fingerCount = 0; 58 for (int loop=0; loop<10; ++loop) { 59 // カメラ画像の取り込み 60 cap >> src; 61 // HSV色空間への変換 62 cvtColor(src, hsv, CV_BGR2HSV); 63 // 肌色部分の抜き出し 64 inRange(hsv, Scalar(0, 20, 20), Scalar(25, 255, 255), skin); 65 66 // 抜き出した部分をなめらかにする 67 Mat structElem = getStructuringElement(MORPH_RECT, Size(3, 3)); 68 morphologyEx(skin, skin, MORPH_CLOSE, structElem); 69 70 // 一番長い輪郭線を選ぶ 71 vector<vector<Point> > contours; 72 vector<Vec4i> hierarchy; 73 findContours(skin, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE); 74 75 double largestArea = 0.0; 76 int largestContourIndex = 0; 77 for(int i=0; i<contours.size(); ++i){ 78 double a = contourArea(contours[i], false); 79 if(a > largestArea){ 80 largestArea = a; 81 largestContourIndex = i; 82 } 83 } 84 85 // 欠落部分を求める 86 vector<vector<int> > hulls (1); 87 convexHull(contours[largestContourIndex], hulls[0], false, false); 88 std::vector<Vec4i> defects; 89 convexityDefects(contours[largestContourIndex], hulls[0], defects); 90 91 // 小さいものや離れすぎているものを除いて指の数を数える 92 for (int i = 0; i< defects.size(); i++){ 93 int start_index = defects[i][0]; 94 CvPoint start_point = contours[largestContourIndex][start_index]; 95 int end_index = defects[i][1]; 96 CvPoint end_point = contours[largestContourIndex][end_index]; 97 double d1 = (end_point.x - start_point.x); 98 double d2 = (end_point.y - start_point.y); 99 double distance = sqrt((d1*d1)+(d2*d2)); 100 int depth = defects[i][3]/1000; 101 102 if (depth > 10 && distance > 2.0 && distance < 200.0){ 103 fingerCount++; 104 } 105 } 106 } 107 108 // 指の数に応じてcpの手を決定する 109 int status; 110 cout << fingerCount << endl; 111 // 自分がグー 112 if (fingerCount < 20){ 113 cout << "グー" << endl; 114 frame = imread("paper.png"); 115 } 116 // 自分がチョキ 117 else if (fingerCount <= 45) { 118 cout << "チョキ" << endl; 119 frame = imread("rock.png"); 120 } 121 // 自分がパー 122 else { 123 cout << "パー" << endl; 124 frame = imread("scissors.png"); 125 } 126 } 127}
プログラミング初心者のものです。
今、PCのカメラに手を写してじゃんけんの「手」を認識し、その手に必ず勝つ手をCPが出力するというプログラムを作成しています。上記のコードをコンパイルすると動画が再生された後、「予期せぬ理由で終了しました。」と表示されるとともにアプリが終了してしまいます。何がおかしいのかわからないので投稿させていただきました。理想としては手を認識するまで動画を繰り返し再生し、認識した時最後の方の行の処理を実行させたいです。説明不足でレベルの低い質問かもしれませんがどなたかご教授願います。
開発環境
macOS:High Sierra10.13.4
ATOM:1.28.0
openCV:3.4.2 このような感じです。情報不足で申し訳ないです。
開発環境は何をご利用ですか?デバッガを利用することで、どの部分がおかしいは把握できるかと思いますし、デバッグ方法を理解しないと、一つ一つつまづくたびに誰かに頼らないと作れないことになりそうです。
あなたの回答
tips
プレビュー