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

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

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

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

C++

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

Raspberry Pi

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

解決済

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

Spi_muto
Spi_muto

総合スコア75

OpenCV

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

C++

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

Raspberry Pi

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

2回答

0評価

0クリップ

557閲覧

投稿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++

#include "opencv2/opencv.hpp" #include "opencv2/highgui.hpp" #include <vector> #include "mpi.h" using namespace cv; using namespace std; //マウス入力用のパラメータ struct mouseParam { int x; int y; int event; int flags; }; //コールバック関数 void mouse_callback(int eventType, int x, int y, int flags, void* userdata) { mouseParam *ptr = static_cast<mouseParam*> (userdata); ptr->x = x; ptr->y = y; ptr->event = eventType; ptr->flags = flags; } double angle_calc(double x, int azi_ele) //指定された座標とディスプレイ中心の角度計算(azi_eleが1で方位角の計算,0で仰角の計算) { int A = 1; double X; if (azi_ele == 1) { if ((x - 320) < 0) { A = -1; } X = (x - 320) / 3.04e+03; //分母はカメラの焦点距離 } else { if ((x - 240) > 0) { A = -1; } X = (x - 240) / 3.04e+03; } double ang = A * acos(1/sqrt(X * X + 1)) * 180 / 2 * M_PI; return ang; } vector<vector<Point> > contours; //輪郭 vector<Vec4i> hierarchy; int main(int argc, char *argv[]) { int rank, procs; double Angle_data[2]; MPI_Status status; MPI_Request request; MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &procs); VideoCapture cap(0); // USBカメラのオープン if (!cap.isOpened()) //カメラが起動できなかった時のエラー処理 { return -1; } Mat frame, gray_img1, gray_img2, gray_img3, diff1, diff2, diff;; CascadeClassifier cascade; cascade.load("../opencv_build/opencv-4.2.0/data/haarcascades/haarcascade_frontalface_alt.xml"); vector<Rect> faces; vector<vector<double>> ears(2, vector<double>(2)); //耳の位置情報格納場所 vector<int> selects; //選択した顔の番号 int select_flag = 0; vector<int> x; vector<int> y; vector<int> x_end; vector<int> y_end; Rect fgRect; //選択した顔の枠情報 int min_x, min_y, max_x, max_y; //モーション検出のx,yの最小値最大値 mouseParam mouseEvent; cap >> frame; //1フレームの画像の読み込み(グレー化) cv::cvtColor(frame, gray_img1, cv::COLOR_BGR2GRAY); cap >> frame; //2フレームの画像の読み込み(グレー化) cv::cvtColor(frame, gray_img2, cv::COLOR_BGR2GRAY); // capture >> frame; //3フレームの画像の読み込み(グレー化) // cv::cvtColor(frame, gray_img3, cv::COLOR_BGR2GRAY); //cout << endl << "z: ズームイン" << endl << "x: ズームアウト" << endl; cout << endl << "s: スクリーンショット" << endl; cout << "q: 終了" << endl; while (cap.read(frame)) { //3フレームの画像の読み込み(グレー化) cv::cvtColor(frame, gray_img3, cv::COLOR_BGR2GRAY); //差分1:フレーム1と2の差を求める cv::absdiff(gray_img1, gray_img2, diff1); //差分2:フレーム2と3の差を求める cv::absdiff(gray_img2, gray_img3, diff2); //差分1と差分2の結果を比較(論理積)し、diffに出力 cv::bitwise_and(diff1, diff2, diff); //表示 // cv::imshow("diff image", diff); //画像を1frameずらす gray_img2.copyTo(gray_img1, gray_img2); gray_img3.copyTo(gray_img2, gray_img3); //格納されたフレームに対してカスケードファイルに基づいて顔を検知 cascade.detectMultiScale(frame, faces, 1.2, 5, 0, Size(20, 20)); //顔を検出した場合 if (faces.size() > 0) { x.resize(faces.size()); y.resize(faces.size()); x_end.resize(faces.size()); y_end.resize(faces.size()); selects.resize(faces.size()); for (int i = 0; i < faces.size(); i++) { //顔座標の左上の座標 x[i] = faces[i].x; y[i] = faces[i].y; //顔座標の右下の座標を求める x_end[i] = x[i] + faces[i].width; y_end[i] = y[i] + faces[i].height; rectangle(frame, Point(x[i], y[i]), Point(x_end[i], y_end[i]), Scalar(0, 0, 255), 3); //選択されていたら色付け if (selects[i] == 1) { Mat roi = frame(Rect(Point(x[i], y[i]), Point(x_end[i], y_end[i]))); Mat color(roi.size(), CV_8UC3, Scalar(150, 100, 0)); double alpha = 0.3; cv::addWeighted(color, alpha, roi, 1.0 - alpha , 0.0, roi); } //マウスカーソルが枠内に入ったら色付け if (mouseEvent.x > x[i] && mouseEvent.x < x_end[i] && mouseEvent.y > y[i] && mouseEvent.y < y_end[i]) { Mat roi = frame(Rect(Point(x[i], y[i]), Point(x_end[i], y_end[i]))); Mat color(roi.size(), CV_8UC3, Scalar(0, 125, 125)); //黄色 double alpha = 0.3; addWeighted(color, alpha, roi, 1.0 - alpha , 0.0, roi); //アルファブレンドで枠内を塗りつぶし } if (select_flag == 1) { int RL; if (x[i] - 50 < 0) { RL = x[i]; } else if (x_end[i] + 50 > frame.cols) { RL = frame.cols - x_end[i]; } else { RL = 50; } //選択した顔の追尾範囲 fgRect = Rect(Point(x[i] - RL, y[i] - 50), Point(x_end[i] + RL, y_end[i] + 50)); //顔付近(余計なものを検出しない, 動きが速いとついていけない) //fgRect = Rect(Point(0, y[i] - 50), Point(frame.cols, y_end[i] + 50)); //顔のあるy座標+-50(顔の位置をしっかり追尾できる, 余計なものも検出してしまう) } } //選択されている顔の耳の位置情報 for (int i = 0; i < faces.size(); i++) { if (selects[i] == 1) { system("clear"); cout << "ear_R = " << "{" << x[i] << ", " << y_end[i] - (faces[i].height / 2) << "}" << endl; cout << "ear_L = " << "{" << x_end[i] << ", " << y_end[i] - (faces[i].height / 2) << "}" << endl; cout << "方位角(右耳): " << angle_calc(x[i], 1) << "°" << endl; cout << "仰角(右耳): " << angle_calc(y_end[i] - (faces[i].height / 2), 0) << "°" << endl; Angle_data[0] = x[i]; Angle_data[1] = y_end[i] - (faces[i].height / 2); } } } //顔が選択されて見切れたら追尾モード(一人だけ) else if (select_flag == 1) { Mat motion_frame = diff(fgRect); //8ビットのバイナリイメージを取り込みその輪郭(contours:点のベクトル)を出力 findContours(motion_frame, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point(0, 0)); vector<Rect> boundRect(contours.size()); vector<vector<Point>> contours_poly(contours.size()); for (int i = 0; i < contours.size();i++) { if(contourArea(contours[i])< 500) //面積500以下のものは無視 { continue; } //いくつかの折れ線(contours_poly)である程度性格に輪郭(contours)を囲む,第三引数は元の曲線と近似曲線の最大距離 approxPolyDP(contours[i], contours_poly[i], 3, true); //折れ線(contours_poly)を囲む領域の最小の大きさ(boundRect)を計算 boundRect[i] = boundingRect(contours_poly[i]); rectangle(frame(fgRect), boundRect[i].tl(), boundRect[i].br(), Scalar(0, 0, 255), 3); //追尾している顔 Mat roi = frame(Rect(boundRect[i].x + fgRect.x, boundRect[i].y + fgRect.y, boundRect[i].width, boundRect[i].height)); Mat color(roi.size(), CV_8UC3, Scalar(150, 100, 0)); //青 double alpha = 0.3; addWeighted(color, alpha, roi, 1.0 - alpha , 0.0, roi); } //多数決で検出範囲をずらす方向を決める int rl = 0, ud = 0; for (int i = 0; i < boundRect.size(); i++) { if (boundRect[i].width > 0) { if (boundRect[i].x < fgRect.width - (boundRect[i].x + boundRect[i].width)) { rl -= 1; } else if (boundRect[i].x > fgRect.width - (boundRect[i].x + boundRect[i].width)) { rl += 1; } } } if (rl > 0) { rl = 50; if (fgRect.x + fgRect.width + rl > frame.cols - 1) { rl = frame.cols - (fgRect.x + fgRect.width); } } else if (rl < 0) { rl = -50; if (fgRect.x - rl < 1) { rl = -fgRect.x; } } else { rl = 0; } //追尾範囲の更新(検出した枠で多数決でどちらに動かすか) fgRect.x += rl; //fgRect.y += ud; //選択されている顔の位置情報 system("clear"); cout << "chase_face = " << "{" << fgRect.x + fgRect.width / 2 << ", " << fgRect.y + fgRect.height / 2 << "}" << endl; cout << "方位角: " << angle_calc(fgRect.x + fgRect.width / 2, 1) << "°" << endl; cout << "仰角: " << angle_calc(fgRect.y + fgRect.height / 2, 0) << "°" << endl; Angle_data[0] = fgRect.x + fgRect.width / 2; Angle_data[1] = fgRect.y + fgRect.height / 2; } //else if (select_flag == 1) else { selects.clear(); } MPI_Isend(&Angle_data, 2, MPI_DOUBLE, 1, 99, MPI_COMM_WORLD, &request); imshow("camera", frame);//画像を表示. setMouseCallback("camera", mouse_callback, &mouseEvent); const int key = cv::waitKey(1); if (mouseEvent.event == EVENT_LBUTTONDOWN) { system("clear"); //マウスの座標出力 cout << "(x, y) = " << "(" << mouseEvent.x << ", " << mouseEvent.y << ")" << endl; cout << "方位角: " << angle_calc(mouseEvent.x, 1) << "°" << endl; cout << "仰角:  " << angle_calc(mouseEvent.y, 0) << "°" << endl; for (int i = 0; i < faces.size(); i++) { if (mouseEvent.x > x[i] && mouseEvent.x < x_end[i] && mouseEvent.y > y[i] && mouseEvent.y < y_end[i]) { if (selects[i] == 0) { select_flag = 1; selects[i] = 1; fgRect = Rect(Point(x[i] - 50, y[i] - 50), Point(x_end[i] + 50, y_end[i] + 50)); //選択した顔の枠情報 } else { select_flag = 0; selects[i] = 0; } } else { //選択した顔枠外をクリックすると選択解除 if (select_flag == 1) { select_flag = 0; selects[i] = 0; } } } if (!(mouseEvent.x > fgRect.x && mouseEvent.x < fgRect.x + fgRect.width && mouseEvent.y > fgRect.y && mouseEvent.y < fgRect.y + fgRect.height)) { //選択した顔枠外をクリックすると選択解除 if (select_flag == 1) { select_flag = 0; selects; } } } //qボタンが押されたとき else if(key == 'q') { break; } } //while (cap.read(frame)) destroyAllWindows(); MPI_Finalize(); return 0; }

良い質問の評価を上げる

以下のような質問は評価を上げましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

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

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

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

teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

  • プログラミングに関係のない質問
  • やってほしいことだけを記載した丸投げの質問
  • 問題・課題が含まれていない質問
  • 意図的に内容が抹消された質問
  • 過去に投稿した質問と同じ内容の質問
  • 広告と受け取られるような投稿

評価を下げると、トップページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

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

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

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

ただいまの回答率
87.20%

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

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

質問する

関連した質問

同じタグがついた質問を見る

OpenCV

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

C++

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

Raspberry Pi

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