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

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

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

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

C++

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

Q&A

解決済

1回答

1352閲覧

std::vectorの扱い方

Spi_muto

総合スコア75

OpenCV

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

C++

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

0グッド

0クリップ

投稿2021/09/02 06:49

前提・実現したいこと

カメラから映像を取得して、そこから顔認識をし認識した顔に枠をつけるというプログラムを作成しています。
プログラム自体は動くのですが、終了させたときにエラーが出てしまいます。

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

corrupted size vs. prev_size 中止

該当のソースコード

c++

1//opencvでの顔認識 2//マウスの座標取得,ビーム照射方向計算 3//複数顔へのマーク 4 5//プログラム終了したときにエラー出る"corrupted size vs. prev_size" 6 7 8#include "opencv2/opencv.hpp" 9#include "opencv2/highgui.hpp" 10#include <vector> 11 12using namespace cv; 13using namespace std; 14 15 16//コールバック関数 17void mouse_callback(int event, int x, int y, int flags, void *userdata) 18{ 19 if (event == EVENT_LBUTTONDOWN) { 20 21 int Ax = 1, Ay = 1; 22 23 if ((x - 320) < 0) { 24 Ax = -1; 25 } 26 if ((y - 240) > 0) { 27 Ay = -1; 28 } 29 30 double X = (x - 320) / 3.04e+03; 31 double Y = (y - 240) / 3.04e+03; 32 33 system("clear"); 34 35 //マウスの座標出力 36 cout << "(x, y) = " << "(" << x << ", " << y << ")" << endl; 37 cout << "方位角: " << Ax * acos(1/sqrt(X * X + 1)) * 180 / 2 * M_PI << "°" << endl; 38 cout << "仰角:  " << Ay * acos(1/sqrt(Y * Y + 1)) * 180 / 2 * M_PI << "°" << endl; 39 //cout << endl << "z: ズームイン" << endl << "x: ズームアウト" << endl; 40 cout << endl << "s: スクリーンショット" << endl; 41 cout << "q: 終了" << endl; 42 43 } 44} 45 46 47int main() 48{ 49 VideoCapture cap(0); // USBカメラのオープン 50 if (!cap.isOpened()) //カメラが起動できなかった時のエラー処理 51 { 52 return -1; 53 } 54 55 Mat frame; //USBカメラから得た1フレームを格納する場所 56 CascadeClassifier cascade; //カスケード分類器格納場所 57 cascade.load("../opencv_build/opencv-4.2.0/data/haarcascades/haarcascade_frontalface_alt.xml"); //正面顔情報が入っているカスケード 58 vector<Rect> faces; //輪郭情報を格納場所 59 60 std::vector<int> x = {0};//顔座標の左上のx座標 61 std::vector<int> y = {0};//顔座標の左上のy座標 62 std::vector<int> x_end = {0};//顔座標の右下のx座標 63 std::vector<int> y_end = {0};//顔座標の右下のy座標 64 65 66 while (cap.read(frame)) 67 { 68 69 //格納されたフレームに対してカスケードファイルに基づいて顔を検知 70 cascade.detectMultiScale(frame, faces, 1.2, 5, 0, Size(20, 20)); 71 72 73 //顔を検出した場合 74 if (faces.size() > 0) { 75 76 for (int i = 0; i < faces.size(); i++) { 77 //顔座標の左上の座標 78 x[i] = faces[i].x; 79 y[i] = faces[i].y; 80 81 //顔座標の右下の座標を求める 82 x_end[i] = x[i] + faces[i].width; 83 y_end[i] = y[i] + faces[i].height; 84 85 rectangle(frame, Point(x[i], y[i]), Point(x_end[i], y_end[i]), Scalar(0, 0, 255), 3); 86 87 } 88 89 } 90 91 92 imshow("camera", frame);//画像を表示. 93 94 setMouseCallback("camera", mouse_callback); 95 96 const int key = cv::waitKey(1); 97 98 // //zでズームイン 99 // if (key == 'z') { 100 // zoom += zoomRate; 101 // } 102 // //xでズームアウト 103 // else if (key == 'x') { 104 // zoom -= zoomRate; 105 // if(zoom < 1) zoom = 1; 106 // } 107 //sボタンでスクリーンショット 108 if (key == 's') { 109 std::string name; 110 111 std::cout << "file name?" << endl; 112 std::getline(std::cin, name); 113 114 cv::imwrite(name, frame); 115 } 116 //qボタンが押されたとき 117 else if(key == 'q') { 118 break; 119 } 120 } 121 122 destroyAllWindows(); 123 124 return 0; 125} 126

試したこと

vectorの宣言のところで

std::vector<int> x;//顔座標の左上のx座標

としたところ、segmentation faltになった。

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

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

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

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

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

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

guest

回答1

0

ベストアンサー

std::vector<int> x = {0};

これだとサイズ1.

std::vector<int> x;

こっちだとサイズ0.
いずれにせよ,

x[i] = faces[i].x;

とかして,iがサイズを超えた個所になってたらまずいでしょ.

投稿2021/09/02 06:53

fana

総合スコア11652

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

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

Spi_muto

2021/09/02 06:55

どう宣言すればいいのでしょうか?
fana

2021/09/02 06:58

std::vector というのは, 例えば x[5] = 何か; とか書けば勝手にそれに見合うサイズに変化してくれるわけではないよ. 後からサイズを変更「できる」のであって,変更するのはあなたの役目.
fana

2021/09/02 07:04

今回の話で言えば,顔検出処理が顔をいくつ検出してくるかはわからないから,「事前にサイズをいくつにしておけば十分か?」というのは定められないハズ. (「顔が1万個あります」とかいう結果があり得るかもしれないのだし) なので,「顔検出結果の個数」が判明した段階で,4つの(xとかyとかいう)vectorのサイズを変更してやればよいのではないかと.resizeとかで. #そもそも faces から4個のvectorに値をコピーする必要があるのか?といった話は脇に置いておくとして.
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問