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
b2cdb7fa
Commit
b2cdb7fa
authored
Sep 20, 2010
by
Alexey Spizhevoy
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
implemented cv::gpu::merge and cv::gpu::split functions
parent
5a804717
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
451 additions
and
0 deletions
+451
-0
gpu.hpp
modules/gpu/include/opencv2/gpu/gpu.hpp
+24
-0
split_merge.cu
modules/gpu/src/cuda/split_merge.cu
+0
-0
split_merge.cpp
modules/gpu/src/split_merge.cpp
+152
-0
split_merge.cpp
tests/gpu/src/split_merge.cpp
+275
-0
No files found.
modules/gpu/include/opencv2/gpu/gpu.hpp
View file @
b2cdb7fa
...
...
@@ -408,6 +408,30 @@ namespace cv
//! Supports INTER_NEAREST, INTER_LINEAR, INTER_CUBIC
CV_EXPORTS
void
rotate
(
const
GpuMat
&
src
,
GpuMat
&
dst
,
Size
dsize
,
double
angle
,
double
xShift
=
0
,
double
yShift
=
0
,
int
interpolation
=
INTER_LINEAR
);
//! makes multi-channel array out of several single-channel arrays
CV_EXPORTS
void
merge
(
const
GpuMat
*
src
,
size_t
n
,
GpuMat
&
dst
);
//! makes multi-channel array out of several single-channel arrays
CV_EXPORTS
void
merge
(
const
vector
<
GpuMat
>&
src
,
GpuMat
&
dst
);
//! makes multi-channel array out of several single-channel arrays (async version)
CV_EXPORTS
void
merge
(
const
GpuMat
*
src
,
size_t
n
,
GpuMat
&
dst
,
const
Stream
&
stream
);
//! makes multi-channel array out of several single-channel arrays (async version)
CV_EXPORTS
void
merge
(
const
vector
<
GpuMat
>&
src
,
GpuMat
&
dst
,
const
Stream
&
stream
);
//! copies each plane of a multi-channel array to a dedicated array
CV_EXPORTS
void
split
(
const
GpuMat
&
src
,
GpuMat
*
dst
);
//! copies each plane of a multi-channel array to a dedicated array
CV_EXPORTS
void
split
(
const
GpuMat
&
src
,
vector
<
GpuMat
>&
dst
);
//! copies each plane of a multi-channel array to a dedicated array (async version)
CV_EXPORTS
void
split
(
const
GpuMat
&
src
,
GpuMat
*
dst
,
const
Stream
&
stream
);
//! copies each plane of a multi-channel array to a dedicated array (async version)
CV_EXPORTS
void
split
(
const
GpuMat
&
src
,
vector
<
GpuMat
>&
dst
,
const
Stream
&
stream
);
////////////////////////////// Image processing //////////////////////////////
// DST[x,y] = SRC[xmap[x,y],ymap[x,y]] with bilinear interpolation.
...
...
modules/gpu/src/cuda/split_merge.cu
0 → 100644
View file @
b2cdb7fa
This diff is collapsed.
Click to expand it.
modules/gpu/src/split_merge.cpp
0 → 100644
View file @
b2cdb7fa
#include "precomp.hpp"
#include <vector>
using
namespace
std
;
#if !defined (HAVE_CUDA)
void
cv
::
gpu
::
merge
(
const
GpuMat
*
/*src*/
,
size_t
/*count*/
,
GpuMat
&
/*dst*/
)
{
throw_nogpu
();
}
void
cv
::
gpu
::
merge
(
const
vector
<
GpuMat
>&
/*src*/
,
GpuMat
&
/*dst*/
)
{
throw_nogpu
();
}
void
cv
::
gpu
::
merge
(
const
GpuMat
*
/*src*/
,
size_t
/*count*/
,
GpuMat
&
/*dst*/
,
const
Stream
&
/*stream*/
)
{
throw_nogpu
();
}
void
cv
::
gpu
::
merge
(
const
vector
<
GpuMat
>&
/*src*/
,
GpuMat
&
/*dst*/
,
const
Stream
&
/*stream*/
)
{
throw_nogpu
();
}
void
cv
::
gpu
::
split
(
const
GpuMat
&
/*src*/
,
GpuMat
*
/*dst*/
)
{
throw_nogpu
();
}
void
cv
::
gpu
::
split
(
const
GpuMat
&
/*src*/
,
vector
<
GpuMat
>&
/*dst*/
)
{
throw_nogpu
();
}
void
cv
::
gpu
::
split
(
const
GpuMat
&
/*src*/
,
GpuMat
*
/*dst*/
,
const
Stream
&
/*stream*/
)
{
throw_nogpu
();
}
void
cv
::
gpu
::
split
(
const
GpuMat
&
/*src*/
,
vector
<
GpuMat
>&
/*dst*/
,
const
Stream
&
/*stream*/
)
{
throw_nogpu
();
}
#else
/* !defined (HAVE_CUDA) */
namespace
cv
{
namespace
gpu
{
namespace
split_merge
{
extern
"C"
void
merge_caller
(
const
DevMem2D
*
src
,
DevMem2D
&
dst
,
int
total_channels
,
int
elem_size
,
const
cudaStream_t
&
stream
);
extern
"C"
void
split_caller
(
const
DevMem2D
&
src
,
DevMem2D
*
dst
,
int
num_channels
,
int
elem_size1
,
const
cudaStream_t
&
stream
);
void
merge
(
const
GpuMat
*
src
,
size_t
n
,
GpuMat
&
dst
,
const
cudaStream_t
&
stream
)
{
CV_Assert
(
src
);
CV_Assert
(
n
>
0
);
int
depth
=
src
[
0
].
depth
();
Size
size
=
src
[
0
].
size
();
bool
single_channel_only
=
true
;
int
total_channels
=
0
;
for
(
size_t
i
=
0
;
i
<
n
;
++
i
)
{
CV_Assert
(
src
[
i
].
size
()
==
size
);
CV_Assert
(
src
[
i
].
depth
()
==
depth
);
single_channel_only
=
single_channel_only
&&
src
[
i
].
channels
()
==
1
;
total_channels
+=
src
[
i
].
channels
();
}
CV_Assert
(
single_channel_only
);
CV_Assert
(
total_channels
<=
4
);
if
(
total_channels
==
1
)
src
[
0
].
copyTo
(
dst
);
else
{
dst
.
create
(
size
,
CV_MAKETYPE
(
depth
,
total_channels
));
DevMem2D
src_as_devmem
[
4
];
for
(
size_t
i
=
0
;
i
<
n
;
++
i
)
src_as_devmem
[
i
]
=
src
[
i
];
split_merge
::
merge_caller
(
src_as_devmem
,
(
DevMem2D
)
dst
,
total_channels
,
CV_ELEM_SIZE
(
depth
),
stream
);
}
}
void
split
(
const
GpuMat
&
src
,
GpuMat
*
dst
,
const
cudaStream_t
&
stream
)
{
CV_Assert
(
dst
);
int
depth
=
src
.
depth
();
int
num_channels
=
src
.
channels
();
Size
size
=
src
.
size
();
if
(
num_channels
==
1
)
{
src
.
copyTo
(
dst
[
0
]);
return
;
}
for
(
int
i
=
0
;
i
<
num_channels
;
++
i
)
dst
[
i
].
create
(
src
.
size
(),
depth
);
CV_Assert
(
num_channels
<=
4
);
DevMem2D
dst_as_devmem
[
4
];
for
(
int
i
=
0
;
i
<
num_channels
;
++
i
)
dst_as_devmem
[
i
]
=
dst
[
i
];
split_merge
::
split_caller
((
DevMem2D
)
src
,
dst_as_devmem
,
num_channels
,
src
.
elemSize1
(),
stream
);
}
}}}
void
cv
::
gpu
::
merge
(
const
GpuMat
*
src
,
size_t
n
,
GpuMat
&
dst
)
{
split_merge
::
merge
(
src
,
n
,
dst
,
0
);
}
void
cv
::
gpu
::
merge
(
const
vector
<
GpuMat
>&
src
,
GpuMat
&
dst
)
{
split_merge
::
merge
(
&
src
[
0
],
src
.
size
(),
dst
,
0
);
}
void
cv
::
gpu
::
merge
(
const
GpuMat
*
src
,
size_t
n
,
GpuMat
&
dst
,
const
Stream
&
stream
)
{
split_merge
::
merge
(
src
,
n
,
dst
,
StreamAccessor
::
getStream
(
stream
));
}
void
cv
::
gpu
::
merge
(
const
vector
<
GpuMat
>&
src
,
GpuMat
&
dst
,
const
Stream
&
stream
)
{
split_merge
::
merge
(
&
src
[
0
],
src
.
size
(),
dst
,
StreamAccessor
::
getStream
(
stream
));
}
void
cv
::
gpu
::
split
(
const
GpuMat
&
src
,
GpuMat
*
dst
)
{
split_merge
::
split
(
src
,
dst
,
0
);
}
void
cv
::
gpu
::
split
(
const
GpuMat
&
src
,
vector
<
GpuMat
>&
dst
)
{
dst
.
resize
(
src
.
channels
());
if
(
src
.
channels
()
>
0
)
split_merge
::
split
(
src
,
&
dst
[
0
],
0
);
}
void
cv
::
gpu
::
split
(
const
GpuMat
&
src
,
GpuMat
*
dst
,
const
Stream
&
stream
)
{
split_merge
::
split
(
src
,
dst
,
StreamAccessor
::
getStream
(
stream
));
}
void
cv
::
gpu
::
split
(
const
GpuMat
&
src
,
vector
<
GpuMat
>&
dst
,
const
Stream
&
stream
)
{
dst
.
resize
(
src
.
channels
());
if
(
src
.
channels
()
>
0
)
split_merge
::
split
(
src
,
&
dst
[
0
],
StreamAccessor
::
getStream
(
stream
));
}
#endif
/* !defined (HAVE_CUDA) */
\ No newline at end of file
tests/gpu/src/split_merge.cpp
0 → 100644
View file @
b2cdb7fa
#include "gputest.hpp"
#include <opencv2/opencv.hpp>
#include <opencv2/gpu/gpu.hpp>
#include <iostream>
#include <string>
#include <vector>
using
namespace
std
;
using
namespace
cv
;
struct
CV_MergeTest
:
public
CvTest
{
CV_MergeTest
()
:
CvTest
(
"GPU-Merge"
,
"merge"
)
{}
void
can_merge
(
size_t
rows
,
size_t
cols
);
void
can_merge_submatrixes
(
size_t
rows
,
size_t
cols
);
void
run
(
int
);
}
merge_test
;
void
CV_MergeTest
::
can_merge
(
size_t
rows
,
size_t
cols
)
{
for
(
size_t
num_channels
=
1
;
num_channels
<=
4
;
++
num_channels
)
for
(
size_t
depth
=
CV_8U
;
depth
<=
CV_64F
;
++
depth
)
{
vector
<
Mat
>
src
;
for
(
size_t
i
=
0
;
i
<
num_channels
;
++
i
)
src
.
push_back
(
Mat
(
rows
,
cols
,
depth
,
Scalar
::
all
(
static_cast
<
double
>
(
i
))));
Mat
dst
(
rows
,
cols
,
CV_MAKETYPE
(
depth
,
num_channels
));
cv
::
merge
(
src
,
dst
);
vector
<
gpu
::
GpuMat
>
dev_src
;
for
(
size_t
i
=
0
;
i
<
num_channels
;
++
i
)
dev_src
.
push_back
(
gpu
::
GpuMat
(
src
[
i
]));
gpu
::
GpuMat
dev_dst
(
rows
,
cols
,
CV_MAKETYPE
(
depth
,
num_channels
));
cv
::
gpu
::
merge
(
dev_src
,
dev_dst
);
Mat
host_dst
=
dev_dst
;
double
err
=
norm
(
dst
,
host_dst
,
NORM_INF
);
if
(
err
>
1e-3
)
{
//ts->printf(CvTS::CONSOLE, "\nNorm: %f\n", err);
//ts->printf(CvTS::CONSOLE, "Depth: %d\n", depth);
//ts->printf(CvTS::CONSOLE, "Rows: %d\n", rows);
//ts->printf(CvTS::CONSOLE, "Cols: %d\n", cols);
//ts->printf(CvTS::CONSOLE, "NumChannels: %d\n", num_channels);
ts
->
set_failed_test_info
(
CvTS
::
FAIL_INVALID_OUTPUT
);
return
;
}
}
}
void
CV_MergeTest
::
can_merge_submatrixes
(
size_t
rows
,
size_t
cols
)
{
for
(
size_t
num_channels
=
1
;
num_channels
<=
4
;
++
num_channels
)
for
(
size_t
depth
=
CV_8U
;
depth
<=
CV_64F
;
++
depth
)
{
vector
<
Mat
>
src
;
for
(
size_t
i
=
0
;
i
<
num_channels
;
++
i
)
{
Mat
m
(
rows
*
2
,
cols
*
2
,
depth
,
Scalar
::
all
(
static_cast
<
double
>
(
i
)));
src
.
push_back
(
m
(
Range
(
rows
/
2
,
rows
/
2
+
rows
),
Range
(
cols
/
2
,
cols
/
2
+
cols
)));
}
Mat
dst
(
rows
,
cols
,
CV_MAKETYPE
(
depth
,
num_channels
));
cv
::
merge
(
src
,
dst
);
vector
<
gpu
::
GpuMat
>
dev_src
;
for
(
size_t
i
=
0
;
i
<
num_channels
;
++
i
)
dev_src
.
push_back
(
gpu
::
GpuMat
(
src
[
i
]));
gpu
::
GpuMat
dev_dst
(
rows
,
cols
,
CV_MAKETYPE
(
depth
,
num_channels
));
cv
::
gpu
::
merge
(
dev_src
,
dev_dst
);
Mat
host_dst
=
dev_dst
;
double
err
=
norm
(
dst
,
host_dst
,
NORM_INF
);
if
(
err
>
1e-3
)
{
//ts->printf(CvTS::CONSOLE, "\nNorm: %f\n", err);
//ts->printf(CvTS::CONSOLE, "Depth: %d\n", depth);
//ts->printf(CvTS::CONSOLE, "Rows: %d\n", rows);
//ts->printf(CvTS::CONSOLE, "Cols: %d\n", cols);
//ts->printf(CvTS::CONSOLE, "NumChannels: %d\n", num_channels);
ts
->
set_failed_test_info
(
CvTS
::
FAIL_INVALID_OUTPUT
);
return
;
}
}
}
void
CV_MergeTest
::
run
(
int
)
{
try
{
can_merge
(
1
,
1
);
can_merge
(
1
,
7
);
can_merge
(
53
,
7
);
can_merge_submatrixes
(
1
,
1
);
can_merge_submatrixes
(
1
,
7
);
can_merge_submatrixes
(
53
,
7
);
}
catch
(
const
cv
::
Exception
&
e
)
{
if
(
!
check_and_treat_gpu_exception
(
e
,
ts
))
throw
;
}
}
struct
CV_SplitTest
:
public
CvTest
{
CV_SplitTest
()
:
CvTest
(
"GPU-Split"
,
"split"
)
{}
void
can_split
(
size_t
rows
,
size_t
cols
);
void
can_split_submatrix
(
size_t
rows
,
size_t
cols
);
void
run
(
int
);
}
split_test
;
void
CV_SplitTest
::
can_split
(
size_t
rows
,
size_t
cols
)
{
for
(
size_t
num_channels
=
1
;
num_channels
<=
4
;
++
num_channels
)
for
(
size_t
depth
=
CV_8U
;
depth
<=
CV_64F
;
++
depth
)
{
Mat
src
(
rows
,
cols
,
CV_MAKETYPE
(
depth
,
num_channels
),
Scalar
(
1.0
,
2.0
,
3.0
,
4.0
));
vector
<
Mat
>
dst
;
cv
::
split
(
src
,
dst
);
gpu
::
GpuMat
dev_src
(
src
);
vector
<
gpu
::
GpuMat
>
dev_dst
;
cv
::
gpu
::
split
(
dev_src
,
dev_dst
);
if
(
dev_dst
.
size
()
!=
dst
.
size
())
{
ts
->
printf
(
CvTS
::
CONSOLE
,
"Bad output sizes"
);
ts
->
set_failed_test_info
(
CvTS
::
FAIL_INVALID_OUTPUT
);
}
for
(
size_t
i
=
0
;
i
<
num_channels
;
++
i
)
{
Mat
host_dst
=
dev_dst
[
i
];
double
err
=
norm
(
dst
[
i
],
host_dst
,
NORM_INF
);
if
(
err
>
1e-3
)
{
//ts->printf(CvTS::CONSOLE, "\nNorm: %f\n", err);
//ts->printf(CvTS::CONSOLE, "Depth: %d\n", depth);
//ts->printf(CvTS::CONSOLE, "Rows: %d\n", rows);
//ts->printf(CvTS::CONSOLE, "Cols: %d\n", cols);
//ts->printf(CvTS::CONSOLE, "NumChannels: %d\n", num_channels);
ts
->
set_failed_test_info
(
CvTS
::
FAIL_INVALID_OUTPUT
);
return
;
}
}
}
}
void
CV_SplitTest
::
can_split_submatrix
(
size_t
rows
,
size_t
cols
)
{
for
(
size_t
num_channels
=
1
;
num_channels
<=
4
;
++
num_channels
)
for
(
size_t
depth
=
CV_8U
;
depth
<=
CV_64F
;
++
depth
)
{
Mat
src_data
(
rows
*
2
,
cols
*
2
,
CV_MAKETYPE
(
depth
,
num_channels
),
Scalar
(
1.0
,
2.0
,
3.0
,
4.0
));
Mat
src
(
src_data
(
Range
(
rows
/
2
,
rows
/
2
+
rows
),
Range
(
cols
/
2
,
cols
/
2
+
cols
)));
vector
<
Mat
>
dst
;
cv
::
split
(
src
,
dst
);
gpu
::
GpuMat
dev_src
(
src
);
vector
<
gpu
::
GpuMat
>
dev_dst
;
cv
::
gpu
::
split
(
dev_src
,
dev_dst
);
if
(
dev_dst
.
size
()
!=
dst
.
size
())
{
ts
->
printf
(
CvTS
::
CONSOLE
,
"Bad output sizes"
);
ts
->
set_failed_test_info
(
CvTS
::
FAIL_INVALID_OUTPUT
);
}
for
(
size_t
i
=
0
;
i
<
num_channels
;
++
i
)
{
Mat
host_dst
=
dev_dst
[
i
];
double
err
=
norm
(
dst
[
i
],
host_dst
,
NORM_INF
);
if
(
err
>
1e-3
)
{
//ts->printf(CvTS::CONSOLE, "\nNorm: %f\n", err);
//ts->printf(CvTS::CONSOLE, "Depth: %d\n", depth);
//ts->printf(CvTS::CONSOLE, "Rows: %d\n", rows);
//ts->printf(CvTS::CONSOLE, "Cols: %d\n", cols);
//ts->printf(CvTS::CONSOLE, "NumChannels: %d\n", num_channels);
ts
->
set_failed_test_info
(
CvTS
::
FAIL_INVALID_OUTPUT
);
return
;
}
}
}
}
void
CV_SplitTest
::
run
(
int
)
{
try
{
can_split
(
1
,
1
);
can_split
(
1
,
7
);
can_split
(
7
,
53
);
can_split_submatrix
(
1
,
1
);
can_split_submatrix
(
1
,
7
);
can_split_submatrix
(
7
,
53
);
}
catch
(
const
cv
::
Exception
&
e
)
{
if
(
!
check_and_treat_gpu_exception
(
e
,
ts
))
throw
;
}
}
struct
CV_SplitMergeTest
:
public
CvTest
{
CV_SplitMergeTest
()
:
CvTest
(
"GPU-SplitMerge"
,
"split merge"
)
{}
void
can_split_merge
(
size_t
rows
,
size_t
cols
);
void
run
(
int
);
}
split_merge_test
;
void
CV_SplitMergeTest
::
can_split_merge
(
size_t
rows
,
size_t
cols
)
{
for
(
size_t
num_channels
=
1
;
num_channels
<=
4
;
++
num_channels
)
for
(
size_t
depth
=
CV_8U
;
depth
<=
CV_64F
;
++
depth
)
{
Mat
orig
(
rows
,
cols
,
CV_MAKETYPE
(
depth
,
num_channels
),
Scalar
(
1.0
,
2.0
,
3.0
,
4.0
));
gpu
::
GpuMat
dev_orig
(
orig
);
vector
<
gpu
::
GpuMat
>
dev_vec
;
cv
::
gpu
::
split
(
dev_orig
,
dev_vec
);
gpu
::
GpuMat
dev_final
(
rows
,
cols
,
CV_MAKETYPE
(
depth
,
num_channels
));
cv
::
gpu
::
merge
(
dev_vec
,
dev_final
);
double
err
=
cv
::
norm
((
Mat
)
dev_orig
,
(
Mat
)
dev_final
,
NORM_INF
);
if
(
err
>
1e-3
)
{
//ts->printf(CvTS::CONSOLE, "\nNorm: %f\n", err);
//ts->printf(CvTS::CONSOLE, "Depth: %d\n", depth);
//ts->printf(CvTS::CONSOLE, "Rows: %d\n", rows);
//ts->printf(CvTS::CONSOLE, "Cols: %d\n", cols);
//ts->printf(CvTS::CONSOLE, "NumChannels: %d\n", num_channels);
ts
->
set_failed_test_info
(
CvTS
::
FAIL_INVALID_OUTPUT
);
return
;
}
}
}
void
CV_SplitMergeTest
::
run
(
int
)
{
try
{
can_split_merge
(
1
,
1
);
can_split_merge
(
1
,
7
);
can_split_merge
(
7
,
53
);
}
catch
(
const
cv
::
Exception
&
e
)
{
if
(
!
check_and_treat_gpu_exception
(
e
,
ts
))
throw
;
}
}
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