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

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

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

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

C++

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

解決済

うまく位置推定ができない

amay
amay

総合スコア2

OpenCV

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

C++

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

1回答

0評価

0クリップ

246閲覧

投稿2021/11/11 05:31

編集2021/11/11 07:45

位置測定が実測と全く合わないです。
事前に別のコードからカメラキャリブレーションを行った前提のこーどです。

#define _CRT_SECURE_NO_WARNINGS #include <opencv2/opencv.hpp> #include <iostream> #include <string> #include <sstream> #include <iomanip> #include <opencv2/imgcodecs.hpp> #include <vector> #include <opencv2/imgproc/imgproc.hpp> #.include <random> #include <strstream> //抽出する画像の輝度値の範囲を指定 #define B_MAX 100 #define B_MIN 0 #define G_MAX 100 #define G_MIN 0 #define R_MAX 255 #define R_MIN 100 using namespace cv; using namespace std; /* class StereoMatcher : public Algorithm { public: //返された奥行マップは CV_16UC1 型であり, 要素は実際には //DISP_SHIFT=4 少数ビットの固定小数点である enum { DISP_SHIFT = 4, DISP_SCALE = (1 << DISP_SHIFT) }; //主要なメソッド, 2つのグレースケールの8ビットの平行化された画像を取り, //16ビットの固定小数点数の視差画像を出力する virtual void compute( InputArray left, InputArray right, OutputArray disparity ) = 0; //最小の視差, 通常は0(点は無限遠にある) virtual int getMinDisparity() const = 0; virtual void setMinDisparity(int minDisparity) = 0; //最小値(含む)と最大値(含まない)との間の視差の幅 virtual int getNumDisparities() const = 0; virtual void setNumDisparities(int numDisparities) = 0; //アルゴリズムで使用されるブロックのサイズ virtual int getBlockSize() const = 0; virtual void setBlockSize(int blockSize) = 0; //スペックルとみなされ, そのようにマークされる最大サイズ virtual int getSpeckleWindowSize() const = 0; virtual void setSpeckleWindowSize(int speckleWindowSize) = 0; //近傍ピクセル間の許容される差 //フラッドフィルベースのスペックルフィルタリングアルゴリズムで使用 virtual int getSpeckleRange() const = 0; virtual void setSpeckleRange(int speckleRange) = 0; }; class StereoBM : public cv::StereoMatcher { enum { PREFILTER_NORMALIZED_RESPONSE = 0, PREFILTER_XSOBEL = 1 }; //PREFILTER_NORMALIZED_RESPONSE か PREFILTER_XSOBEL のいずれかを選択 virtual int getPreFilterType() const = 0; virtual void setPreFilterType(int preFilterType) = 0; //PREFILTER_NORMALIZED_RESPONSE モードで使用されるブロックのサイズ virtual int getPreFilterSize() const = 0; virtual void setPreFilterSize(int preFilterSize) = 0; //事前フィルタリング後に適用される飽和しきい値 virtual int getPreFilterCap() const = 0; virtual void setPreFilterCap(int preFilterCap) = 0; //テクスチャのしきい値, テクスチャ特性を有するブロック(微分係数の絶対値の合計)が //このしきい値よりも小さいブロックは, 明確な視差のない領域としてマークされる virtual int getTextureThreshold() const = 0; virtual void setTextureThreshold(int textureThreshold) = 0; //視差範囲にわたってコスト関数に明らかな勝者がない場合, //ピクセルには明確な視差がない. //一意性のしきい値は, どれが「明白な勝者」かを定義し, //最高点と次点の間のマージンを % で定義する virtual int getUniquenessRatio() const = 0; virtual void setUniquenessRatio(int uniquenessRatio) = 0; //コンストラクタ関数, デフォルトの値をもつが, 最初のパラメータは技術的な理由から //実際にはここか, 後で setNumDisparities() を使用して指定するべき static Ptr<StereoBM> create( int numDisparities = 0, int blockSize = 21 ); }; */ int main(void) { Mat left, right; VideoCapture cap1(0); VideoCapture cap2(1); if (!cap1.isOpened()) { cerr << "ERROR! Unable to open camera\n"; return -1; } if (!cap2.isOpened()) { cerr << "ERROR! Unable to open camera\n"; return -1; } //キャリブレーションで求めたパラメーター Mat cam_matrix1, cam_matrix2; Mat dist_matrix1, dist_matrix2; Mat R_calib, T_calib; Mat R1(3, 3, CV_64F); Mat R2(3, 3, CV_64F); Mat P1(3, 4, CV_64F); Mat P2(3, 4, CV_64F); Mat Q; Mat F; Size size = left.size(); Mat left_good, right_good; //並行化後の画像 Mat joint; //左右を結合した画像 //パラメータの読み込み FileStorage fs("C:\Users\yamamura\source\repos\ip\ip\img\camera.xml", FileStorage::READ); if (!fs.isOpened()) { cout << "File can not be opened." << endl; return -1; } cout << "しきい値を入力してください" << endl; int tsd_v; cin >> tsd_v; while (true) { cap1.read(left); cap2.read(right); const int key = waitKey(1); //表示して確認 namedWindow("左"); imshow("左", left); namedWindow("右"); imshow("右", right); //結果保存用Matを定義 Mat maskl, maskr, outl, outr; //inRangeを用いてフィルタリング Scalar s_min = Scalar(B_MIN, G_MIN, R_MIN); Scalar s_max = Scalar(B_MAX, G_MAX, R_MAX); inRange(left, s_min, s_max, maskl); inRange(right, s_min, s_max, maskr); //マスク画像を表示 namedWindow("maskl"); namedWindow("maskr"); imshow("maskl", maskl); imshow("maskr", maskr); //マスクを基に入力画像をフィルタリング left.copyTo(outl, maskl); right.copyTo(outr, maskr); //結果の表示と保存 namedWindow("outl"); namedWindow("outr"); imshow("outl", outl); imshow("outr", outr); Mat binaryl, binaryr; //二値化 threshold(maskl, binaryl, tsd_v, 255, THRESH_BINARY); threshold(maskr, binaryr, tsd_v, 255, THRESH_BINARY); waitKey(1); //画像を平滑化(メディアンフィルタ) int size = 5; UMat dstl, dstr; medianBlur(binaryl, dstl, size); medianBlur(binaryr, dstr, size); imshow("dstl", dstl); imshow("dstr", dstr); /*ビット反転 bitwise_not(dstl, dstl); bitwise_not(dstr, dstr); */ /* //ラベリング Mat labl, labr, statsl, statsr, centerl, centerr; int nlabell = connectedComponentsWithStats(dstl, labl, statsl, centerl); int nlabelr = connectedComponentsWithStats(dstr, labr, statsr, centerr); //ラベリング結果の描画色を決定 vector <Vec3b> colorsl(nlabell); vector <Vec3b> colorsr(nlabelr); colorsl[0] = Vec3b(0, 0, 0); colorsr[0] = Vec3b(0, 0, 0); for (int i = 1; i < nlabell; ++i) { colorsl[i] = Vec3b((rand() & 255), (rand() & 255), (rand() & 255)); } for (int i = 1; i < nlabelr; ++i) { colorsr[i] = Vec3b((rand() & 255), (rand() & 255), (rand() & 255)); } //ラベリング結果の描画 Mat Dstl(dstl.size(), CV_8UC3); Mat Dstr(dstr.size(), CV_8UC3); for (int i = 0; i < Dstl.rows; ++i) { int* lb = labl.ptr<int>(i); Vec3b* pix = Dstl.ptr<Vec3b>(i); for (int j = 0; j < Dstl.cols; ++j) { pix[j] = colorsl[lb[j]]; } } for (int i = 0; i < Dstr.rows; ++i) { int* lb = labr.ptr<int>(i); Vec3b* pix = Dstr.ptr<Vec3b>(i); for (int j = 0; j < Dstr.cols; ++j) { pix[j] = colorsr[lb[j]]; } } //ROIの設定 for (int i = 1; i < nlabell; ++i) { int* param = statsl.ptr<int>(i); int x = param[ConnectedComponentsTypes::CC_STAT_LEFT]; int y = param[ConnectedComponentsTypes::CC_STAT_TOP]; int height = param[ConnectedComponentsTypes::CC_STAT_HEIGHT]; int width = param[ConnectedComponentsTypes::CC_STAT_WIDTH]; rectangle(Dstl, Rect(x, y, width, height), Scalar(0, 255, 0), 2); } for (int i = 1; i < nlabelr; ++i) { int* param = statsr.ptr<int>(i); int x = param[ConnectedComponentsTypes::CC_STAT_LEFT]; int y = param[ConnectedComponentsTypes::CC_STAT_TOP]; int height = param[ConnectedComponentsTypes::CC_STAT_HEIGHT]; int width = param[ConnectedComponentsTypes::CC_STAT_WIDTH]; rectangle(Dstr, Rect(x, y, width, height), Scalar(0, 255, 0), 2); } //重心の出力 for (int i = 1; i < nlabell; ++i) { double* param = centerl.ptr<double>(i); int x1 = static_cast<int>(param[0]); int y1 = static_cast<int>(param[1]); circle(Dstl, Point(x1, y1), 3, Scalar(0, 0, 255), -1); cout << "centerl" << i << "=" << param[4] << endl; } for (int i = 1; i < nlabelr; ++i) { double* param = centerr.ptr<double>(i); int x2 = static_cast<int>(param[0]); int y2 = static_cast<int>(param[1]); circle(Dstr, Point(x2, y2), 3, Scalar(0, 0, 255), -1); cout << "centerr" << i << "=" << param[4] << endl; } //面積値の出力 for (int i = 1; i < nlabell; ++i) { int* param = statsl.ptr<int>(i); int x = param[0]; int y = param[1]; stringstream num; num << i; putText(dstl, num.str(), Point(x + 5, y + 20), FONT_HERSHEY_COMPLEX, 0.7, Scalar(0, 255, 255), 2); } for (int i = 1; i < nlabelr; ++i) { int* param = statsr.ptr<int>(i); int x = param[0]; int y = param[1]; stringstream num; num << i; putText(dstr, num.str(), Point(x + 5, y + 20), FONT_HERSHEY_COMPLEX, 0.7, Scalar(0, 255, 255), 2); } imshow("Dstl", Dstl); imshow("Dstr", Dstr); waitKey(1); */ //重心探索 Moments mom1 = moments(dstl, 1); Point2f pt1 = Point2f(mom1.m10 / mom1.m00, mom1.m01 / mom1.m00); circle(dstl, pt1, 10, Scalar(100), 3, 4); Moments mom2 = moments(dstr, 1); Point2f pt2 = Point2f(mom2.m10 / mom2.m00, mom2.m01 / mom2.m00); circle(dstr, pt2, 10, Scalar(100), 3, 4); imshow("DstL", dstl); imshow("DstR", dstr); waitKey(1); float T = 15; //カメラ間距離 float F = 163.6; //焦点距離 //float Z = 50; //物体距離 //ピクセル誤差 float D = pt1.x - pt2.x; //焦点距離 //float f = Z*D/T; //推定距離 float z = F * T / D; //標準出力 //cout << f << endl; cout << z << endl; waitKey(1); /* for (int i = 0; i < nlabell; i++) { compare(labl, i, dstl, CMP_EQ); imshow("LabelingL", dstl); waitKey(1); } for (int i = 0; i < nlabell; i++) { compare(labr, i, dstr, CMP_EQ); imshow("LabelingR", dstr); waitKey(1); } */ if (key == 'q') { /* imwrite("maskl.jpg", maskl); imwrite("maskr.jpg", maskr); imwrite("outl.jpg", outl); imwrite("outr.jpg", outr); //二値化画像の保存 imwrite("binaryl.jpg", binaryl); imwrite("binaryr.jpg", binaryr); //ラベリング画像の保存 imwrite("labl.jpg", dstl); imwrite("labr.jpg", dstr); */ break; } } return 0; }

