Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implementation of Quasi Dense Stereo algorithm. #1941

Merged
merged 29 commits into from
Dec 28, 2018

Conversation

dimitrisPs
Copy link
Contributor

I have implemented a class that establishes dense pairwise correspondences from a stereo image pair, and I wish to contribute it to the official repository. The class extracts a sparse set of correspondences from a stereo image pair using pyramidal Lucas-Kanade Flow algorithm based on Shi and Tomasi features, this way the class can process non-rectified images. To interpolate a dense set of correspondences the class uses the Quasi Dense Stereo algorithm proposed by M. Lhuillier and Long Quan et. al. [https://ieeexplore.ieee.org/document/905620].

Please let me know if you have any further questions or comments.

Thank You

Copy link
Member

@alalek alalek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this algorithm should be added into stereo module instead of creation of new one.

CV_PROP_RW cv::Point2i p1;
CV_PROP_RW float corr;

CV_WRAP bool operator < (const Match & rhs) const
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

C++ operators can't be wrapped directly.
Use CV_WRAP_AS(less) to wrap under different name.

modules/qds/include/opencv2/qds/quasiDenseStereo.hpp Outdated Show resolved Hide resolved
modules/qds/samples/export_param_file.cpp Outdated Show resolved Hide resolved
@dimitrisPs
Copy link
Contributor Author

Yes, I can add it there, just tell me how do you want me to integrate it. For now, will try and remove the warnings that your build-bot exports.

Copy link
Member

@alalek alalek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Migration to "stereo" module:

Extract public API part (which is going to be used by samples or high-level tests) from all headers and put it all into (opencv2/stereo/quasiDenseStereo.hpp). Merge documentation (documentation is generated from "public" headers (include/) only).
BTW, It is better to avoid case in filenames - quasi_dense_stereo.hpp

Include "opencv2/stereo/quasiDenseStereo.hpp" into "opencv2/stereo.hpp". Like this (for ximgproc module)

  1. Merge .bib files and move tutorials

Update dependencies in stereo/CMakeLists.txt
opencv_imgcodecs - should not be used. Algorithms should accept cv::Mat, instead of file names. Most part of image data comes from cameras.
Avoid entries duplication in OPTIONAL section.

  1. Bindings integration can be done later (current state probably doesn't work well and there is Python sample). Just don't use WRAP or _W variants of macros. CV_EXPORTS is enough.

  2. It would be nice to add some minimal test for primary API.

modules/qds/include/opencv2/qds/defaults.hpp Outdated Show resolved Hide resolved
modules/qds/include/opencv2/qds/defaults.hpp Outdated Show resolved Hide resolved

PropagationParameters Param;

protected:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Split interface (include/) and implementation (src/).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure I understand how you want me to change the structure. I think that this version of the class is already split. Could you please provide me with more information on how you want me to split the class?.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most of algorithms use following scheme:

// hpp

class Algo {
public:
  virtual void doSomething() = 0;
  virtual void setSomeProperty() = 0;
  virtual float getSomeProperty() = 0;
  ...
// no protected or private members
// no class fields
};

// can be defined inside the class - "static Ptr<Algo> Algo::create(...)"
static Ptr<Algo> createAlgo(...);
// cpp

class AlgoImpl : public Algo {
// implement all methods
};

Ptr<Algo> createAlgo(...)
{
  return makePtr<AlgoImpl>(...);
}

modules/qds/include/opencv2/qds/quasiDenseStereo.hpp Outdated Show resolved Hide resolved
@@ -0,0 +1,18 @@
#ifdef HAVE_OPENCV_QDS
#include "opencv2/core/saturate.hpp"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why saturate header is needed here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My mistake, I had trouble wrapping for python and I copied a snippet from pyopencv_linemod.hpp without checking if the header is needed.

modules/qds/include/opencv2/qds/quasiDenseStereo.hpp Outdated Show resolved Hide resolved
@dimitrisPs
Copy link
Contributor Author

Thank you for your input. I made changes to qds module. If your build-bot won't output any errors/warnings, I will start the integration to stereo module the way you described it.

* in case of video processing.
* @sa loadParameters
*/
CV_EXPORTS virtual int loadParameters(cv::String filepath="") = 0;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove CV_EXPORTS from members. It is already applied for whole class.

@dimitrisPs
Copy link
Contributor Author

I will fix the errors within the next hour and I will upload it again.

Copy link
Member

@alalek alalek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well done!

Please take a look on comments below.

isbn="978-3-642-15705-9"
}


Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove extra space before "}" and extra empty lines


};

