前提・実現したいこと
カメラで取得した映像で顔認識をし、検出した顔の位置座標を別のプログラムに送り標準出力したい。
発生している問題・エラーメッセージ
mpirun detected that one or more processes exited with non-zero status, thus causing the job to be terminated.
該当のソースコード
カメラの映像から顔認識して顔の位置座標を送信するプログラム
c++
1#include "opencv2/opencv.hpp" 2#include "opencv2/highgui.hpp" 3#include <vector> 4#include "mpi.h" 5 6using namespace cv; 7using namespace std; 8 9 10//マウス入力用のパラメータ 11struct mouseParam { 12 int x; 13 int y; 14 int event; 15 int flags; 16}; 17 18 19//コールバック関数 20void mouse_callback(int eventType, int x, int y, int flags, void* userdata) 21{ 22 mouseParam *ptr = static_cast<mouseParam*> (userdata); 23 24 ptr->x = x; 25 ptr->y = y; 26 ptr->event = eventType; 27 ptr->flags = flags; 28} 29 30 31double angle_calc(double x, int azi_ele) //指定された座標とディスプレイ中心の角度計算(azi_eleが1で方位角の計算,0で仰角の計算) 32{ 33 int A = 1; 34 double X; 35 36 if (azi_ele == 1) { 37 if ((x - 320) < 0) { 38 A = -1; 39 } 40 X = (x - 320) / 3.04e+03; //分母はカメラの焦点距離 41 } 42 else { 43 if ((x - 240) > 0) { 44 A = -1; 45 } 46 X = (x - 240) / 3.04e+03; 47 } 48 49 double ang = A * acos(1/sqrt(X * X + 1)) * 180 / 2 * M_PI; 50 51 return ang; 52} 53 54 55vector<vector<Point> > contours; //輪郭 56vector<Vec4i> hierarchy; 57 58int main(int argc, char *argv[]) 59{ 60 int rank, procs; 61 double Angle_data[2]; 62 MPI_Status status; 63 MPI_Request request; 64 65 MPI_Init(&argc, &argv); 66 MPI_Comm_rank(MPI_COMM_WORLD, &rank); 67 MPI_Comm_size(MPI_COMM_WORLD, &procs); 68 69 VideoCapture cap(0); // USBカメラのオープン 70 if (!cap.isOpened()) //カメラが起動できなかった時のエラー処理 71 { 72 return -1; 73 } 74 75 Mat frame, gray_img1, gray_img2, gray_img3, diff1, diff2, diff;; 76 CascadeClassifier cascade; 77 cascade.load("../opencv_build/opencv-4.2.0/data/haarcascades/haarcascade_frontalface_alt.xml"); 78 79 vector<Rect> faces; 80 vector<vector<double>> ears(2, vector<double>(2)); //耳の位置情報格納場所 81 vector<int> selects; //選択した顔の番号 82 83 int select_flag = 0; 84 85 vector<int> x; 86 vector<int> y; 87 vector<int> x_end; 88 vector<int> y_end; 89 90 Rect fgRect; //選択した顔の枠情報 91 92 int min_x, min_y, max_x, max_y; //モーション検出のx,yの最小値最大値 93 94 mouseParam mouseEvent; 95 96 97 cap >> frame; //1フレームの画像の読み込み(グレー化) 98 cv::cvtColor(frame, gray_img1, cv::COLOR_BGR2GRAY); 99 cap >> frame; //2フレームの画像の読み込み(グレー化) 100 cv::cvtColor(frame, gray_img2, cv::COLOR_BGR2GRAY); 101 // capture >> frame; //3フレームの画像の読み込み(グレー化) 102 // cv::cvtColor(frame, gray_img3, cv::COLOR_BGR2GRAY); 103 104 //cout << endl << "z: ズームイン" << endl << "x: ズームアウト" << endl; 105 cout << endl << "s: スクリーンショット" << endl; 106 cout << "q: 終了" << endl; 107 108 109 while (cap.read(frame)) 110 { 111 //3フレームの画像の読み込み(グレー化) 112 cv::cvtColor(frame, gray_img3, cv::COLOR_BGR2GRAY); 113 114 //差分1:フレーム1と2の差を求める 115 cv::absdiff(gray_img1, gray_img2, diff1); 116 //差分2:フレーム2と3の差を求める 117 cv::absdiff(gray_img2, gray_img3, diff2); 118 //差分1と差分2の結果を比較(論理積)し、diffに出力 119 cv::bitwise_and(diff1, diff2, diff); 120 121 //表示 122 // cv::imshow("diff image", diff); 123 124 //画像を1frameずらす 125 gray_img2.copyTo(gray_img1, gray_img2); 126 gray_img3.copyTo(gray_img2, gray_img3); 127 128 129 //格納されたフレームに対してカスケードファイルに基づいて顔を検知 130 cascade.detectMultiScale(frame, faces, 1.2, 5, 0, Size(20, 20)); 131 132 133 //顔を検出した場合 134 if (faces.size() > 0) { 135 136 x.resize(faces.size()); 137 y.resize(faces.size()); 138 x_end.resize(faces.size()); 139 y_end.resize(faces.size()); 140 selects.resize(faces.size()); 141 142 for (int i = 0; i < faces.size(); i++) { 143 //顔座標の左上の座標 144 x[i] = faces[i].x; 145 y[i] = faces[i].y; 146 147 //顔座標の右下の座標を求める 148 x_end[i] = x[i] + faces[i].width; 149 y_end[i] = y[i] + faces[i].height; 150 151 rectangle(frame, Point(x[i], y[i]), Point(x_end[i], y_end[i]), Scalar(0, 0, 255), 3); 152 153 //選択されていたら色付け 154 if (selects[i] == 1) { 155 Mat roi = frame(Rect(Point(x[i], y[i]), Point(x_end[i], y_end[i]))); 156 Mat color(roi.size(), CV_8UC3, Scalar(150, 100, 0)); 157 double alpha = 0.3; 158 cv::addWeighted(color, alpha, roi, 1.0 - alpha , 0.0, roi); 159 } 160 161 //マウスカーソルが枠内に入ったら色付け 162 if (mouseEvent.x > x[i] && mouseEvent.x < x_end[i] && mouseEvent.y > y[i] && mouseEvent.y < y_end[i]) { 163 Mat roi = frame(Rect(Point(x[i], y[i]), Point(x_end[i], y_end[i]))); 164 Mat color(roi.size(), CV_8UC3, Scalar(0, 125, 125)); //黄色 165 double alpha = 0.3; 166 addWeighted(color, alpha, roi, 1.0 - alpha , 0.0, roi); //アルファブレンドで枠内を塗りつぶし 167 } 168 169 if (select_flag == 1) { 170 int RL; 171 172 if (x[i] - 50 < 0) { 173 RL = x[i]; 174 } 175 else if (x_end[i] + 50 > frame.cols) { 176 RL = frame.cols - x_end[i]; 177 } 178 else { 179 RL = 50; 180 } 181 //選択した顔の追尾範囲 182 fgRect = Rect(Point(x[i] - RL, y[i] - 50), Point(x_end[i] + RL, y_end[i] + 50)); //顔付近(余計なものを検出しない, 動きが速いとついていけない) 183 //fgRect = Rect(Point(0, y[i] - 50), Point(frame.cols, y_end[i] + 50)); //顔のあるy座標+-50(顔の位置をしっかり追尾できる, 余計なものも検出してしまう) 184 } 185 } 186 //選択されている顔の耳の位置情報 187 for (int i = 0; i < faces.size(); i++) { 188 if (selects[i] == 1) { 189 system("clear"); 190 cout << "ear_R = " << "{" << x[i] << ", " << y_end[i] - (faces[i].height / 2) << "}" << endl; 191 cout << "ear_L = " << "{" << x_end[i] << ", " << y_end[i] - (faces[i].height / 2) << "}" << endl; 192 cout << "方位角(右耳): " << angle_calc(x[i], 1) << "°" << endl; 193 cout << "仰角(右耳): " << angle_calc(y_end[i] - (faces[i].height / 2), 0) << "°" << endl; 194 195 Angle_data[0] = x[i]; 196 Angle_data[1] = y_end[i] - (faces[i].height / 2); 197 } 198 } 199 } 200 //顔が選択されて見切れたら追尾モード(一人だけ) 201 else if (select_flag == 1) { 202 Mat motion_frame = diff(fgRect); 203 //8ビットのバイナリイメージを取り込みその輪郭(contours:点のベクトル)を出力 204 findContours(motion_frame, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point(0, 0)); 205 206 vector<Rect> boundRect(contours.size()); 207 vector<vector<Point>> contours_poly(contours.size()); 208 209 for (int i = 0; i < contours.size();i++) { 210 if(contourArea(contours[i])< 500) //面積500以下のものは無視 211 { 212 continue; 213 } 214 //いくつかの折れ線(contours_poly)である程度性格に輪郭(contours)を囲む,第三引数は元の曲線と近似曲線の最大距離 215 approxPolyDP(contours[i], contours_poly[i], 3, true); 216 //折れ線(contours_poly)を囲む領域の最小の大きさ(boundRect)を計算 217 boundRect[i] = boundingRect(contours_poly[i]); 218 rectangle(frame(fgRect), boundRect[i].tl(), boundRect[i].br(), Scalar(0, 0, 255), 3); //追尾している顔 219 Mat roi = frame(Rect(boundRect[i].x + fgRect.x, boundRect[i].y + fgRect.y, boundRect[i].width, boundRect[i].height)); 220 Mat color(roi.size(), CV_8UC3, Scalar(150, 100, 0)); //青 221 double alpha = 0.3; 222 addWeighted(color, alpha, roi, 1.0 - alpha , 0.0, roi); 223 } 224 225 //多数決で検出範囲をずらす方向を決める 226 int rl = 0, ud = 0; 227 228 for (int i = 0; i < boundRect.size(); i++) { 229 if (boundRect[i].width > 0) { 230 if (boundRect[i].x < fgRect.width - (boundRect[i].x + boundRect[i].width)) { 231 rl -= 1; 232 } 233 else if (boundRect[i].x > fgRect.width - (boundRect[i].x + boundRect[i].width)) { 234 rl += 1; 235 } 236 } 237 } 238 239 if (rl > 0) { 240 rl = 50; 241 if (fgRect.x + fgRect.width + rl > frame.cols - 1) { 242 rl = frame.cols - (fgRect.x + fgRect.width); 243 } 244 } 245 else if (rl < 0) { 246 rl = -50; 247 if (fgRect.x - rl < 1) { 248 rl = -fgRect.x; 249 } 250 } 251 else { 252 rl = 0; 253 } 254 //追尾範囲の更新(検出した枠で多数決でどちらに動かすか) 255 fgRect.x += rl; 256 //fgRect.y += ud; 257 258 //選択されている顔の位置情報 259 system("clear"); 260 cout << "chase_face = " << "{" << fgRect.x + fgRect.width / 2 << ", " << fgRect.y + fgRect.height / 2 << "}" << endl; 261 cout << "方位角: " << angle_calc(fgRect.x + fgRect.width / 2, 1) << "°" << endl; 262 cout << "仰角: " << angle_calc(fgRect.y + fgRect.height / 2, 0) << "°" << endl; 263 264 Angle_data[0] = fgRect.x + fgRect.width / 2; 265 Angle_data[1] = fgRect.y + fgRect.height / 2; 266 267 } //else if (select_flag == 1) 268 else { 269 selects.clear(); 270 } 271 272 MPI_Isend(&Angle_data, 2, MPI_DOUBLE, 1, 99, MPI_COMM_WORLD, &request); 273 274 imshow("camera", frame);//画像を表示. 275 276 setMouseCallback("camera", mouse_callback, &mouseEvent); 277 278 const int key = cv::waitKey(1); 279 280 if (mouseEvent.event == EVENT_LBUTTONDOWN) { 281 282 system("clear"); 283 284 //マウスの座標出力 285 cout << "(x, y) = " << "(" << mouseEvent.x << ", " << mouseEvent.y << ")" << endl; 286 cout << "方位角: " << angle_calc(mouseEvent.x, 1) << "°" << endl; 287 cout << "仰角: " << angle_calc(mouseEvent.y, 0) << "°" << endl; 288 289 290 for (int i = 0; i < faces.size(); i++) { 291 if (mouseEvent.x > x[i] && mouseEvent.x < x_end[i] && mouseEvent.y > y[i] && mouseEvent.y < y_end[i]) { 292 if (selects[i] == 0) { 293 select_flag = 1; 294 selects[i] = 1; 295 fgRect = Rect(Point(x[i] - 50, y[i] - 50), Point(x_end[i] + 50, y_end[i] + 50)); //選択した顔の枠情報 296 } 297 else { 298 select_flag = 0; 299 selects[i] = 0; 300 } 301 } 302 else { //選択した顔枠外をクリックすると選択解除 303 if (select_flag == 1) { 304 select_flag = 0; 305 selects[i] = 0; 306 } 307 } 308 } 309 if (!(mouseEvent.x > fgRect.x && mouseEvent.x < fgRect.x + fgRect.width && mouseEvent.y > fgRect.y && mouseEvent.y < fgRect.y + fgRect.height)) { //選択した顔枠外をクリックすると選択解除 310 if (select_flag == 1) { 311 select_flag = 0; 312 selects; 313 } 314 } 315 } 316 //qボタンが押されたとき 317 else if(key == 'q') { 318 break; 319 } 320 } //while (cap.read(frame)) 321 322 destroyAllWindows(); 323 MPI_Finalize(); 324 325 return 0; 326}
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。