良い質問の評価を上げる

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

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

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

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

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

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

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

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

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

y_waiwai

2021/11/11 05:55

このままではコードが読みづらいので、質問を編集し、<code>ボタンを押し、出てくる’’’の枠の中にコードを貼り付けてください
SaitoAtsushi

2021/11/11 06:17

うまくできないというのは具体的にどういう意味ですか? どのような期待をしているところにどのような結果になってしまったのか書きましょう。
jbpb0

2021/11/11 06:20

c++のコードの一番最初の行のすぐ上に ```c++ だけの行を追加してください また、c++のコードの一番最後の行のすぐ下に ``` だけの行を追加してください または、 https://teratail.storage.googleapis.com/uploads/contributed_images/e378967f71829feb9e6187e5be60349f.gif を見て、そのようにしてみてください 現状、コードがとても読み辛いです 質問にコードを載せる際に上記をやってくれたら、他人がコードを読みやすくなり、コードの実行による現象確認もやりやすくなるので、回答されやすくなります
episteme

2021/11/11 07:37

質問になっていない。コードを貼り付けただけ。
fana

2021/11/12 01:28

何故か注釈で StereoMatcher や StereoBM といった型の話が書かれているようですが, この質問においてそれらが無関係であれば,そういった物を無意味に提示コードに含めるべきではありません.

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

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

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

ただいまの回答率
87.20%

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

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

質問する

関連した質問

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

OpenCV

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

C++

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