typedef std::priority_queue<Match, std::vector<Match>, std::less<Match> > t_matchPriorityQueue;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not used in public API. Move to "src/" private headers.
Move #include <queue> too.

* in case of video processing.
* @sa loadParameters
*/
virtual int loadParameters(cv::String filepath="") = 0;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

=""

default value is not needed here

* @note This method can be used to generate a template file for tuning the class.
* @sa loadParameters
*/
virtual int saveParameters(cv::String filepath="./qds_parameters.yaml") = 0;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove default value too

virtual cv::Mat getDisparity(uint8_t disparityLvls=50) = 0;


static cv::Ptr<QuasiDenseStereo> create(cv::Size monoImgSize, cv::String paramFilepath ="");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

= cv::String()

@@ -0,0 +1,234 @@
/*
By downloading, copying, installing or using the software you agree to this license.
If you do not agree to this license, do not download, install,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use short OpenCV license header:

// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.

https://github.com/opencv/opencv/wiki/Coding_Style_Guide

You may add "author" information after these 3 lines.

- Compute dense Stereo correspondences.

-----------
[Source Code](../samples/dense_disparity.cpp)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

```
Mat rightImg, leftImg;
leftImg = imread("./imgLeft.png", IMREAD_COLOR);
rightImg = imread("./imgRight.png", IMREAD_COLOR);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use @snippet instead of code duplication.

{
Match tmpMatch;
dMatches.clear();
// dMatches.resize(dMatchesLen);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dMatches.reserve

Copy link
Member

@alalek alalek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well done!

/*
By downloading, copying, installing or using the software you agree to this license.
If you do not agree to this license, do not download, install,
copy or use the software.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use the short license header here too.

Copy link
Member

@alalek alalek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you 👍

@ZhuLingfeng1993
Copy link

@dimitrisPs
I test quasi dense stereo algorithm with opencv4.5.1.
I use images in testdata folder in stereo module to test the sample code file dense_disparity.cpp, but I get a disparity map with wrong result. Can you share your test image and configuration?

@ZhuLingfeng1993 ZhuLingfeng1993 mentioned this pull request Feb 13, 2021
6 tasks
@dimitrisPs
Copy link
Contributor Author

@ZhuLingfeng1993
Unfortunately, I do not have a copy of the test code I used back then.
Most likely, the reason you do not get correct disparity results is that you are using the getDisparity() function to get disparities. Inside this function, the disparity values get normalized to span the full range between 0 and 255. This was done because when I implemented the code I was working with planar scenes and I needed a fast way of visualizing normalized disparity images. To get proper disparity maps you can use the getDenseMatches() which will return the location of corresponding points and use those to create a disparity map.
I am fully aware that the getDisparity has a confusing name, for what it does, I plan to commit changes in the following days.

@ZhuLingfeng1993
Copy link

@dimitrisPs
Thank you for your reply. I read the source code of getDisparity() and understand your reply. And I get the correct disparity map finally, thank you for your contribution.

@dimitrisPs
Copy link
Contributor Author

@ZhuLingfeng1993
That's good to hear... I already made a pull request which removes the normalisation and added an accuracy test, proving that the algorithm works out of the box on Middlebury. Hopefully it will get merged and you will be able to get correct disparities using the getDisparity directly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants