位置測定が実測と全く合わないです。
事前に別のコードからカメラキャリブレーションを行った前提のこーどです。
#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; }
このままではコードが読みづらいので、質問を編集し、<code>ボタンを押し、出てくる’’’の枠の中にコードを貼り付けてください
うまくできないというのは具体的にどういう意味ですか?
どのような期待をしているところにどのような結果になってしまったのか書きましょう。
c++のコードの一番最初の行のすぐ上に
```c++
だけの行を追加してください
また、c++のコードの一番最後の行のすぐ下に
```
だけの行を追加してください
または、
https://teratail.storage.googleapis.com/uploads/contributed_images/e378967f71829feb9e6187e5be60349f.gif
を見て、そのようにしてみてください
現状、コードがとても読み辛いです
質問にコードを載せる際に上記をやってくれたら、他人がコードを読みやすくなり、コードの実行による現象確認もやりやすくなるので、回答されやすくなります
質問になっていない。コードを貼り付けただけ。
何故か注釈で StereoMatcher や StereoBM といった型の話が書かれているようですが,
この質問においてそれらが無関係であれば,そういった物を無意味に提示コードに含めるべきではありません.
回答1件
あなたの回答
tips
プレビュー