Skip to content

solved issue 2813 #2819

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

Merged
merged 2 commits into from
Jan 22, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion modules/stereo/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
set(the_description "Stereo Correspondence")
ocv_define_module(stereo opencv_imgproc opencv_features2d opencv_core opencv_tracking)
ocv_define_module(stereo opencv_imgproc opencv_features2d opencv_core opencv_tracking WRAP python)
66 changes: 34 additions & 32 deletions modules/stereo/include/opencv2/stereo/quasi_dense_stereo.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,42 +24,44 @@ namespace stereo


// A basic match structure
struct CV_EXPORTS Match
struct CV_EXPORTS_W_SIMPLE MatchQuasiDense
{
cv::Point2i p0;
cv::Point2i p1;
float corr;
CV_PROP_RW cv::Point2i p0;
CV_PROP_RW cv::Point2i p1;
CV_PROP_RW float corr;

bool operator < (const Match & rhs) const//fixme may be used uninitialized in this function
CV_WRAP MatchQuasiDense() { corr = 0; }

CV_WRAP_AS(apply) bool operator < (const MatchQuasiDense & rhs) const//fixme may be used uninitialized in this function
{
return this->corr < rhs.corr;
}
};
struct CV_EXPORTS PropagationParameters
struct CV_EXPORTS_W_SIMPLE PropagationParameters
{
int corrWinSizeX; // similarity window
int corrWinSizeY;
CV_PROP_RW int corrWinSizeX; // similarity window
CV_PROP_RW int corrWinSizeY;

int borderX; // border to ignore
int borderY;
CV_PROP_RW int borderX; // border to ignore
CV_PROP_RW int borderY;

//matching
float correlationThreshold; // correlation threshold
float textrureThreshold; // texture threshold
CV_PROP_RW float correlationThreshold; // correlation threshold
CV_PROP_RW float textrureThreshold; // texture threshold

int neighborhoodSize; // neighborhood size
int disparityGradient; // disparity gradient threshold
CV_PROP_RW int neighborhoodSize; // neighborhood size
CV_PROP_RW int disparityGradient; // disparity gradient threshold

// Parameters for LK flow algorithm
int lkTemplateSize;
int lkPyrLvl;
int lkTermParam1;
float lkTermParam2;
CV_PROP_RW int lkTemplateSize;
CV_PROP_RW int lkPyrLvl;
CV_PROP_RW int lkTermParam1;
CV_PROP_RW float lkTermParam2;

// Parameters for GFT algorithm.
float gftQualityThres;
int gftMinSeperationDist;
int gftMaxNumFeatures;
CV_PROP_RW float gftQualityThres;
CV_PROP_RW int gftMinSeperationDist;
CV_PROP_RW int gftMaxNumFeatures;

};

Expand Down Expand Up @@ -90,14 +92,14 @@ struct CV_EXPORTS PropagationParameters
*
*/

