デプスマップの取得

アラム・ゲボルギャン

視差から通常の深度マップを取得できません。これが私のコードです:

#include "opencv2/core/core.hpp"
#include "opencv2/calib3d/calib3d.hpp"
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include "opencv2/contrib/contrib.hpp"
#include <cstdio>
#include <iostream>
#include <fstream>

using namespace cv;
using namespace std;

ofstream out("points.txt");

int main()
{
    Mat img1, img2;
    img1 = imread("images/im7rect.bmp");
    img2 = imread("images/im8rect.bmp");

    //resize(img1, img1, Size(320, 280));
    //resize(img2, img2, Size(320, 280));

    Mat g1,g2, disp, disp8;
    cvtColor(img1, g1, CV_BGR2GRAY);
    cvtColor(img2, g2, CV_BGR2GRAY);

    int sadSize = 3;
    StereoSGBM sbm;
    sbm.SADWindowSize = sadSize;
    sbm.numberOfDisparities = 144;//144; 128
    sbm.preFilterCap = 10; //63
    sbm.minDisparity = 0; //-39; 0
    sbm.uniquenessRatio = 10;
    sbm.speckleWindowSize = 100;
    sbm.speckleRange = 32;
    sbm.disp12MaxDiff = 1;
    sbm.fullDP = true;
    sbm.P1 = sadSize*sadSize*4;
    sbm.P2 = sadSize*sadSize*32;
    sbm(g1, g2, disp);

    normalize(disp, disp8, 0, 255, CV_MINMAX, CV_8U);

    Mat dispSGBMscale; 
    disp.convertTo(dispSGBMscale,CV_32F, 1./16); 

    imshow("image", img1);

    imshow("disparity", disp8);

    Mat Q;
    FileStorage fs("Q.txt", FileStorage::READ);
    fs["Q"] >> Q;
    fs.release();

    Mat points, points1;
    //reprojectImageTo3D(disp, points, Q, true);
    reprojectImageTo3D(disp, points, Q, false, CV_32F);
    imshow("points", points);

    ofstream point_cloud_file;
    point_cloud_file.open ("point_cloud.xyz");
    for(int i = 0; i < points.rows; i++) {
        for(int j = 0; j < points.cols; j++) {
            Vec3f point = points.at<Vec3f>(i,j);
            if(point[2] < 10) {
                point_cloud_file << point[0] << " " << point[1] << " " << point[2]
                    << " " << static_cast<unsigned>(img1.at<uchar>(i,j)) << " " << static_cast<unsigned>(img1.at<uchar>(i,j)) << " " << static_cast<unsigned>(img1.at<uchar>(i,j)) << endl;
            }
        }
    }
    point_cloud_file.close(); 

    waitKey(0);

    return 0;
}

私の画像は次のとおりです。

ここに画像の説明を入力してください ここに画像の説明を入力してください

視差マップ:

ここに画像の説明を入力してください

私はこの点群のようにsmthを取得します: ここに画像の説明を入力してください

Qは等しい:[1.、0.、0。、-3.2883545303344727e + 02、0。、1.、0。、-2.3697290992736816e + 02、0。、0.、0.、5.4497170185417110e + 02、0 。、0。、-1.4446083962336606e-02、0。]

私は他の多くのことを試みました。別の画像で試してみましたが、通常の深度マップを取得できません。

What am I doing wrong? Should I do with reprojectImageTo3D or use other approach instead of it? What is the best way to vizualize depth map? (I tried point_cloud library) Or could you provide me the working example with dataset and calibration info, that I could run it and get depth map. Or how can I get depth_map from middlebury stereo database (http://vision.middlebury.edu/stereo/data/), I think there isn't enough calibration info.

Edited: Now I get smth like : ここに画像の説明を入力してください

It is of course better, but still not normal.

Edited2: I tried what you say:

Mat disp;
disp = imread("disparity-image.pgm", CV_LOAD_IMAGE_GRAYSCALE);

Mat disp64; 
disp.convertTo(disp64,CV_64F, 1.0/16.0); 
imshow("disp", disp);

I get this result with line cv::minMaxIdx(...) : ここに画像の説明を入力してください

And this when I comment this line: ここに画像の説明を入力してください

Ps: Also please could you tell me how can I calculate depth knowing only baseline and focal length in pixels.

Kornel

OpenCVreprojectImageTo3D()と自分のOpenCVを簡単に比較し(以下を参照)、正しい視差とQマトリックスのテストも実行しました

// Reproject image to 3D
void customReproject(const cv::Mat& disparity, const cv::Mat& Q, cv::Mat& out3D)
{
    CV_Assert(disparity.type() == CV_32F && !disparity.empty());
    CV_Assert(Q.type() == CV_32F && Q.cols == 4 && Q.rows == 4);

    // 3-channel matrix for containing the reprojected 3D world coordinates
    out3D = cv::Mat::zeros(disparity.size(), CV_32FC3);

    // Getting the interesting parameters from Q, everything else is zero or one
    float Q03 = Q.at<float>(0, 3);
    float Q13 = Q.at<float>(1, 3);
    float Q23 = Q.at<float>(2, 3);
    float Q32 = Q.at<float>(3, 2);
    float Q33 = Q.at<float>(3, 3);

    // Transforming a single-channel disparity map to a 3-channel image representing a 3D surface
    for (int i = 0; i < disparity.rows; i++)
    {
        const float* disp_ptr = disparity.ptr<float>(i);
        cv::Vec3f* out3D_ptr = out3D.ptr<cv::Vec3f>(i);

        for (int j = 0; j < disparity.cols; j++)
        {
            const float pw = 1.0f / (disp_ptr[j] * Q32 + Q33);

            cv::Vec3f& point = out3D_ptr[j];
            point[0] = (static_cast<float>(j)+Q03) * pw;
            point[1] = (static_cast<float>(i)+Q13) * pw;
            point[2] = Q23 * pw;
        }
    }
}

両方の方法でほぼ同じ結果が得られ、それらはすべて私には正しいようです。視差マップとQマトリックスで試してみませんか?私のGitHubに私のテスト環境を置くことができます

注1:視差を2倍に拡大縮小しないように注意してください(拡大縮小されているdisparity.convertTo(disparity, CV_32F, 1.0 / 16.0);場合は、行をコメントアウトしてくださいdisparity)。

注2:OpenCV 3.0で構築されているため、インクルードを変​​更する必要がある場合があります。

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

Scala:マップ内の要素のインデックスを取得する

分類Dev

インデックスでHazelcastマップの値を取得します

分類Dev

マップ関数でSeq / Vectorのインデックスを取得する

分類Dev

ストリームを含むマップ内のマップからデータを取得する

分類Dev

データマップは国コードのリストを取得します

分類Dev

Android:適切なグーグルマップを取得していないデバイス上のマップアイコンのみを取得している

分類Dev

FirebaseからGoogleマップへのデータの取得

分類Dev

マップボックスマップの範囲内のマーカーのリストを取得します

分類Dev

Googleマップからマイプレイスのリストを取得する

分類Dev

角度/タイプスクリプトのマップの値を取得します

分類Dev

nullアイテムを含むマップの最後のインデックスを取得する方法

分類Dev

パンダは、マップ関数の要素のインデックスを取得します

分類Dev

C ++マルチインデックスマップの実装

分類Dev

マップ内のデータを取得する

分類Dev

iOSでGoogleマップのスナップショットを取得する方法

分類Dev

マップからキーのスライスを取得する

分類Dev

バウンディングボックスのNEとSWをマップし、NWとSEを取得します

分類Dev

Firebaseデータベースはマップを使用して子の特定の値を取得します

分類Dev

パターンマッチングのデフォルトケースのタイプを取得する

分類Dev

null値を取得するハイブマップデータの取得

分類Dev

Golangでのマップインデックスの逆参照

分類Dev

jsonへのインデックス付きのJavascriptマップ

分類Dev

マップの特定のインデックスに挿入

分類Dev

Linuxデスクトップのコマンドラインからディスプレイの解像度を取得する

分類Dev

Spring JDBCがマップのリストを取得する

分類Dev

マップ要素のアドレスを取得できません

分類Dev

gulp + babel + browserify + uglifyのソースマップを取得する方法

分類Dev

マップのリストから情報を取得するElixir

分類Dev

GoogleマップリリースAPIキーの取得

Related 関連記事

  1. 1

    Scala:マップ内の要素のインデックスを取得する

  2. 2

    インデックスでHazelcastマップの値を取得します

  3. 3

    マップ関数でSeq / Vectorのインデックスを取得する

  4. 4

    ストリームを含むマップ内のマップからデータを取得する

  5. 5

    データマップは国コードのリストを取得します

  6. 6

    Android:適切なグーグルマップを取得していないデバイス上のマップアイコンのみを取得している

  7. 7

    FirebaseからGoogleマップへのデータの取得

  8. 8

    マップボックスマップの範囲内のマーカーのリストを取得します

  9. 9

    Googleマップからマイプレイスのリストを取得する

  10. 10

    角度/タイプスクリプトのマップの値を取得します

  11. 11

    nullアイテムを含むマップの最後のインデックスを取得する方法

  12. 12

    パンダは、マップ関数の要素のインデックスを取得します

  13. 13

    C ++マルチインデックスマップの実装

  14. 14

    マップ内のデータを取得する

  15. 15

    iOSでGoogleマップのスナップショットを取得する方法

  16. 16

    マップからキーのスライスを取得する

  17. 17

    バウンディングボックスのNEとSWをマップし、NWとSEを取得します

  18. 18

    Firebaseデータベースはマップを使用して子の特定の値を取得します

  19. 19

    パターンマッチングのデフォルトケースのタイプを取得する

  20. 20

    null値を取得するハイブマップデータの取得

  21. 21

    Golangでのマップインデックスの逆参照

  22. 22

    jsonへのインデックス付きのJavascriptマップ

  23. 23

    マップの特定のインデックスに挿入

  24. 24

    Linuxデスクトップのコマンドラインからディスプレイの解像度を取得する

  25. 25

    Spring JDBCがマップのリストを取得する

  26. 26

    マップ要素のアドレスを取得できません

  27. 27

    gulp + babel + browserify + uglifyのソースマップを取得する方法

  28. 28

    マップのリストから情報を取得するElixir

  29. 29

    GoogleマップリリースAPIキーの取得

ホットタグ

アーカイブ