Skip to content

Commit d733a80

Browse files
Merge pull request #2819 from LaurentBerger:pyb_qd
* solved issue 2813 * review
1 parent ae14c7c commit d733a80

File tree

7 files changed

+104
-44
lines changed

7 files changed

+104
-44
lines changed

modules/stereo/CMakeLists.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
set(the_description "Stereo Correspondence")
2-
ocv_define_module(stereo opencv_imgproc opencv_features2d opencv_core opencv_tracking)
2+
ocv_define_module(stereo opencv_imgproc opencv_features2d opencv_core opencv_tracking WRAP python)

modules/stereo/include/opencv2/stereo/quasi_dense_stereo.hpp

+34-32
Original file line numberDiff line numberDiff line change
@@ -24,42 +24,44 @@ namespace stereo
2424

2525

2626
// A basic match structure
27-
struct CV_EXPORTS Match
27+
struct CV_EXPORTS_W_SIMPLE MatchQuasiDense
2828
{
29-
cv::Point2i p0;
30-
cv::Point2i p1;
31-
float corr;
29+
CV_PROP_RW cv::Point2i p0;
30+
CV_PROP_RW cv::Point2i p1;
31+
CV_PROP_RW float corr;
3232

33-
bool operator < (const Match & rhs) const//fixme may be used uninitialized in this function
33+
CV_WRAP MatchQuasiDense() { corr = 0; }
34+
35+
CV_WRAP_AS(apply) bool operator < (const MatchQuasiDense & rhs) const//fixme may be used uninitialized in this function
3436
{
3537
return this->corr < rhs.corr;
3638
}
3739
};
38-
struct CV_EXPORTS PropagationParameters
40+
struct CV_EXPORTS_W_SIMPLE PropagationParameters
3941
{
40-
int corrWinSizeX; // similarity window
41-
int corrWinSizeY;
42+
CV_PROP_RW int corrWinSizeX; // similarity window
43+
CV_PROP_RW int corrWinSizeY;
4244

43-
int borderX; // border to ignore
44-
int borderY;
45+
CV_PROP_RW int borderX; // border to ignore
46+
CV_PROP_RW int borderY;
4547

4648
//matching
47-
float correlationThreshold; // correlation threshold
48-
float textrureThreshold; // texture threshold
49+
CV_PROP_RW float correlationThreshold; // correlation threshold
50+
CV_PROP_RW float textrureThreshold; // texture threshold
4951

50-
int neighborhoodSize; // neighborhood size
51-
int disparityGradient; // disparity gradient threshold
52+
CV_PROP_RW int neighborhoodSize; // neighborhood size
53+
CV_PROP_RW int disparityGradient; // disparity gradient threshold
5254

5355
// Parameters for LK flow algorithm
54-
int lkTemplateSize;
55-
int lkPyrLvl;
56-
int lkTermParam1;
57-
float lkTermParam2;
56+
CV_PROP_RW int lkTemplateSize;
57+
CV_PROP_RW int lkPyrLvl;
58+
CV_PROP_RW int lkTermParam1;
59+
CV_PROP_RW float lkTermParam2;
5860

5961
// Parameters for GFT algorithm.
60-
float gftQualityThres;
61-
int gftMinSeperationDist;
62-
int gftMaxNumFeatures;
62+
CV_PROP_RW float gftQualityThres;
63+
CV_PROP_RW int gftMinSeperationDist;
64+
CV_PROP_RW int gftMaxNumFeatures;
6365

6466
};
6567

@@ -90,14 +92,14 @@ struct CV_EXPORTS PropagationParameters
9092
*
9193
*/
9294