class CV_EXPORTS QuasiDenseStereo
class CV_EXPORTS_W QuasiDenseStereo
{
public:
/**
* @brief destructor
* Method to free all the memory allocated by matrices and vectors in this class.
*/
virtual ~QuasiDenseStereo() = 0;
CV_WRAP virtual ~QuasiDenseStereo() = 0;


/**
Expand All @@ -113,7 +115,7 @@ class CV_EXPORTS QuasiDenseStereo
* in case of video processing.
* @sa loadParameters
*/
virtual int loadParameters(cv::String filepath) = 0;
CV_WRAP 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.

Looks like bindings scripts can't properly wrap abstract classes and pure methods.



/**
Expand All @@ -124,7 +126,7 @@ class CV_EXPORTS QuasiDenseStereo
* @note This method can be used to generate a template file for tuning the class.
* @sa loadParameters
*/
virtual int saveParameters(cv::String filepath) = 0;
CV_WRAP virtual int saveParameters(cv::String filepath) = 0;


/**
Expand All @@ -133,7 +135,7 @@ class CV_EXPORTS QuasiDenseStereo
* @note The method clears the sMatches vector.
* @note The returned Match elements inside the sMatches vector, do not use corr member.
*/
virtual void getSparseMatches(std::vector<stereo::Match> &sMatches) = 0;
CV_WRAP virtual void getSparseMatches(CV_OUT std::vector<MatchQuasiDense> &sMatches) = 0;


/**
Expand All @@ -142,7 +144,7 @@ class CV_EXPORTS QuasiDenseStereo
* @note The method clears the denseMatches vector.
* @note The returned Match elements inside the sMatches vector, do not use corr member.
*/
virtual void getDenseMatches(std::vector<stereo::Match> &denseMatches) = 0;
CV_WRAP virtual void getDenseMatches(CV_OUT std::vector<MatchQuasiDense> &denseMatches) = 0;



Expand All @@ -158,7 +160,7 @@ class CV_EXPORTS QuasiDenseStereo
* @sa sparseMatching
* @sa quasiDenseMatching
*/
virtual void process(const cv::Mat &imgLeft ,const cv::Mat &imgRight) = 0;
CV_WRAP virtual void process(const cv::Mat &imgLeft ,const cv::Mat &imgRight) = 0;


/**
Expand All @@ -169,7 +171,7 @@ class CV_EXPORTS QuasiDenseStereo
* @retval cv::Point(0, 0) (NO_MATCH) if no match is found in the right image for the specified pixel location in the left image.
* @note This method should be always called after process, otherwise the matches will not be correct.
*/
virtual cv::Point2f getMatch(const int x, const int y) = 0;
CV_WRAP virtual cv::Point2f getMatch(const int x, const int y) = 0;


/**
Expand All @@ -180,13 +182,13 @@ class CV_EXPORTS QuasiDenseStereo
* @sa computeDisparity
* @sa quantizeDisparity
*/
virtual cv::Mat getDisparity(uint8_t disparityLvls=50) = 0;
CV_WRAP virtual cv::Mat getDisparity(uint8_t disparityLvls=50) = 0;


static cv::Ptr<QuasiDenseStereo> create(cv::Size monoImgSize, cv::String paramFilepath = cv::String());
CV_WRAP static cv::Ptr<QuasiDenseStereo> create(cv::Size monoImgSize, cv::String paramFilepath = cv::String());


PropagationParameters Param;
CV_PROP_RW PropagationParameters Param;
};

} //namespace cv
Expand Down
17 changes: 17 additions & 0 deletions modules/stereo/misc/python/pyopencv_stereo.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#ifdef HAVE_OPENCV_STEREO
typedef std::vector<stereo::MatchQuasiDense> vector_MatchQuasiDense;

template<> struct pyopencvVecConverter<stereo::MatchQuasiDense>
{
static bool to(PyObject* obj, std::vector<stereo::MatchQuasiDense>& value, const ArgInfo& info)
{
return pyopencv_to_generic_vec(obj, value, info);
}

static PyObject* from(const std::vector<stereo::MatchQuasiDense>& value)
{
return pyopencv_from_generic_vec(value);
}
};

#endif
20 changes: 20 additions & 0 deletions modules/stereo/misc/python/test/test_stereo.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/usr/bin/env python
import cv2 as cv

from tests_common import NewOpenCVTests

class quasi_dense_stereo_test(NewOpenCVTests):

def test_simple(self):

stereo = cv.stereo.QuasiDenseStereo_create((100, 100))
self.assertIsNotNone(stereo)

dense_matches = cv.stereo_MatchQuasiDense()
self.assertIsNotNone(dense_matches)

parameters = cv.stereo_PropagationParameters()
self.assertIsNotNone(parameters)

if __name__ == '__main__':
NewOpenCVTests.bootstrap()
2 changes: 1 addition & 1 deletion modules/stereo/samples/dense_disparity.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ int main()


//! [export]
vector<stereo::Match> matches;
vector<stereo::MatchQuasiDense> matches;
stereo->getDenseMatches(matches);
std::ofstream dense("./dense.txt", std::ios::out);
for (uint i=0; i< matches.size(); i++)
Expand Down
21 changes: 21 additions & 0 deletions modules/stereo/samples/sample_quasi_dense.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import numpy as np
import cv2 as cv

left_img = cv.imread(cv.samples.findFile("aloeL.jpg"), cv.IMREAD_COLOR)
right_img = cv.imread(cv.samples.findFile("aloeR.jpg"), cv.IMREAD_COLOR)

frame_size = leftImg.shape[0:2];

