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

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

ただいまの
回答率

90.45%

  • C++

    4552questions

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

  • OpenCV

    1572questions

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

  • Leap Motion

    33questions

    Leap Motionは、Leap Motionによって開発、販売している、手のジェスチャーでパソコンを操作できるデバイスです。

opencvを用いてcv::Vec3bの型で画像を加工した後 グレースケールに変換してからラベリングを行いたいのですがエラーが出てしまいます.

受付中

回答 0

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 2,331

bigbosssemd

score 2

前提・実現したいこと

opencvを用いてcv::Vec3bの型で画像を加工した後
グレースケールに変換してからラベリングを行いたいのですがエラーが出てしまいます.
connectedComponentsWithStatsの行で例外が生じます.
自分は変換する型があっていないと考えています.

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

Unhandled exception at 0x76D84878 in this.exe: Microsoft C++ exception: cv::Exception at memory location 0x00E9EB10.

該当のソースコード

#include <Leap.h>
#include <opencv2\opencv.hpp>
#include <opencv\cv.h>
#include <opencv2\highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <stdio.h>

cv::Mat warp(Leap::Image image) {
    cv::Mat_<cv::Vec3b> out(cv::Size(640, 480));

    const cv::Mat_<unsigned char> cvImage = cv::Mat(image.height(), image.width(), CV_8UC1, image.dataPointer());

    out.forEach([&](cv::Vec3b& pixel, const int pos[])-> void {
        float y = (float)pos[0] / out.rows;
        float x = (float)(pos[1] - 120) / out.rows;

        const Leap::Vector v(
            (x - image.rayOffsetX()) / image.rayScaleX() / 4 * 2,

            (y - image.rayOffsetY()) / image.rayScaleY() / 4 * 2,
            0);

        const auto warped = image.warp(v);

        if (warped.x > 0 && warped.x < (cvImage.cols - 1)
            && warped.y > 0 && warped.y < (cvImage.rows - 1)) {
            // std::cout << warped << std::endl;
            pixel = cv::Vec3b::all(cvImage(warped.y, warped.x));
        }
        else {
            pixel = cv::Vec3b(255, 255, 255);
        }
    });

    return out;
}

int main()
{
    Leap::Controller controller;
    controller.setPolicy(Leap::Controller::POLICY_IMAGES);
    controller.setPolicy(Leap::Controller::POLICY_BACKGROUND_FRAMES);

    while (cv::waitKey(1) != 'q') {
        const auto frame = controller.frame();
        if (!frame.isValid()) {
            std::cout << "Frame is Invalid" << std::endl;
            continue;
        }

        const auto imageList = frame.images();

        if (imageList.isEmpty()) {
            std::cout << "imageList.isEmpty()" << std::endl;
            continue;
        }




        /*歪み補正ゾーン*/



        const auto cvImageR = warp(imageList[0]);
        const auto cvImageL = warp(imageList[1]);

        /*歪み補正ゾーン終わり*/


        cvImageR.convertTo(cvImageR, CV_8UC1);
        cvImageL.convertTo(cvImageL, CV_8UC1);








        /*二値化ゾーン*/

        cv::Mat img_thresholdL;
        cv::threshold(cvImageL, img_thresholdL, 200, 255, CV_THRESH_BINARY);
        cv::Mat img_thresholdR;
        cv::threshold(cvImageR, img_thresholdR, 200, 255, CV_THRESH_BINARY);

        /*二値化ゾーン終わり*/


        /************************************/
        /*        ラベリングゾーン            */
        /************************************/
        int im = 0;
        for (im = 0; im < 2; im++){

            cv::Mat stats;        //面積値らしい
            cv::Mat centroids;  //重心


                // ラベル用画像生成(※CV_32S or CV_16Uにする必要あり)
            cv::Mat labelImage;// labelImage(img_thresholdL.size(), CV_32S);

            if (im == 0){

                cv::Mat labelImage(img_thresholdL.size(), CV_32S);        //左の画像のラベリング
            }
            if (im == 1){

                cv::Mat labelImage(img_thresholdR.size(), CV_32S);        //右の画像のラベリング
            }

            // ラベリング実行.戻り値がラベル数.また,このサンプルでは8近傍でラベリングする.
            //int nLabels = cv::connectedComponents(img_thresholdL, labelImage, 8);
            //int nLabels = cv::connectedComponentsWithStats(img_thresholdL, labelImage, stats, centroids);

            int nLabels;

            if (im == 0){
                nLabels = cv::connectedComponentsWithStats(img_thresholdL, labelImage, stats, centroids);        //左の画像
            }
            if (im == 1){
                nLabels = cv::connectedComponentsWithStats(img_thresholdR, labelImage, stats, centroids);        //右の画像
            }



            // ラベリング結果の描画色を決定
            std::vector<cv::Vec3b> colors(nLabels);
            colors[0] = cv::Vec3b(0, 0, 0);


            int mc = 0,lb = 0; //面積のでかいやつの面積値とラベル番号
            for (int label = 1; label < nLabels; ++label)
            {
                colors[label] = cv::Vec3b((rand() & 255), (rand() & 255), (rand() & 255));

                int *param = stats.ptr<int>(label);
                std::cout <<"image"<< im << " area " << label << " = " << param[cv::ConnectedComponentsTypes::CC_STAT_AREA] << std::endl;

                if (mc < param[cv::ConnectedComponentsTypes::CC_STAT_AREA]){
                    mc = param[cv::ConnectedComponentsTypes::CC_STAT_AREA];                
                    lb = label;                                                    //面積の大きいラベルの番号を保持
                }

            }

            // ラベリング結果の描画
            cv::Mat dst(img_thresholdL.size(), CV_8UC3);
            for (int y = 0; y < dst.rows; ++y)
            {
                for (int x = 0; x < dst.cols; ++x)
                {
                    int label = labelImage.at<int>(y, x);
                    cv::Vec3b &pixel = dst.at<cv::Vec3b>(y, x);
                    pixel = colors[label];
                }
            }


            //重心を赤点で表示
            for (int i = 1; i < nLabels; ++i) {
                double *param = centroids.ptr<double>(i);        //中心座標的な
                int x = static_cast<int>(param[0]);
                int y = static_cast<int>(param[1]);

                cv::circle(dst, cv::Point(x, y), 2, cv::Scalar(0, 0, 255), -1);

                std::cout << "image" << im << " x "  << " = " << x << std::endl;
                std::cout << "image" << im << " y " << " = " << y << std::endl;
            }

            char X[1000], Y[1000];
            double *param = centroids.ptr<double>(lb);
            int x = static_cast<int>(param[0]);
            int y = static_cast<int>(param[1]);

            sprintf_s(X, "%d", x);
            sprintf_s(Y, "%d", y);


            cv::putText(dst, X, cv::Point(50, 50), cv::FONT_HERSHEY_SIMPLEX, 1.2, cv::Scalar(200, 200, 200), 2, CV_AA);
            cv::putText(dst, Y, cv::Point(50, 100), cv::FONT_HERSHEY_SIMPLEX, 1.2, cv::Scalar(200, 200, 200), 2, CV_AA);


            if (im == 0){
                cv::namedWindow("二値化&ラベリングL", cv::WINDOW_AUTOSIZE);
                cv::imshow("二値化&ラベリングL", dst);
            }
            if (im == 1){
                cv::namedWindow("二値化&ラベリングR", cv::WINDOW_AUTOSIZE);
                cv::imshow("二値化&ラベリングR", dst);
            }


        }


        /************************************/
        /*  ラベリングゾーン終わり        */
        /***********************************/








        //cv::adaptiveThreshold(cvImageL, cvImageL, 0,1,0,7,0);

        /*生画像表示ゾーン*/

        cv::imshow("CvimageL", cvImageL);
        cv::imshow("CvimageR", cvImageR);


        /*生画像表示ゾーン*/

        /*cv::imshow("歪み改善後imageL", imageL);
        cv::imshow("歪み改善後imageR", imageR);*/
        cv::imshow("2値L", img_thresholdL);
        cv::imshow("2値R", img_thresholdR);


    }

    return 0;
}

試したこと

opencvのグレースケールに変換する関数やCV_8UC1に変換しましたがエラーが出ました.

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

visualstdioc++ 2013
leapmotion v2
leapmotion sdk

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

質問への追記・修正の依頼

  • haru666

    2016/12/16 15:30

    どこで例外が出ているかを明記しましょう。それから、コードは```で括ってください。タブ文字の使用はやめてスペースを使ってインデントしたものを貼り付けてください。

    キャンセル

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

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

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

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

  • C++

    4552questions

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

  • OpenCV

    1572questions

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

  • Leap Motion

    33questions

    Leap Motionは、Leap Motionによって開発、販売している、手のジェスチャーでパソコンを操作できるデバイスです。

  • トップ
  • C++に関する質問
  • opencvを用いてcv::Vec3bの型で画像を加工した後 グレースケールに変換してからラベリングを行いたいのですがエラーが出てしまいます.