93-
class CV_EXPORTS QuasiDenseStereo
95+
class CV_EXPORTS_W QuasiDenseStereo
9496
{
9597
public:
9698
/**
9799
* @brief destructor
98100
* Method to free all the memory allocated by matrices and vectors in this class.
99101
*/
100-
virtual ~QuasiDenseStereo() = 0;
102+
CV_WRAP virtual ~QuasiDenseStereo() = 0;
101103

102104

103105
/**
@@ -113,7 +115,7 @@ class CV_EXPORTS QuasiDenseStereo
113115
* in case of video processing.
114116
* @sa loadParameters
115117
*/
116-
virtual int loadParameters(cv::String filepath) = 0;
118+
CV_WRAP virtual int loadParameters(cv::String filepath) = 0;
117119

118120

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

129131

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

138140

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

147149

148150

@@ -158,7 +160,7 @@ class CV_EXPORTS QuasiDenseStereo
158160
* @sa sparseMatching
159161
* @sa quasiDenseMatching
160162
*/
161-
virtual void process(const cv::Mat &imgLeft ,const cv::Mat &imgRight) = 0;
163+
CV_WRAP virtual void process(const cv::Mat &imgLeft ,const cv::Mat &imgRight) = 0;
162164

163165

164166
/**
@@ -169,7 +171,7 @@ class CV_EXPORTS QuasiDenseStereo
169171
* @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.
170172
* @note This method should be always called after process, otherwise the matches will not be correct.
171173
*/
172-
virtual cv::Point2f getMatch(const int x, const int y) = 0;
174+
CV_WRAP virtual cv::Point2f getMatch(const int x, const int y) = 0;
173175

174176

175177
/**
@@ -180,13 +182,13 @@ class CV_EXPORTS QuasiDenseStereo
180182
* @sa computeDisparity
181183
* @sa quantizeDisparity
182184
*/
183-
virtual cv::Mat getDisparity(uint8_t disparityLvls=50) = 0;
185+
CV_WRAP virtual cv::Mat getDisparity(uint8_t disparityLvls=50) = 0;
184186

185187

186-
static cv::Ptr<QuasiDenseStereo> create(cv::Size monoImgSize, cv::String paramFilepath = cv::String());
188+
CV_WRAP static cv::Ptr<QuasiDenseStereo> create(cv::Size monoImgSize, cv::String paramFilepath = cv::String());
187189

188190

189-
PropagationParameters Param;
191+
CV_PROP_RW PropagationParameters Param;
190192
};
191193

192194
} //namespace cv
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#ifdef HAVE_OPENCV_STEREO
2+
typedef std::vector<stereo::MatchQuasiDense> vector_MatchQuasiDense;
3+
4+
template<> struct pyopencvVecConverter<stereo::MatchQuasiDense>
5+
{
6+
static bool to(PyObject* obj, std::vector<stereo::MatchQuasiDense>& value, const ArgInfo& info)
7+
{
8+
return pyopencv_to_generic_vec(obj, value, info);
9+
}
10+
11+
static PyObject* from(const std::vector<stereo::MatchQuasiDense>& value)
12+
{
13+
return pyopencv_from_generic_vec(value);
14+
}
15+
};
16+
17+
#endif
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#!/usr/bin/env python
2+
import cv2 as cv
3+
4+
from tests_common import NewOpenCVTests
5+
6+
class quasi_dense_stereo_test(NewOpenCVTests):
7+
8+
def test_simple(self):
9+
10+
stereo = cv.stereo.QuasiDenseStereo_create((100, 100))
11+
self.assertIsNotNone(stereo)
12+
13+
dense_matches = cv.stereo_MatchQuasiDense()
14+
self.assertIsNotNone(dense_matches)
15+
16+
parameters = cv.stereo_PropagationParameters()
17+
self.assertIsNotNone(parameters)
18+
19+
if __name__ == '__main__':
20+
NewOpenCVTests.bootstrap()

modules/stereo/samples/dense_disparity.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ int main()
4646

4747

4848
//! [export]
49-
vector<stereo::Match> matches;
49+
vector<stereo::MatchQuasiDense> matches;
5050
stereo->getDenseMatches(matches);
5151
std::ofstream dense("./dense.txt", std::ios::out);
5252
for (uint i=0; i< matches.size(); i++)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import numpy as np
2+
import cv2 as cv
3+
4+
left_img = cv.imread(cv.samples.findFile("aloeL.jpg"), cv.IMREAD_COLOR)
5+
right_img = cv.imread(cv.samples.findFile("aloeR.jpg"), cv.IMREAD_COLOR)
6+
7+
frame_size = leftImg.shape[0:2];
8+
9+
stereo = cv.stereo.QuasiDenseStereo_create(frame_size[::-1])
10+
stereo.process(left_img, right_img)
11+
disp = stereo.getDisparity(80)
12+
cv.imshow("disparity", disp)
13+
cv.waitKey()
14+
dense_matches = stereo.getDenseMatches()
15+
try:
16+
with open("dense.txt", "wt") as f:
17+
# if you want all matches use for idx in len(dense_matches): It can be a big file
18+
for idx in range(0, min(10, len(dense_matches))):
19+
nb = f.write(str(dense_matches[idx].p0) + "\t" + str(dense_matches[idx].p1) + "\t" + str(dense_matches[idx].corr) + "\n")
20+
except:
21+
print("Cannot open file")

modules/stereo/src/quasi_dense_stereo.cpp

+10-10
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ namespace stereo {
1313

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

16-
typedef std::priority_queue<Match, std::vector<Match>, std::less<Match> > t_matchPriorityQueue;
16+
typedef std::priority_queue<MatchQuasiDense, std::vector<MatchQuasiDense>, std::less<MatchQuasiDense> > t_matchPriorityQueue;
1717

1818

1919
class QuasiDenseStereoImpl : public QuasiDenseStereo
@@ -165,7 +165,7 @@ class QuasiDenseStereoImpl : public QuasiDenseStereo
165165
t_matchPriorityQueue Local;
166166

167167
// Get the best seed at the moment
168-
Match m = seeds.top();
168+
MatchQuasiDense m = seeds.top();
169169
seeds.pop();
170170

171171
// Ignore the border
@@ -209,7 +209,7 @@ class QuasiDenseStereoImpl : public QuasiDenseStereo
209209
// push back if this is valid match
210210
if( corr > Param.correlationThreshold )
211211
{
212-
Match nm;
212+
MatchQuasiDense nm;
213213
nm.p0 = p0;
214214
nm.p1 = p1;
215215
nm.corr = corr;
@@ -223,7 +223,7 @@ class QuasiDenseStereoImpl : public QuasiDenseStereo
223223
// Get seeds from the local
224224
while( !Local.empty() )
225225
{
226-
Match lm = Local.top();
226+
MatchQuasiDense lm = Local.top();
227227
Local.pop();
228228
// Check if its unique in both ref and dst.
229229
if(refMap.at<cv::Point2i>(lm.p0.y, lm.p0.x) != NO_MATCH)
@@ -410,7 +410,7 @@ class QuasiDenseStereoImpl : public QuasiDenseStereo
410410
for(uint i=0; i < featuresLeft.size(); i++)
411411
{
412412
// Calculate correlation and store match in Seeds.
413-
Match m;
413+
MatchQuasiDense m;
414414
m.p0 = cv::Point2i(featuresLeft[i]);
415415
m.p1 = cv::Point2i(featuresRight[i]);
416416
m.corr = 0;
@@ -442,7 +442,7 @@ class QuasiDenseStereoImpl : public QuasiDenseStereo
442442
* @retval true If the feature is in the border of the image.
443443
* @retval false If the feature is not in the border of image.
444444
*/
445-
bool CheckBorder(Match m, int bx, int by, int w, int h)
445+
bool CheckBorder(MatchQuasiDense m, int bx, int by, int w, int h)
446446
{
447447
if(m.p0.x<bx || m.p0.x>w-bx || m.p0.y<by || m.p0.y>h-by ||
448448
m.p1.x<bx || m.p1.x>w-bx || m.p1.y<by || m.p1.y>h-by)
@@ -492,9 +492,9 @@ class QuasiDenseStereoImpl : public QuasiDenseStereo
492492
//-------------------------------------------------------------------------
493493

494494

495-
void getSparseMatches(std::vector<stereo::Match> &sMatches) override
495+
void getSparseMatches(std::vector<stereo::MatchQuasiDense> &sMatches) override
496496
{
497-
Match tmpMatch;
497+
MatchQuasiDense tmpMatch;
498498
sMatches.clear();
499499
sMatches.reserve(leftFeatures.size());
500500
for (uint i=0; i<leftFeatures.size(); i++)
@@ -594,9 +594,9 @@ class QuasiDenseStereoImpl : public QuasiDenseStereo
594594
return -1;
595595
}
596596

597-
void getDenseMatches(std::vector<stereo::Match> &denseMatches) override
597+
void getDenseMatches(std::vector<stereo::MatchQuasiDense> &denseMatches) override
598598
{
599-
Match tmpMatch;
599+
MatchQuasiDense tmpMatch;
600600
denseMatches.clear();
601601
denseMatches.reserve(dMatchesLen);
602602
for (int row=0; row<height; row++)

0 commit comments

Comments
 (0)