Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
O
opencv
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
opencv
Commits
d0e89337
Commit
d0e89337
authored
May 08, 2013
by
Vladislav Vinogradov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
refactored StereoBeliefPropagation
parent
dd6d58f8
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
294 additions
and
255 deletions
+294
-255
gpustereo.hpp
modules/gpustereo/include/opencv2/gpustereo.hpp
+34
-40
perf_stereo.cpp
modules/gpustereo/perf/perf_stereo.cpp
+2
-2
stereobp.cpp
modules/gpustereo/src/stereobp.cpp
+236
-196
test_stereo.cpp
modules/gpustereo/test/test_stereo.cpp
+7
-2
stereo_match.cpp
samples/gpu/stereo_match.cpp
+15
-15
No files found.
modules/gpustereo/include/opencv2/gpustereo.hpp
View file @
d0e89337
...
...
@@ -65,61 +65,55 @@ public:
CV_EXPORTS
Ptr
<
gpu
::
StereoBM
>
createStereoBM
(
int
numDisparities
=
64
,
int
blockSize
=
19
);
/////////////////////////////////////////
// StereoBeliefPropagation
// "Efficient Belief Propagation for Early Vision"
// P.Felzenszwalb
class
CV_EXPORTS
StereoBeliefPropagation
//! "Efficient Belief Propagation for Early Vision" P.Felzenszwalb
class
CV_EXPORTS
StereoBeliefPropagation
:
public
cv
::
StereoMatcher
{
public
:
enum
{
DEFAULT_NDISP
=
64
};
enum
{
DEFAULT_ITERS
=
5
};
enum
{
DEFAULT_LEVELS
=
5
};
using
cv
::
StereoMatcher
::
compute
;
static
void
estimateRecommendedParams
(
int
width
,
int
height
,
int
&
ndisp
,
int
&
iters
,
int
&
levels
)
;
virtual
void
compute
(
InputArray
left
,
InputArray
right
,
OutputArray
disparity
,
Stream
&
stream
)
=
0
;
//! the default constructor
explicit
StereoBeliefPropagation
(
int
ndisp
=
DEFAULT_NDISP
,
int
iters
=
DEFAULT_ITERS
,
int
levels
=
DEFAULT_LEVELS
,
int
msg_type
=
CV_32F
);
//! version for user specified data term
virtual
void
compute
(
InputArray
data
,
OutputArray
disparity
,
Stream
&
stream
=
Stream
::
Null
())
=
0
;
//! the full constructor taking the number of disparities, number of BP iterations on each level,
//! number of levels, truncation of data cost, data weight,
//! truncation of discontinuity cost and discontinuity single jump
//! DataTerm = data_weight * min(fabs(I2-I1), max_data_term)
//! DiscTerm = min(disc_single_jump * fabs(f1-f2), max_disc_term)
//! please see paper for more details
StereoBeliefPropagation
(
int
ndisp
,
int
iters
,
int
levels
,
float
max_data_term
,
float
data_weight
,
float
max_disc_term
,
float
disc_single_jump
,
int
msg_type
=
CV_32F
);
//! number of BP iterations on each level
virtual
int
getNumIters
()
const
=
0
;
virtual
void
setNumIters
(
int
iters
)
=
0
;
//!
the stereo correspondence operator. Finds the disparity for the specified rectified stereo pair,
//! if disparity is empty output type will be CV_16S else output type will be disparity.type().
v
oid
operator
()(
const
GpuMat
&
left
,
const
GpuMat
&
right
,
GpuMat
&
disparity
,
Stream
&
stream
=
Stream
::
Null
())
;
//!
number of levels
virtual
int
getNumLevels
()
const
=
0
;
v
irtual
void
setNumLevels
(
int
levels
)
=
0
;
//! truncation of data cost
virtual
double
getMaxDataTerm
()
const
=
0
;
virtual
void
setMaxDataTerm
(
double
max_data_term
)
=
0
;
//! version for user specified data term
void
operator
()(
const
GpuMat
&
data
,
GpuMat
&
disparity
,
Stream
&
stream
=
Stream
::
Null
());
//! data weight
virtual
double
getDataWeight
()
const
=
0
;
virtual
void
setDataWeight
(
double
data_weight
)
=
0
;
int
ndisp
;
//! truncation of discontinuity cost
virtual
double
getMaxDiscTerm
()
const
=
0
;
virtual
void
setMaxDiscTerm
(
double
max_disc_term
)
=
0
;
int
iters
;
int
levels
;
//! discontinuity single jump
virtual
double
getDiscSingleJump
()
const
=
0
;
virtual
void
setDiscSingleJump
(
double
disc_single_jump
)
=
0
;
float
max_data_term
;
float
data_weight
;
float
max_disc_term
;
float
disc_single_jump
;
virtual
int
getMsgType
()
const
=
0
;
virtual
void
setMsgType
(
int
msg_type
)
=
0
;
int
msg_type
;
private
:
GpuMat
u
,
d
,
l
,
r
,
u2
,
d2
,
l2
,
r2
;
std
::
vector
<
GpuMat
>
datas
;
GpuMat
out
;
static
void
estimateRecommendedParams
(
int
width
,
int
height
,
int
&
ndisp
,
int
&
iters
,
int
&
levels
);
};
CV_EXPORTS
Ptr
<
gpu
::
StereoBeliefPropagation
>
createStereoBeliefPropagation
(
int
ndisp
=
64
,
int
iters
=
5
,
int
levels
=
5
,
int
msg_type
=
CV_32F
);
// "A Constant-Space Belief Propagation Algorithm for Stereo Matching"
// Qingxiong Yang, Liang Wang, Narendra Ahuja
// http://vision.ai.uiuc.edu/~qyang6/
...
...
modules/gpustereo/perf/perf_stereo.cpp
View file @
d0e89337
...
...
@@ -107,13 +107,13 @@ PERF_TEST_P(ImagePair, StereoBeliefPropagation,
if
(
PERF_RUN_GPU
())
{
cv
::
gpu
::
StereoBeliefPropagation
d_bp
(
ndisp
);
cv
::
Ptr
<
cv
::
gpu
::
StereoBeliefPropagation
>
d_bp
=
cv
::
gpu
::
createStereoBeliefPropagation
(
ndisp
);
const
cv
::
gpu
::
GpuMat
d_imgLeft
(
imgLeft
);
const
cv
::
gpu
::
GpuMat
d_imgRight
(
imgRight
);
cv
::
gpu
::
GpuMat
dst
;
TEST_CYCLE
()
d_bp
(
d_imgLeft
,
d_imgRight
,
dst
);
TEST_CYCLE
()
d_bp
->
compute
(
d_imgLeft
,
d_imgRight
,
dst
);
GPU_SANITY_CHECK
(
dst
);
}
...
...
modules/gpustereo/src/stereobp.cpp
View file @
d0e89337
...
...
@@ -49,12 +49,7 @@ using namespace cv::gpu;
void
cv
::
gpu
::
StereoBeliefPropagation
::
estimateRecommendedParams
(
int
,
int
,
int
&
,
int
&
,
int
&
)
{
throw_no_cuda
();
}
cv
::
gpu
::
StereoBeliefPropagation
::
StereoBeliefPropagation
(
int
,
int
,
int
,
int
)
{
throw_no_cuda
();
}
cv
::
gpu
::
StereoBeliefPropagation
::
StereoBeliefPropagation
(
int
,
int
,
int
,
float
,
float
,
float
,
float
,
int
)
{
throw_no_cuda
();
}
void
cv
::
gpu
::
StereoBeliefPropagation
::
operator
()(
const
GpuMat
&
,
const
GpuMat
&
,
GpuMat
&
,
Stream
&
)
{
throw_no_cuda
();
}
void
cv
::
gpu
::
StereoBeliefPropagation
::
operator
()(
const
GpuMat
&
,
GpuMat
&
,
Stream
&
)
{
throw_no_cuda
();
}
Ptr
<
gpu
::
StereoBeliefPropagation
>
cv
::
gpu
::
createStereoBeliefPropagation
(
int
,
int
,
int
,
int
)
{
throw_no_cuda
();
return
Ptr
<
gpu
::
StereoBeliefPropagation
>
();
}
#else
/* !defined (HAVE_CUDA) */
...
...
@@ -78,263 +73,308 @@ namespace cv { namespace gpu { namespace cudev
}
}}}
using
namespace
::
cv
::
gpu
::
cudev
::
stereobp
;
namespace
{
class
StereoBPImpl
:
public
gpu
::
StereoBeliefPropagation
{
public
:
StereoBPImpl
(
int
ndisp
,
int
iters
,
int
levels
,
int
msg_type
);
void
compute
(
InputArray
left
,
InputArray
right
,
OutputArray
disparity
);
void
compute
(
InputArray
left
,
InputArray
right
,
OutputArray
disparity
,
Stream
&
stream
);
void
compute
(
InputArray
data
,
OutputArray
disparity
,
Stream
&
stream
);
int
getMinDisparity
()
const
{
return
0
;
}
void
setMinDisparity
(
int
/*minDisparity*/
)
{}
int
getNumDisparities
()
const
{
return
ndisp_
;
}
void
setNumDisparities
(
int
numDisparities
)
{
ndisp_
=
numDisparities
;
}
int
getBlockSize
()
const
{
return
0
;
}
void
setBlockSize
(
int
/*blockSize*/
)
{}
int
getSpeckleWindowSize
()
const
{
return
0
;
}
void
setSpeckleWindowSize
(
int
/*speckleWindowSize*/
)
{}
int
getSpeckleRange
()
const
{
return
0
;
}
void
setSpeckleRange
(
int
/*speckleRange*/
)
{}
int
getDisp12MaxDiff
()
const
{
return
0
;
}
void
setDisp12MaxDiff
(
int
/*disp12MaxDiff*/
)
{}
int
getNumIters
()
const
{
return
iters_
;
}
void
setNumIters
(
int
iters
)
{
iters_
=
iters
;
}
int
getNumLevels
()
const
{
return
levels_
;
}
void
setNumLevels
(
int
levels
)
{
levels_
=
levels
;
}
double
getMaxDataTerm
()
const
{
return
max_data_term_
;
}
void
setMaxDataTerm
(
double
max_data_term
)
{
max_data_term_
=
(
float
)
max_data_term
;
}
double
getDataWeight
()
const
{
return
data_weight_
;
}
void
setDataWeight
(
double
data_weight
)
{
data_weight_
=
(
float
)
data_weight
;
}
double
getMaxDiscTerm
()
const
{
return
max_disc_term_
;
}
void
setMaxDiscTerm
(
double
max_disc_term
)
{
max_disc_term_
=
(
float
)
max_disc_term
;
}
double
getDiscSingleJump
()
const
{
return
disc_single_jump_
;
}
void
setDiscSingleJump
(
double
disc_single_jump
)
{
disc_single_jump_
=
(
float
)
disc_single_jump
;
}
int
getMsgType
()
const
{
return
msg_type_
;
}
void
setMsgType
(
int
msg_type
)
{
msg_type_
=
msg_type
;
}
private
:
void
init
(
Stream
&
stream
);
void
calcBP
(
OutputArray
disp
,
Stream
&
stream
);
int
ndisp_
;
int
iters_
;
int
levels_
;
float
max_data_term_
;
float
data_weight_
;
float
max_disc_term_
;
float
disc_single_jump_
;
int
msg_type_
;
float
scale_
;
int
rows_
,
cols_
;
std
::
vector
<
int
>
cols_all_
,
rows_all_
;
GpuMat
u_
,
d_
,
l_
,
r_
,
u2_
,
d2_
,
l2_
,
r2_
;
std
::
vector
<
GpuMat
>
datas_
;
GpuMat
outBuf_
;
};
const
float
DEFAULT_MAX_DATA_TERM
=
10.0
f
;
const
float
DEFAULT_DATA_WEIGHT
=
0.07
f
;
const
float
DEFAULT_MAX_DISC_TERM
=
1.7
f
;
const
float
DEFAULT_DISC_SINGLE_JUMP
=
1.0
f
;
}
void
cv
::
gpu
::
StereoBeliefPropagation
::
estimateRecommendedParams
(
int
width
,
int
height
,
int
&
ndisp
,
int
&
iters
,
int
&
levels
)
{
ndisp
=
width
/
4
;
if
((
ndisp
&
1
)
!=
0
)
ndisp
++
;
StereoBPImpl
::
StereoBPImpl
(
int
ndisp
,
int
iters
,
int
levels
,
int
msg_type
)
:
ndisp_
(
ndisp
),
iters_
(
iters
),
levels_
(
levels
),
max_data_term_
(
DEFAULT_MAX_DATA_TERM
),
data_weight_
(
DEFAULT_DATA_WEIGHT
),
max_disc_term_
(
DEFAULT_MAX_DISC_TERM
),
disc_single_jump_
(
DEFAULT_DISC_SINGLE_JUMP
),
msg_type_
(
msg_type
)
{
}
int
mm
=
std
::
max
(
width
,
height
);
iters
=
mm
/
100
+
2
;
void
StereoBPImpl
::
compute
(
InputArray
left
,
InputArray
right
,
OutputArray
disparity
)
{
compute
(
left
,
right
,
disparity
,
Stream
::
Null
());
}
levels
=
(
int
)(
::
log
(
static_cast
<
double
>
(
mm
))
+
1
)
*
4
/
5
;
if
(
levels
==
0
)
levels
++
;
}
void
StereoBPImpl
::
compute
(
InputArray
_left
,
InputArray
_right
,
OutputArray
disparity
,
Stream
&
stream
)
{
using
namespace
cv
::
gpu
::
cudev
::
stereobp
;
cv
::
gpu
::
StereoBeliefPropagation
::
StereoBeliefPropagation
(
int
ndisp_
,
int
iters_
,
int
levels_
,
int
msg_type_
)
:
ndisp
(
ndisp_
),
iters
(
iters_
),
levels
(
levels_
),
max_data_term
(
DEFAULT_MAX_DATA_TERM
),
data_weight
(
DEFAULT_DATA_WEIGHT
),
max_disc_term
(
DEFAULT_MAX_DISC_TERM
),
disc_single_jump
(
DEFAULT_DISC_SINGLE_JUMP
),
msg_type
(
msg_type_
),
datas
(
levels_
)
{
}
typedef
void
(
*
comp_data_t
)(
const
PtrStepSzb
&
left
,
const
PtrStepSzb
&
right
,
const
PtrStepSzb
&
data
,
cudaStream_t
stream
);
static
const
comp_data_t
comp_data_callers
[
2
][
5
]
=
{
{
0
,
comp_data_gpu
<
unsigned
char
,
short
>
,
0
,
comp_data_gpu
<
uchar3
,
short
>
,
comp_data_gpu
<
uchar4
,
short
>
},
{
0
,
comp_data_gpu
<
unsigned
char
,
float
>
,
0
,
comp_data_gpu
<
uchar3
,
float
>
,
comp_data_gpu
<
uchar4
,
float
>
}
};
cv
::
gpu
::
StereoBeliefPropagation
::
StereoBeliefPropagation
(
int
ndisp_
,
int
iters_
,
int
levels_
,
float
max_data_term_
,
float
data_weight_
,
float
max_disc_term_
,
float
disc_single_jump_
,
int
msg_type_
)
:
ndisp
(
ndisp_
),
iters
(
iters_
),
levels
(
levels_
),
max_data_term
(
max_data_term_
),
data_weight
(
data_weight_
),
max_disc_term
(
max_disc_term_
),
disc_single_jump
(
disc_single_jump_
),
msg_type
(
msg_type_
),
datas
(
levels_
)
{
}
scale_
=
msg_type_
==
CV_32F
?
1.0
f
:
10.0
f
;
namespace
{
class
StereoBeliefPropagationImpl
{
public
:
StereoBeliefPropagationImpl
(
StereoBeliefPropagation
&
rthis_
,
GpuMat
&
u_
,
GpuMat
&
d_
,
GpuMat
&
l_
,
GpuMat
&
r_
,
GpuMat
&
u2_
,
GpuMat
&
d2_
,
GpuMat
&
l2_
,
GpuMat
&
r2_
,
std
::
vector
<
GpuMat
>&
datas_
,
GpuMat
&
out_
)
:
rthis
(
rthis_
),
u
(
u_
),
d
(
d_
),
l
(
l_
),
r
(
r_
),
u2
(
u2_
),
d2
(
d2_
),
l2
(
l2_
),
r2
(
r2_
),
datas
(
datas_
),
out
(
out_
),
zero
(
Scalar
::
all
(
0
)),
scale
(
rthis_
.
msg_type
==
CV_32F
?
1.0
f
:
10.0
f
)
{
CV_Assert
(
0
<
rthis
.
ndisp
&&
0
<
rthis
.
iters
&&
0
<
rthis
.
levels
);
CV_Assert
(
rthis
.
msg_type
==
CV_32F
||
rthis
.
msg_type
==
CV_16S
);
CV_Assert
(
rthis
.
msg_type
==
CV_32F
||
(
1
<<
(
rthis
.
levels
-
1
))
*
scale
*
rthis
.
max_data_term
<
std
::
numeric_limits
<
short
>::
max
());
}
CV_Assert
(
0
<
ndisp_
&&
0
<
iters_
&&
0
<
levels_
);
CV_Assert
(
msg_type_
==
CV_32F
||
msg_type_
==
CV_16S
);
CV_Assert
(
msg_type_
==
CV_32F
||
(
1
<<
(
levels_
-
1
))
*
scale_
*
max_data_term_
<
std
::
numeric_limits
<
short
>::
max
()
);
void
operator
()(
const
GpuMat
&
left
,
const
GpuMat
&
right
,
GpuMat
&
disp
,
Stream
&
stream
)
{
typedef
void
(
*
comp_data_t
)(
const
PtrStepSzb
&
left
,
const
PtrStepSzb
&
right
,
const
PtrStepSzb
&
data
,
cudaStream_t
stream
);
static
const
comp_data_t
comp_data_callers
[
2
][
5
]
=
{
{
0
,
comp_data_gpu
<
unsigned
char
,
short
>
,
0
,
comp_data_gpu
<
uchar3
,
short
>
,
comp_data_gpu
<
uchar4
,
short
>
},
{
0
,
comp_data_gpu
<
unsigned
char
,
float
>
,
0
,
comp_data_gpu
<
uchar3
,
float
>
,
comp_data_gpu
<
uchar4
,
float
>
}
};
GpuMat
left
=
_left
.
getGpuMat
();
GpuMat
right
=
_right
.
getGpuMat
();
CV_Assert
(
left
.
size
()
==
right
.
size
()
&&
left
.
type
()
==
right
.
type
()
);
CV_Assert
(
left
.
type
()
==
CV_8UC1
||
left
.
type
()
==
CV_8UC3
||
left
.
type
()
==
CV_8UC4
);
CV_Assert
(
left
.
type
()
==
CV_8UC1
||
left
.
type
()
==
CV_8UC3
||
left
.
type
()
==
CV_8UC4
);
CV_Assert
(
left
.
size
()
==
right
.
size
()
&&
left
.
type
()
==
right
.
type
()
);
rows
=
left
.
rows
;
cols
=
left
.
cols
;
rows_
=
left
.
rows
;
cols_
=
left
.
cols
;
int
divisor
=
(
int
)
pow
(
2.
f
,
rthis
.
levels
-
1.0
f
);
int
lowest_cols
=
cols
/
divisor
;
int
lowest_rows
=
rows
/
divisor
;
const
int
min_image_dim_size
=
2
;
CV_Assert
(
std
::
min
(
lowest_cols
,
lowest_rows
)
>
min_image_dim_size
);
const
int
divisor
=
(
int
)
pow
(
2.
f
,
levels_
-
1.0
f
);
const
int
lowest_cols
=
cols_
/
divisor
;
const
int
lowest_rows
=
rows_
/
divisor
;
const
int
min_image_dim_size
=
2
;
CV_Assert
(
std
::
min
(
lowest_cols
,
lowest_rows
)
>
min_image_dim_size
);
init
(
stream
);
init
(
stream
);
datas
[
0
].
create
(
rows
*
rthis
.
ndisp
,
cols
,
rthis
.
msg_type
);
datas_
[
0
].
create
(
rows_
*
ndisp_
,
cols_
,
msg_type_
);
comp_data_callers
[
rthis
.
msg_type
==
CV_32F
][
left
.
channels
()](
left
,
right
,
datas
[
0
],
StreamAccessor
::
getStream
(
stream
));
comp_data_callers
[
msg_type_
==
CV_32F
][
left
.
channels
()](
left
,
right
,
datas_
[
0
],
StreamAccessor
::
getStream
(
stream
));
calcBP
(
disp
,
stream
);
}
calcBP
(
disparity
,
stream
);
}
void
operator
()(
const
GpuMat
&
data
,
GpuMat
&
disp
,
Stream
&
stream
)
{
CV_Assert
((
data
.
type
()
==
rthis
.
msg_type
)
&&
(
data
.
rows
%
rthis
.
ndisp
==
0
))
;
void
StereoBPImpl
::
compute
(
InputArray
_data
,
OutputArray
disparity
,
Stream
&
stream
)
{
scale_
=
msg_type_
==
CV_32F
?
1.0
f
:
10.0
f
;
rows
=
data
.
rows
/
rthis
.
ndisp
;
cols
=
data
.
cols
;
CV_Assert
(
0
<
ndisp_
&&
0
<
iters_
&&
0
<
levels_
);
CV_Assert
(
msg_type_
==
CV_32F
||
msg_type_
==
CV_16S
);
CV_Assert
(
msg_type_
==
CV_32F
||
(
1
<<
(
levels_
-
1
))
*
scale_
*
max_data_term_
<
std
::
numeric_limits
<
short
>::
max
()
);
int
divisor
=
(
int
)
pow
(
2.
f
,
rthis
.
levels
-
1.0
f
);
int
lowest_cols
=
cols
/
divisor
;
int
lowest_rows
=
rows
/
divisor
;
const
int
min_image_dim_size
=
2
;
CV_Assert
(
std
::
min
(
lowest_cols
,
lowest_rows
)
>
min_image_dim_size
);
GpuMat
data
=
_data
.
getGpuMat
();
init
(
stream
);
CV_Assert
(
(
data
.
type
()
==
msg_type_
)
&&
(
data
.
rows
%
ndisp_
==
0
)
);
datas
[
0
]
=
data
;
rows_
=
data
.
rows
/
ndisp_
;
cols_
=
data
.
cols
;
calcBP
(
disp
,
stream
);
}
private
:
void
init
(
Stream
&
stream
)
{
u
.
create
(
rows
*
rthis
.
ndisp
,
cols
,
rthis
.
msg_type
);
d
.
create
(
rows
*
rthis
.
ndisp
,
cols
,
rthis
.
msg_type
);
l
.
create
(
rows
*
rthis
.
ndisp
,
cols
,
rthis
.
msg_type
);
r
.
create
(
rows
*
rthis
.
ndisp
,
cols
,
rthis
.
msg_type
);
const
int
divisor
=
(
int
)
pow
(
2.
f
,
levels_
-
1.0
f
);
const
int
lowest_cols
=
cols_
/
divisor
;
const
int
lowest_rows
=
rows_
/
divisor
;
const
int
min_image_dim_size
=
2
;
CV_Assert
(
std
::
min
(
lowest_cols
,
lowest_rows
)
>
min_image_dim_size
);
if
(
rthis
.
levels
&
1
)
{
//can clear less area
u
.
setTo
(
zero
,
stream
);
d
.
setTo
(
zero
,
stream
);
l
.
setTo
(
zero
,
stream
);
r
.
setTo
(
zero
,
stream
);
}
init
(
stream
);
if
(
rthis
.
levels
>
1
)
{
int
less_rows
=
(
rows
+
1
)
/
2
;
int
less_cols
=
(
cols
+
1
)
/
2
;
u2
.
create
(
less_rows
*
rthis
.
ndisp
,
less_cols
,
rthis
.
msg_type
);
d2
.
create
(
less_rows
*
rthis
.
ndisp
,
less_cols
,
rthis
.
msg_type
);
l2
.
create
(
less_rows
*
rthis
.
ndisp
,
less_cols
,
rthis
.
msg_type
);
r2
.
create
(
less_rows
*
rthis
.
ndisp
,
less_cols
,
rthis
.
msg_type
);
if
((
rthis
.
levels
&
1
)
==
0
)
{
u2
.
setTo
(
zero
,
stream
);
d2
.
setTo
(
zero
,
stream
);
l2
.
setTo
(
zero
,
stream
);
r2
.
setTo
(
zero
,
stream
);
}
}
data
.
copyTo
(
datas_
[
0
],
stream
);
load_constants
(
rthis
.
ndisp
,
rthis
.
max_data_term
,
scale
*
rthis
.
data_weight
,
scale
*
rthis
.
max_disc_term
,
scale
*
rthis
.
disc_single_jump
);
calcBP
(
disparity
,
stream
);
}
datas
.
resize
(
rthis
.
levels
);
void
StereoBPImpl
::
init
(
Stream
&
stream
)
{
using
namespace
cv
::
gpu
::
cudev
::
stereobp
;
cols_all
.
resize
(
rthis
.
levels
);
rows_all
.
resize
(
rthis
.
levels
);
u_
.
create
(
rows_
*
ndisp_
,
cols_
,
msg_type_
);
d_
.
create
(
rows_
*
ndisp_
,
cols_
,
msg_type_
);
l_
.
create
(
rows_
*
ndisp_
,
cols_
,
msg_type_
);
r_
.
create
(
rows_
*
ndisp_
,
cols_
,
msg_type_
);
cols_all
[
0
]
=
cols
;
rows_all
[
0
]
=
rows
;
if
(
levels_
&
1
)
{
//can clear less area
u_
.
setTo
(
0
,
stream
);
d_
.
setTo
(
0
,
stream
);
l_
.
setTo
(
0
,
stream
);
r_
.
setTo
(
0
,
stream
);
}
void
calcBP
(
GpuMat
&
disp
,
Stream
&
stream
)
if
(
levels_
>
1
)
{
typedef
void
(
*
data_step_down_t
)(
int
dst_cols
,
int
dst_rows
,
int
src_rows
,
const
PtrStepSzb
&
src
,
const
PtrStepSzb
&
dst
,
cudaStream_t
stream
);
static
const
data_step_down_t
data_step_down_callers
[
2
]
=
{
data_step_down_gpu
<
short
>
,
data_step_down_gpu
<
float
>
};
int
less_rows
=
(
rows_
+
1
)
/
2
;
int
less_cols
=
(
cols_
+
1
)
/
2
;
typedef
void
(
*
level_up_messages_t
)(
int
dst_idx
,
int
dst_cols
,
int
dst_rows
,
int
src_rows
,
PtrStepSzb
*
mus
,
PtrStepSzb
*
mds
,
PtrStepSzb
*
mls
,
PtrStepSzb
*
mrs
,
cudaStream_t
stream
);
static
const
level_up_messages_t
level_up_messages_callers
[
2
]
=
{
level_up_messages_gpu
<
short
>
,
level_up_messages_gpu
<
float
>
};
u2_
.
create
(
less_rows
*
ndisp_
,
less_cols
,
msg_type_
);
d2_
.
create
(
less_rows
*
ndisp_
,
less_cols
,
msg_type_
);
l2_
.
create
(
less_rows
*
ndisp_
,
less_cols
,
msg_type_
);
r2_
.
create
(
less_rows
*
ndisp_
,
less_cols
,
msg_type_
);
typedef
void
(
*
calc_all_iterations_t
)(
int
cols
,
int
rows
,
int
iters
,
const
PtrStepSzb
&
u
,
const
PtrStepSzb
&
d
,
const
PtrStepSzb
&
l
,
const
PtrStepSzb
&
r
,
const
PtrStepSzb
&
data
,
cudaStream_t
stream
);
static
const
calc_all_iterations_t
calc_all_iterations_callers
[
2
]
=
if
((
levels_
&
1
)
==
0
)
{
calc_all_iterations_gpu
<
short
>
,
calc_all_iterations_gpu
<
float
>
};
u2_
.
setTo
(
0
,
stream
);
d2_
.
setTo
(
0
,
stream
);
l2_
.
setTo
(
0
,
stream
);
r2_
.
setTo
(
0
,
stream
);
}
}
typedef
void
(
*
output_t
)(
const
PtrStepSzb
&
u
,
const
PtrStepSzb
&
d
,
const
PtrStepSzb
&
l
,
const
PtrStepSzb
&
r
,
const
PtrStepSzb
&
data
,
const
PtrStepSz
<
short
>&
disp
,
cudaStream_t
stream
);
static
const
output_t
output_callers
[
2
]
=
{
output_gpu
<
short
>
,
output_gpu
<
float
>
};
load_constants
(
ndisp_
,
max_data_term_
,
scale_
*
data_weight_
,
scale_
*
max_disc_term_
,
scale_
*
disc_single_jump_
);
const
int
funcIdx
=
rthis
.
msg_type
==
CV_32F
;
datas_
.
resize
(
levels_
)
;
cudaStream_t
cudaStream
=
StreamAccessor
::
getStream
(
stream
);
cols_all_
.
resize
(
levels_
);
rows_all_
.
resize
(
levels_
);
for
(
int
i
=
1
;
i
<
rthis
.
levels
;
++
i
)
{
cols_all
[
i
]
=
(
cols_all
[
i
-
1
]
+
1
)
/
2
;
rows_all
[
i
]
=
(
rows_all
[
i
-
1
]
+
1
)
/
2
;
cols_all_
[
0
]
=
cols_
;
rows_all_
[
0
]
=
rows_
;
}
datas
[
i
].
create
(
rows_all
[
i
]
*
rthis
.
ndisp
,
cols_all
[
i
],
rthis
.
msg_type
);
void
StereoBPImpl
::
calcBP
(
OutputArray
disp
,
Stream
&
_stream
)
{
using
namespace
cv
::
gpu
::
cudev
::
stereobp
;
data_step_down_callers
[
funcIdx
](
cols_all
[
i
],
rows_all
[
i
],
rows_all
[
i
-
1
],
datas
[
i
-
1
],
datas
[
i
],
cudaStream
);
}
typedef
void
(
*
data_step_down_t
)(
int
dst_cols
,
int
dst_rows
,
int
src_rows
,
const
PtrStepSzb
&
src
,
const
PtrStepSzb
&
dst
,
cudaStream_t
stream
);
static
const
data_step_down_t
data_step_down_callers
[
2
]
=
{
data_step_down_gpu
<
short
>
,
data_step_down_gpu
<
float
>
};
PtrStepSzb
mus
[]
=
{
u
,
u2
};
PtrStepSzb
mds
[]
=
{
d
,
d2
};
PtrStepSzb
mrs
[]
=
{
r
,
r2
};
PtrStepSzb
mls
[]
=
{
l
,
l2
};
typedef
void
(
*
level_up_messages_t
)(
int
dst_idx
,
int
dst_cols
,
int
dst_rows
,
int
src_rows
,
PtrStepSzb
*
mus
,
PtrStepSzb
*
mds
,
PtrStepSzb
*
mls
,
PtrStepSzb
*
mrs
,
cudaStream_t
stream
);
static
const
level_up_messages_t
level_up_messages_callers
[
2
]
=
{
level_up_messages_gpu
<
short
>
,
level_up_messages_gpu
<
float
>
};
int
mem_idx
=
(
rthis
.
levels
&
1
)
?
0
:
1
;
typedef
void
(
*
calc_all_iterations_t
)(
int
cols
,
int
rows
,
int
iters
,
const
PtrStepSzb
&
u
,
const
PtrStepSzb
&
d
,
const
PtrStepSzb
&
l
,
const
PtrStepSzb
&
r
,
const
PtrStepSzb
&
data
,
cudaStream_t
stream
);
static
const
calc_all_iterations_t
calc_all_iterations_callers
[
2
]
=
{
calc_all_iterations_gpu
<
short
>
,
calc_all_iterations_gpu
<
float
>
};
for
(
int
i
=
rthis
.
levels
-
1
;
i
>=
0
;
--
i
)
{
// for lower level we have already computed messages by setting to zero
if
(
i
!=
rthis
.
levels
-
1
)
level_up_messages_callers
[
funcIdx
](
mem_idx
,
cols_all
[
i
],
rows_all
[
i
],
rows_all
[
i
+
1
],
mus
,
mds
,
mls
,
mrs
,
cudaStream
)
;
typedef
void
(
*
output_t
)(
const
PtrStepSzb
&
u
,
const
PtrStepSzb
&
d
,
const
PtrStepSzb
&
l
,
const
PtrStepSzb
&
r
,
const
PtrStepSzb
&
data
,
const
PtrStepSz
<
short
>&
disp
,
cudaStream_t
stream
);
static
const
output_t
output_callers
[
2
]
=
{
output_gpu
<
short
>
,
output_gpu
<
float
>
}
;
calc_all_iterations_callers
[
funcIdx
](
cols_all
[
i
],
rows_all
[
i
],
rthis
.
iters
,
mus
[
mem_idx
],
mds
[
mem_idx
],
mls
[
mem_idx
],
mrs
[
mem_idx
],
datas
[
i
],
cudaStream
)
;
const
int
funcIdx
=
msg_type_
==
CV_32F
;
mem_idx
=
(
mem_idx
+
1
)
&
1
;
}
cudaStream_t
stream
=
StreamAccessor
::
getStream
(
_stream
);
if
(
disp
.
empty
())
disp
.
create
(
rows
,
cols
,
CV_16S
);
for
(
int
i
=
1
;
i
<
levels_
;
++
i
)
{
cols_all_
[
i
]
=
(
cols_all_
[
i
-
1
]
+
1
)
/
2
;
rows_all_
[
i
]
=
(
rows_all_
[
i
-
1
]
+
1
)
/
2
;
out
=
((
disp
.
type
()
==
CV_16S
)
?
disp
:
(
out
.
create
(
rows
,
cols
,
CV_16S
),
out
)
);
datas_
[
i
].
create
(
rows_all_
[
i
]
*
ndisp_
,
cols_all_
[
i
],
msg_type_
);
out
.
setTo
(
zero
,
stream
);
data_step_down_callers
[
funcIdx
](
cols_all_
[
i
],
rows_all_
[
i
],
rows_all_
[
i
-
1
],
datas_
[
i
-
1
],
datas_
[
i
],
stream
);
}
output_callers
[
funcIdx
](
u
,
d
,
l
,
r
,
datas
.
front
(),
out
,
cudaStream
);
PtrStepSzb
mus
[]
=
{
u_
,
u2_
};
PtrStepSzb
mds
[]
=
{
d_
,
d2_
};
PtrStepSzb
mrs
[]
=
{
r_
,
r2_
};
PtrStepSzb
mls
[]
=
{
l_
,
l2_
};
if
(
disp
.
type
()
!=
CV_16S
)
out
.
convertTo
(
disp
,
disp
.
type
(),
stream
);
}
int
mem_idx
=
(
levels_
&
1
)
?
0
:
1
;
StereoBeliefPropagation
&
rthis
;
for
(
int
i
=
levels_
-
1
;
i
>=
0
;
--
i
)
{
// for lower level we have already computed messages by setting to zero
if
(
i
!=
levels_
-
1
)
level_up_messages_callers
[
funcIdx
](
mem_idx
,
cols_all_
[
i
],
rows_all_
[
i
],
rows_all_
[
i
+
1
],
mus
,
mds
,
mls
,
mrs
,
stream
);
calc_all_iterations_callers
[
funcIdx
](
cols_all_
[
i
],
rows_all_
[
i
],
iters_
,
mus
[
mem_idx
],
mds
[
mem_idx
],
mls
[
mem_idx
],
mrs
[
mem_idx
],
datas_
[
i
],
stream
);
GpuMat
&
u
;
GpuMat
&
d
;
GpuMat
&
l
;
GpuMat
&
r
;
mem_idx
=
(
mem_idx
+
1
)
&
1
;
}
GpuMat
&
u2
;
GpuMat
&
d2
;
GpuMat
&
l2
;
GpuMat
&
r2
;
const
int
dtype
=
disp
.
fixedType
()
?
disp
.
type
()
:
CV_16SC1
;
std
::
vector
<
GpuMat
>&
datas
;
GpuMat
&
out
;
disp
.
create
(
rows_
,
cols_
,
dtype
)
;
GpuMat
out
=
disp
.
getGpuMat
()
;
const
Scalar
zero
;
const
float
scale
;
if
(
dtype
!=
CV_16SC1
)
{
outBuf_
.
create
(
rows_
,
cols_
,
CV_16SC1
);
out
=
outBuf_
;
}
int
rows
,
cols
;
out
.
setTo
(
0
,
_stream
)
;
std
::
vector
<
int
>
cols_all
,
rows_all
;
};
output_callers
[
funcIdx
](
u_
,
d_
,
l_
,
r_
,
datas_
.
front
(),
out
,
stream
);
if
(
dtype
!=
CV_16SC1
)
out
.
convertTo
(
disp
,
dtype
,
_stream
);
}
}
void
cv
::
gpu
::
StereoBeliefPropagation
::
operator
()(
const
GpuMat
&
left
,
const
GpuMat
&
right
,
GpuMat
&
disp
,
Stream
&
stream
)
Ptr
<
gpu
::
StereoBeliefPropagation
>
cv
::
gpu
::
createStereoBeliefPropagation
(
int
ndisp
,
int
iters
,
int
levels
,
int
msg_type
)
{
StereoBeliefPropagationImpl
impl
(
*
this
,
u
,
d
,
l
,
r
,
u2
,
d2
,
l2
,
r2
,
datas
,
out
);
impl
(
left
,
right
,
disp
,
stream
);
return
new
StereoBPImpl
(
ndisp
,
iters
,
levels
,
msg_type
);
}
void
cv
::
gpu
::
StereoBeliefPropagation
::
operator
()(
const
GpuMat
&
data
,
GpuMat
&
disp
,
Stream
&
stream
)
void
cv
::
gpu
::
StereoBeliefPropagation
::
estimateRecommendedParams
(
int
width
,
int
height
,
int
&
ndisp
,
int
&
iters
,
int
&
levels
)
{
StereoBeliefPropagationImpl
impl
(
*
this
,
u
,
d
,
l
,
r
,
u2
,
d2
,
l2
,
r2
,
datas
,
out
);
impl
(
data
,
disp
,
stream
);
ndisp
=
width
/
4
;
if
((
ndisp
&
1
)
!=
0
)
ndisp
++
;
int
mm
=
std
::
max
(
width
,
height
);
iters
=
mm
/
100
+
2
;
levels
=
(
int
)(
::
log
(
static_cast
<
double
>
(
mm
))
+
1
)
*
4
/
5
;
if
(
levels
==
0
)
levels
++
;
}
#endif
/* !defined (HAVE_CUDA) */
modules/gpustereo/test/test_stereo.cpp
View file @
d0e89337
...
...
@@ -106,10 +106,15 @@ GPU_TEST_P(StereoBeliefPropagation, Regression)
ASSERT_FALSE
(
right_image
.
empty
());
ASSERT_FALSE
(
disp_gold
.
empty
());
cv
::
gpu
::
StereoBeliefPropagation
bp
(
64
,
8
,
2
,
25
,
0.1
f
,
15
,
1
,
CV_16S
);
cv
::
Ptr
<
cv
::
gpu
::
StereoBeliefPropagation
>
bp
=
cv
::
gpu
::
createStereoBeliefPropagation
(
64
,
8
,
2
,
CV_16S
);
bp
->
setMaxDataTerm
(
25.0
);
bp
->
setDataWeight
(
0.1
);
bp
->
setMaxDiscTerm
(
15.0
);
bp
->
setDiscSingleJump
(
1.0
);
cv
::
gpu
::
GpuMat
disp
;
bp
(
loadMat
(
left_image
),
loadMat
(
right_image
),
disp
);
bp
->
compute
(
loadMat
(
left_image
),
loadMat
(
right_image
),
disp
);
cv
::
Mat
h_disp
(
disp
);
h_disp
.
convertTo
(
h_disp
,
disp_gold
.
depth
());
...
...
samples/gpu/stereo_match.cpp
View file @
d0e89337
...
...
@@ -66,7 +66,7 @@ private:
gpu
::
GpuMat
d_left
,
d_right
;
Ptr
<
gpu
::
StereoBM
>
bm
;
gpu
::
StereoBeliefPropagation
bp
;
Ptr
<
gpu
::
StereoBeliefPropagation
>
bp
;
gpu
::
StereoConstantSpaceBP
csbp
;
int64
work_begin
;
...
...
@@ -173,7 +173,7 @@ void App::run()
// Set common parameters
bm
=
gpu
::
createStereoBM
(
p
.
ndisp
);
bp
.
ndisp
=
p
.
ndisp
;
bp
=
gpu
::
createStereoBeliefPropagation
(
p
.
ndisp
)
;
csbp
.
ndisp
=
p
.
ndisp
;
// Prepare disparity map of specified type
...
...
@@ -203,7 +203,7 @@ void App::run()
}
bm
->
compute
(
d_left
,
d_right
,
d_disp
);
break
;
case
Params
:
:
BP
:
bp
(
d_left
,
d_right
,
d_disp
);
break
;
case
Params
:
:
BP
:
bp
->
compute
(
d_left
,
d_right
,
d_disp
);
break
;
case
Params
:
:
CSBP
:
csbp
(
d_left
,
d_right
,
d_disp
);
break
;
}
workEnd
();
...
...
@@ -232,8 +232,8 @@ void App::printParams() const
cout
<<
"prefilter_sobel: "
<<
bm
->
getPreFilterType
()
<<
endl
;
break
;
case
Params
:
:
BP
:
cout
<<
"iter_count: "
<<
bp
.
iters
<<
endl
;
cout
<<
"level_count: "
<<
bp
.
levels
<<
endl
;
cout
<<
"iter_count: "
<<
bp
->
getNumIters
()
<<
endl
;
cout
<<
"level_count: "
<<
bp
->
getNumLevels
()
<<
endl
;
break
;
case
Params
:
:
CSBP
:
cout
<<
"iter_count: "
<<
csbp
.
iters
<<
endl
;
...
...
@@ -305,14 +305,14 @@ void App::handleKey(char key)
p
.
ndisp
=
p
.
ndisp
==
1
?
8
:
p
.
ndisp
+
8
;
cout
<<
"ndisp: "
<<
p
.
ndisp
<<
endl
;
bm
->
setNumDisparities
(
p
.
ndisp
);
bp
.
ndisp
=
p
.
ndisp
;
bp
->
setNumDisparities
(
p
.
ndisp
)
;
csbp
.
ndisp
=
p
.
ndisp
;
break
;
case
'q'
:
case
'Q'
:
p
.
ndisp
=
max
(
p
.
ndisp
-
8
,
1
);
cout
<<
"ndisp: "
<<
p
.
ndisp
<<
endl
;
bm
->
setNumDisparities
(
p
.
ndisp
);
bp
.
ndisp
=
p
.
ndisp
;
bp
->
setNumDisparities
(
p
.
ndisp
)
;
csbp
.
ndisp
=
p
.
ndisp
;
break
;
case
'2'
:
...
...
@@ -332,8 +332,8 @@ void App::handleKey(char key)
case
'3'
:
if
(
p
.
method
==
Params
::
BP
)
{
bp
.
iters
+=
1
;
cout
<<
"iter_count: "
<<
bp
.
iters
<<
endl
;
bp
->
setNumIters
(
bp
->
getNumIters
()
+
1
)
;
cout
<<
"iter_count: "
<<
bp
->
getNumIters
()
<<
endl
;
}
else
if
(
p
.
method
==
Params
::
CSBP
)
{
...
...
@@ -344,8 +344,8 @@ void App::handleKey(char key)
case
'e'
:
case
'E'
:
if
(
p
.
method
==
Params
::
BP
)
{
bp
.
iters
=
max
(
bp
.
iters
-
1
,
1
);
cout
<<
"iter_count: "
<<
bp
.
iters
<<
endl
;
bp
->
setNumIters
(
max
(
bp
->
getNumIters
()
-
1
,
1
)
);
cout
<<
"iter_count: "
<<
bp
->
getNumIters
()
<<
endl
;
}
else
if
(
p
.
method
==
Params
::
CSBP
)
{
...
...
@@ -356,8 +356,8 @@ void App::handleKey(char key)
case
'4'
:
if
(
p
.
method
==
Params
::
BP
)
{
bp
.
levels
+=
1
;
cout
<<
"level_count: "
<<
bp
.
levels
<<
endl
;
bp
->
setNumLevels
(
bp
->
getNumLevels
()
+
1
)
;
cout
<<
"level_count: "
<<
bp
->
getNumLevels
()
<<
endl
;
}
else
if
(
p
.
method
==
Params
::
CSBP
)
{
...
...
@@ -368,8 +368,8 @@ void App::handleKey(char key)
case
'r'
:
case
'R'
:
if
(
p
.
method
==
Params
::
BP
)
{
bp
.
levels
=
max
(
bp
.
levels
-
1
,
1
);
cout
<<
"level_count: "
<<
bp
.
levels
<<
endl
;
bp
->
setNumLevels
(
max
(
bp
->
getNumLevels
()
-
1
,
1
)
);
cout
<<
"level_count: "
<<
bp
->
getNumLevels
()
<<
endl
;
}
else
if
(
p
.
method
==
Params
::
CSBP
)
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment