Skip to content

Commit e967557

Browse files
committed
Allows structured_light pipeline to be run from Python
SinusoidalPattern::unwrapPhaseMap now takes an InputArray instead of InputArrayOfArrays to correct a Python binding problem present a scriptable HistogramPhaseUnwrapping::create replicate C++ structured_light test in Python PhaseUnwrapping now init unwrappedPhase so pixel outside the mask area are set to 0 python binding for HistogramPhaseUnwrapping::Params to use HistogramPhaseUnwrapping::create
1 parent 9c0ae27 commit e967557

File tree

5 files changed

+109
-8
lines changed

5 files changed

+109
-8
lines changed

modules/phase_unwrapping/include/opencv2/phase_unwrapping/histogramphaseunwrapping.hpp

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -75,20 +75,21 @@ class CV_EXPORTS_W HistogramPhaseUnwrapping : public PhaseUnwrapping
7575
* @param nbrOfSmallBins Number of bins between 0 and "histThresh". Default value is 10.
7676
* @param nbrOfLargeBins Number of bins between "histThresh" and 32*pi*pi (highest edge reliability value). Default value is 5.
7777
*/
78-
struct CV_EXPORTS Params
78+
struct CV_EXPORTS_W_SIMPLE Params
7979
{
80-
Params();
81-
int width;
82-
int height;
83-
float histThresh;
84-
int nbrOfSmallBins;
85-
int nbrOfLargeBins;
80+
CV_WRAP Params();
81+
CV_PROP_RW int width;
82+
CV_PROP_RW int height;
83+
CV_PROP_RW float histThresh;
84+
CV_PROP_RW int nbrOfSmallBins;
85+
CV_PROP_RW int nbrOfLargeBins;
8686
};
8787
/**
8888
* @brief Constructor
8989
9090
* @param parameters HistogramPhaseUnwrapping parameters HistogramPhaseUnwrapping::Params: width,height of the phase map and histogram characteristics.
9191
*/
92+
CV_WRAP
9293
static Ptr<HistogramPhaseUnwrapping> create( const HistogramPhaseUnwrapping::Params &parameters =
9394
HistogramPhaseUnwrapping::Params() );
9495

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#ifdef HAVE_OPENCV_PHASE_UNWRAPPING
2+
typedef cv::phase_unwrapping::HistogramPhaseUnwrapping::Params HistogramPhaseUnwrapping_Params;
3+
#endif

modules/phase_unwrapping/src/histogramphaseunwrapping.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -712,7 +712,10 @@ void HistogramPhaseUnwrapping_Impl::addIncrement( OutputArray unwrappedPhaseMap
712712
int rows = params.height;
713713
int cols = params.width;
714714
if( uPhaseMap.empty() )
715+
{
715716
uPhaseMap.create(rows, cols, CV_32FC1);
717+
uPhaseMap = Scalar::all(0);
718+
}
716719
int nbrOfPixels = static_cast<int>(pixels.size());
717720
for( int i = 0; i < nbrOfPixels; ++i )
718721
{

modules/structured_light/include/opencv2/structured_light/sinusoidalpattern.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ class CV_EXPORTS_W SinusoidalPattern : public StructuredLightPattern
119119
* @param shadowMask Mask used to discard shadow regions.
120120
*/
121121
CV_WRAP
122-
virtual void unwrapPhaseMap( InputArrayOfArrays wrappedPhaseMap,
122+
virtual void unwrapPhaseMap( InputArray wrappedPhaseMap,
123123
OutputArray unwrappedPhaseMap,
124124
cv::Size camSize,
125125
InputArray shadowMask = noArray() ) = 0;
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
#!/usr/bin/env python
2+
3+
# Python 2/3 compatibility
4+
from __future__ import print_function
5+
6+
import os, numpy
7+
8+
import cv2 as cv
9+
10+
from tests_common import NewOpenCVTests
11+
12+
class structured_light_test(NewOpenCVTests):
13+
14+
def test_unwrap(self):
15+
paramsPsp = cv.structured_light_SinusoidalPattern_Params();
16+
paramsFtp = cv.structured_light_SinusoidalPattern_Params();
17+
paramsFaps = cv.structured_light_SinusoidalPattern_Params();
18+
paramsPsp.methodId = cv.structured_light.PSP;
19+
paramsFtp.methodId = cv.structured_light.FTP;
20+
paramsFaps.methodId = cv.structured_light.FAPS;
21+
22+
sinusPsp = cv.structured_light.SinusoidalPattern_create(paramsPsp)
23+
sinusFtp = cv.structured_light.SinusoidalPattern_create(paramsFtp)
24+
sinusFaps = cv.structured_light.SinusoidalPattern_create(paramsFaps)
25+
26+
captures = []
27+
for i in range(0,3):
28+
capture = self.get_sample('/cv/structured_light/data/capture_sin_%d.jpg'%i, cv.IMREAD_GRAYSCALE)
29+
if capture is None:
30+
raise unittest.SkipTest("Missing files with test data")
31+
captures.append(capture)
32+
33+
rows,cols = captures[0].shape
34+
35+
unwrappedPhaseMapPspRef = self.get_sample('/cv/structured_light/data/unwrappedPspTest.jpg',
36+
cv.IMREAD_GRAYSCALE)
37+
unwrappedPhaseMapFtpRef = self.get_sample('/cv/structured_light/data/unwrappedFtpTest.jpg',
38+
cv.IMREAD_GRAYSCALE)
39+
unwrappedPhaseMapFapsRef = self.get_sample('/cv/structured_light/data/unwrappedFapsTest.jpg',
40+
cv.IMREAD_GRAYSCALE)
41+
42+
wrappedPhaseMap,shadowMask = sinusPsp.computePhaseMap(captures);
43+
unwrappedPhaseMap = sinusPsp.unwrapPhaseMap(wrappedPhaseMap, (cols, rows), shadowMask=shadowMask)
44+
unwrappedPhaseMap8 = unwrappedPhaseMap*1 + 128
45+
unwrappedPhaseMap8 = numpy.uint8(unwrappedPhaseMap8)
46+
47+
sumOfDiff = 0
48+
count = 0
49+
for i in range(rows):
50+
for j in range(cols):
51+
ref = int(unwrappedPhaseMapPspRef[i, j])
52+
comp = int(unwrappedPhaseMap8[i, j])
53+
sumOfDiff += (ref - comp)
54+
count += 1
55+
56+
ratio = sumOfDiff/float(count)
57+
self.assertLessEqual(ratio, 0.2)
58+
59+
wrappedPhaseMap,shadowMask = sinusFtp.computePhaseMap(captures);
60+
unwrappedPhaseMap = sinusFtp.unwrapPhaseMap(wrappedPhaseMap, (cols, rows), shadowMask=shadowMask)
61+
unwrappedPhaseMap8 = unwrappedPhaseMap*1 + 128
62+
unwrappedPhaseMap8 = numpy.uint8(unwrappedPhaseMap8)
63+
64+
sumOfDiff = 0
65+
count = 0
66+
for i in range(rows):
67+
for j in range(cols):
68+
ref = int(unwrappedPhaseMapFtpRef[i, j])
69+
comp = int(unwrappedPhaseMap8[i, j])
70+
sumOfDiff += (ref - comp)
71+
count += 1
72+
73+
ratio = sumOfDiff/float(count)
74+
self.assertLessEqual(ratio, 0.2)
75+
76+
wrappedPhaseMap,shadowMask2 = sinusFaps.computePhaseMap(captures);
77+
unwrappedPhaseMap = sinusFaps.unwrapPhaseMap(wrappedPhaseMap, (cols, rows), shadowMask=shadowMask)
78+
unwrappedPhaseMap8 = unwrappedPhaseMap*1 + 128
79+
unwrappedPhaseMap8 = numpy.uint8(unwrappedPhaseMap8)
80+
81+
sumOfDiff = 0
82+
count = 0
83+
for i in range(rows):
84+
for j in range(cols):
85+
ref = int(unwrappedPhaseMapFapsRef[i, j])
86+
comp = int(unwrappedPhaseMap8[i, j])
87+
sumOfDiff += (ref - comp)
88+
count += 1
89+
90+
ratio = sumOfDiff/float(count)
91+
self.assertLessEqual(ratio, 0.2)
92+
93+
if __name__ == '__main__':
94+
NewOpenCVTests.bootstrap()

0 commit comments

Comments
 (0)