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

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

ただいまの
回答率

89.85%

C++ VisualStudio2017 OpenCV3.2.0で一時停止標識を検出できない

受付中

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 1,491

ksmiki

score 4

前提・実現したいこと

OpenCVでカメラからのとまれの一時停止標識を検出しようと思っています
VisualStudioに全く触ったことがなく、Linux上で開発していました。
初心者で分かりません。

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

63行目のtargets.size()で"18446743988082066159"という大きな値が出てきます。
この後のfor文で多く回ってしまうことでウィンドウが表示されないのだと思います。

該当のソースコード

#include <iostream> // for standard I/O
#include <string>   // for strings
#include <iomanip>  // for controlling float print precision
#include <sstream>  // string to number conversion
#include <stdlib.h>
#include <vector>

#include <opencv2/core/core.hpp>        // Basic OpenCV structures (cv::Mat, Scalar)
#include <opencv2/imgproc/imgproc.hpp>  // Gaussian Blur
#include <opencv2/highgui/highgui.hpp>  // OpenCV window I/O
#include <opencv2/objdetect/objdetect.hpp>
#include <opencv2/videoio/videoio.hpp>

#define _TRIANGLETESTMAIN

using namespace cv;
//using namespace std;

static void showUsage(const char *cmd)
{
    std::cerr << cmd << ": [-h] imageFilename trainFilename" << std::endl;
    std::cerr << "         -n: do not open display windows" << std::endl;
}

int main(void)
{
    Mat frame;


    VideoCapture cap(0);
    if (!cap.isOpened()) {
        std::cerr << "Cannot open camera." << std::endl;
        return 1;
    }
    namedWindow("Output", WINDOW_AUTOSIZE);
    CascadeClassifier clsf;
    try {
        clsf.load("001/cascade.xml");
    }
    catch (Exception& e) {
        const char* err_msg = e.what();
        std::cout << err_msg << std::endl;
    }
    if (clsf.empty()) {
        std::cerr << "cannot load cascade file" << std::endl;
        exit(-1);
    }
    std::vector<Rect> targets;
    while (1) {
        cap >> frame;
        clsf.detectMultiScale(frame, targets);
        if (clsf.empty()) {
            std::cerr << "cannot load cascade file" << std::endl;
            exit(-1);
        }
        else {
            std::cout << "read" << std::endl;
        }
        std::cout << targets.size() << std::endl;
        for (int i = 0; i < targets.size(); i++) {
            rectangle(frame, Rect(targets[i].x, targets[i].y, targets[i].width, targets[i].height), Scalar(255, 0, 0), 2);
        }
        imshow("Output", frame);
        char c = (char)waitKey(10);
        if (c == 'q') {
            break;
        }
    }
endOfMovie:
    destroyWindow("Output");
    return 0;
}

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

環境 
CMakeでOpenCVインストールしました。
opencv3.2
visual studio2017
プロパティ 
C/C++ 
追加のインクルードディレクトリ C:\opencv-3.2.0\build\install\include; 
リンカー 
追加のライブラリディレクトリ C:\opencv-3.2.0\build\install\x64\vc15\lib 
追加依存ファイル 追加のライブラリディレクトリにあるものはすべて追加しました。 

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

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

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

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

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

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

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

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

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

0

素人意見ですが、たとえばtargets.size()が100を超えていたらループを100回までにして無理やり先に進めてみて、出てきた矩形はちゃんと標識の位置を示しているでしょうか?
使っている分類器(001/cascade.xml)は自作されたものですかね?これが狂っているとか...?カメラのキャプチャ像でなく、何か別の画像なら正しく検出できますでしょうか。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/06/21 11:22

    100は難しいですが、5にした場合、いろいろなところに矩形矩形ができていました。
    一時停止標識を見せるとそこに集中しているような感じです。
    デバッグのあと
    xutility internal headerに以下のようなものができていました。
    0x00007FF77B474BCD で例外がスローされました (stopdetector.exe 内): 0xC0000005: 場所 0x0000005B0000005B への書き込み中にアクセス違反が発生しました

    また、別の画像で試したところ一時停止標識を囲む矩形ができていました。
    ただ以下が表示されました。
    0x00007FFF5D4D0BDD (ntdll.dll) で例外がスローされました (stopdetector.exe 内): 0xC0000005: 場所 0x0000007900000081 への書き込み中にアクセス違反が発生しました

    キャンセル

  • 2017/06/21 12:08

    標識周辺で大量の矩形が発生してしまう...となると、http://workpiles.com/2015/04/opencv-detectmultiscale-minneighbors/http://workpiles.com/2015/04/opencv-detectmultiscale-scalefactor/で紹介されているような感じでdetectMultiScaleの引数を調整してみて、不要な検出を排除できないですかね?特にminNeighborsあたりを上げてみて、信頼度の高い部分のみを抽出させるとどうなるでしょうか。

    キャンセル

  • 2017/06/25 01:11

    minNeighborsを調整してみたところ、確かに矩形の個数は変わります。
    しかし、同じcascadeファイルでOpenCVがインストールされているUbuntuの場合targets.size()で表示される数はせいぜい多くても2個くらいで矩形もその個数だけできます。
    同じcppファイルを用いて、ここまで違うのはおかしな気がするんです。
    試しに、Windows上でcascadeファイルを作ってみても結果は同じです。
    根本的な原因と解決策が見出せません...

    キャンセル

  • 2017/06/25 05:45

    もしかするとOpenCLによるGPUアクセラレーションの有無によるのかもしれません。このあたりが両環境でどうなっているか確認してみてはいかがでしょう。
    https://github.com/opencv/opencv/issues/6693https://github.com/opencv/opencv/issues/7189を見ますと、どうもCPU版とGPU版に関数実装の差異があったり、あるいはどちらもGPU版であってもグラフィックスカードの設定が異なるマシン上では違う結果になりうる?ようなコメントがあり、その辺の事情が関係あるのかもしれません。しかしここまで差が出るものなんでしょうかね?すみませんがいまいち判断しかねます...

    キャンセル

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

  • ただいまの回答率 89.85%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる