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

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

ただいまの
回答率

89.12%

Zhangのキャリブレーションを行いたい

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 959

nuiri1343

score 54

 前提・実現したいこと

単純なZhangのキャリブレーションを行うプログラムを作っています。

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

findChessboardCornersが成功しません

 該当のソースコード

#include"main.h"


int main(void) {

    const std::string win_src = "Source";
    const std::string win_und = "Undistorted Image";
    const std::string file_cam_param = "cam_param.xml";

    std::vector<Mat> img;
    const int NUM_IMG = 5;
    const Size PAT_SIZE(13, 8);
    float CHESS_SIZE = 37.5;

    std::vector<std::vector<Point3f>> obj_pos(NUM_IMG);
    std::vector<std::vector<Point2f>> img_pos(NUM_IMG);

    TermCriteria criteria(TermCriteria::MAX_ITER | TermCriteria::EPS, 20, 0.001);

    Mat inner;
    Mat distort;
    std::vector<Mat> r_vec;
    std::vector<Mat> t_vec;

    for (int i = 0; i < NUM_IMG; i++) {
        std::string fileName = "./calib_img" + std::to_string(i + 1) + ".jpg";
        img.push_back(imread(fileName));
    }

    for (int i = 0; i < NUM_IMG; i++) {
        for (int j = 0; j < PAT_SIZE.area(); j++) {
            obj_pos[i].push_back(Point3f(static_cast<float>(j%PAT_SIZE.width*CHESS_SIZE), static_cast<float>(j / PAT_SIZE.width*CHESS_SIZE), 0.0));
        }
    }

    for (int i = 0; i < NUM_IMG; i++) {
        std::cout << "calib_img" << i + 1 << ".jpg";
        imshow(win_src, img[i]);
        if (findChessboardCorners(img[i], PAT_SIZE, img_pos[i])) {
            drawChessboardCorners(img[i], PAT_SIZE, img_pos[i], true);
            imshow(win_src, img[i]);
            std::cout << " - siccess" << std::endl;
            waitKey(0);
        }
        else {
            std::cout << " - fail" << std::endl;
            waitKey(0);
            return -1;
        }
    }

    calibrateCamera(obj_pos, img_pos, img[0].size(), inner, distort, r_vec, t_vec);



    Mat extr(4, 4, CV_64F);
    setIdentity(extr);
    Rodrigues(r_vec[0], extr(Rect(0, 0, 3, 3)));
    t_vec[0].copyTo(extr(Rect(3, 0, 1, 3)));

    FileStorage fswrite(file_cam_param, FileStorage::WRITE);
    if (fswrite.isOpened()) {
        fswrite << "extrinsic" << extr;
        fswrite << "intrinsic" << inner;
        fswrite << "distortion" << distort;
    }
    fswrite.release();

    Mat img_undist;
    for (int i = 0; i < NUM_IMG; i++) {
        undistort(img[i], img_undist, inner, distort);
        imshow(win_src, img[i]);
        imshow(win_und, img_undist);
        waitKey(0);
    }

    return 0;



}

 試したこと

以下のような画像を多数用意し、上記のプログラムを実行したのですが、どの画像でも一度もfindChessboardCornersが成功せずfailになってしまいます。
以下の画像は、USBカメラを使用し撮影したカラー画像を、cvtColor(color_img, gray_img, CV_BGR2GRAY)を使用してグレースケール化したものです。
イメージ説明

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

windows10
visualstudio2017
opencv-3.4.2

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 1

checkベストアンサー

0

const Size PAT_SIZE(13, 8);
が間違ってませんか。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/11/18 18:17

    13,9ですか!
    数え間違えていました

    ちなみに、偶数×奇数じゃなければならないというようなことが書いてあるサイトがあったのですが
    それだとこの画像ではできないのですか?

    キャンセル

  • 2018/11/18 18:31 編集

    >偶数×奇数
    についてはわかりません。
    しかし、実際のチェスボードは8マスx8マス(つまり7x7)ですし、
    https://docs.opencv.org/3.4/d9/d0c/group__calib3d.html#ga93efa9b0aa890de240ca32b11253dd4a
    に掲載のサンプルでは8x6を使用しています。
    ```
    Sample usage of detecting and drawing chessboard corners: :
    Size patternsize(8,6); //interior number of corners
    Mat gray = ....; //source image
    vector<Point2f> corners; //this will be filled by the detected corners
    //CALIB_CB_FAST_CHECK saves a lot of time on images
    //that do not contain any chessboard corners
    bool patternfound = findChessboardCorners(gray, patternsize, corners,
    CALIB_CB_ADAPTIVE_THRESH + CALIB_CB_NORMALIZE_IMAGE
    + CALIB_CB_FAST_CHECK);
    ```

    キャンセル

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

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