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

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

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

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

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Raspberry Pi

Raspberry Piは、ラズベリーパイ財団が開発した、名刺サイズのLinuxコンピュータです。 学校で基本的なコンピュータ科学の教育を促進することを意図しています。

Q&A

解決済

2回答

1685閲覧

OpenMPIによるプログラム間でのデータ送受信

Spi_muto

総合スコア75

OpenCV

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

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Raspberry Pi

Raspberry Piは、ラズベリーパイ財団が開発した、名刺サイズのLinuxコンピュータです。 学校で基本的なコンピュータ科学の教育を促進することを意図しています。

0グッド

0クリップ

投稿2021/10/10 05:43

編集2021/10/10 05:44

前提・実現したいこと

カメラで取得した映像で顔認識をし、検出した顔の位置座標を別のプログラムに送り標準出力したい。

発生している問題・エラーメッセージ

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}

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

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

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

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

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

guest

回答2

0

自己解決

MPI_Isend, MPI_Irecv

MPI_Send, MPI_Recv

に変えたらうまく動きました。

投稿2021/10/11 08:18

Spi_muto

総合スコア75

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

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

0

こちらが顔の位置座標を受け取るプログラムです

#include <stdio.h> #include "mpi.h" //#include <time.h> int main(int argc, char **argv) { int rank, procs; double Angle_data[2], azimuth = 0, elevation = 0; MPI_Status status; MPI_Request request; MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &procs); bool loop = true; while(1) { int flag = 1; MPI_Irecv(Angle_data, 2, MPI_DOUBLE, 0, 99, MPI_COMM_WORLD, &request); MPI_Test(&request, &flag, &status); if (azimuth != Angle_data[0] || elevation != Angle_data[1]) { azimuth = Angle_data[0]; elevation = Angle_data[1]; printf("Recv\tazi = %.2f, ele = %.2f\n", azimuth, elevation); } } MPI_Finalize(); return 0; }

投稿2021/10/10 05:45

Spi_muto

総合スコア75

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問