stereo = cv.stereo.QuasiDenseStereo_create(frame_size[::-1])
stereo.process(left_img, right_img)
disp = stereo.getDisparity(80)
cv.imshow("disparity", disp)
cv.waitKey()
dense_matches = stereo.getDenseMatches()
try:
with open("dense.txt", "wt") as f:
# if you want all matches use for idx in len(dense_matches): It can be a big file
for idx in range(0, min(10, len(dense_matches))):
nb = f.write(str(dense_matches[idx].p0) + "\t" + str(dense_matches[idx].p1) + "\t" + str(dense_matches[idx].corr) + "\n")
except:
print("Cannot open file")
20 changes: 10 additions & 10 deletions modules/stereo/src/quasi_dense_stereo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ namespace stereo {

#define NO_MATCH cv::Point(0,0)

typedef std::priority_queue<Match, std::vector<Match>, std::less<Match> > t_matchPriorityQueue;
typedef std::priority_queue<MatchQuasiDense, std::vector<MatchQuasiDense>, std::less<MatchQuasiDense> > t_matchPriorityQueue;


class QuasiDenseStereoImpl : public QuasiDenseStereo
Expand Down Expand Up @@ -165,7 +165,7 @@ class QuasiDenseStereoImpl : public QuasiDenseStereo
t_matchPriorityQueue Local;

// Get the best seed at the moment
Match m = seeds.top();
MatchQuasiDense m = seeds.top();
seeds.pop();

// Ignore the border
Expand Down Expand Up @@ -209,7 +209,7 @@ class QuasiDenseStereoImpl : public QuasiDenseStereo
// push back if this is valid match
if( corr > Param.correlationThreshold )
{
Match nm;
MatchQuasiDense nm;
nm.p0 = p0;
nm.p1 = p1;
nm.corr = corr;
Expand All @@ -223,7 +223,7 @@ class QuasiDenseStereoImpl : public QuasiDenseStereo
// Get seeds from the local
while( !Local.empty() )
{
Match lm = Local.top();
MatchQuasiDense lm = Local.top();
Local.pop();
// Check if its unique in both ref and dst.
if(refMap.at<cv::Point2i>(lm.p0.y, lm.p0.x) != NO_MATCH)
Expand Down Expand Up @@ -410,7 +410,7 @@ class QuasiDenseStereoImpl : public QuasiDenseStereo
for(uint i=0; i < featuresLeft.size(); i++)
{
// Calculate correlation and store match in Seeds.
Match m;
MatchQuasiDense m;
m.p0 = cv::Point2i(featuresLeft[i]);
m.p1 = cv::Point2i(featuresRight[i]);
m.corr = 0;
Expand Down Expand Up @@ -442,7 +442,7 @@ class QuasiDenseStereoImpl : public QuasiDenseStereo
* @retval true If the feature is in the border of the image.
* @retval false If the feature is not in the border of image.
*/
bool CheckBorder(Match m, int bx, int by, int w, int h)
bool CheckBorder(MatchQuasiDense m, int bx, int by, int w, int h)
{
if(m.p0.x<bx || m.p0.x>w-bx || m.p0.y<by || m.p0.y>h-by ||
m.p1.x<bx || m.p1.x>w-bx || m.p1.y<by || m.p1.y>h-by)
Expand Down Expand Up @@ -492,9 +492,9 @@ class QuasiDenseStereoImpl : public QuasiDenseStereo
//-------------------------------------------------------------------------


void getSparseMatches(std::vector<stereo::Match> &sMatches) override
void getSparseMatches(std::vector<stereo::MatchQuasiDense> &sMatches) override
{
Match tmpMatch;
MatchQuasiDense tmpMatch;
sMatches.clear();
sMatches.reserve(leftFeatures.size());
for (uint i=0; i<leftFeatures.size(); i++)
Expand Down Expand Up @@ -594,9 +594,9 @@ class QuasiDenseStereoImpl : public QuasiDenseStereo
return -1;
}

void getDenseMatches(std::vector<stereo::Match> &denseMatches) override
void getDenseMatches(std::vector<stereo::MatchQuasiDense> &denseMatches) override
{
Match tmpMatch;
MatchQuasiDense tmpMatch;
denseMatches.clear();
denseMatches.reserve(dMatchesLen);
for (int row=0; row<height; row++)
Expand Down