Skip to content

Commit

Permalink
bigdata: add test, resolve split/merge issue
Browse files Browse the repository at this point in the history
  • Loading branch information
alalek committed Jul 8, 2016
1 parent 627e2b1 commit 5f269d0
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 12 deletions.
4 changes: 4 additions & 0 deletions cmake/OpenCVModule.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -1110,6 +1110,10 @@ function(ocv_add_accuracy_tests)
set_target_properties(${the_target} PROPERTIES FOLDER "tests accuracy")
endif()

if(OPENCV_TEST_BIGDATA)
ocv_append_target_property(${the_target} COMPILE_DEFINITIONS "OPENCV_TEST_BIGDATA=1")
endif()

if(NOT BUILD_opencv_world)
_ocv_add_precompiled_headers(${the_target})
endif()
Expand Down
10 changes: 10 additions & 0 deletions cmake/OpenCVUtils.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,16 @@ function(ocv_include_directories)
include_directories(BEFORE ${__add_before})
endfunction()

function(ocv_append_target_property target prop)
get_target_property(val ${target} ${prop})
if(val)
set(val "${val} ${ARGN}")
set_target_properties(${target} PROPERTIES ${prop} "${val}")
else()
set_target_properties(${target} PROPERTIES ${prop} "${ARGN}")
endif()
endfunction()

# adds include directories in such way that directories from the OpenCV source tree go first
function(ocv_target_include_directories target)
_ocv_fix_target(target)
Expand Down
29 changes: 17 additions & 12 deletions modules/core/src/convert.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
#define CV_NEON 0
#endif

#define CV_SPLIT_MERGE_MAX_BLOCK_SIZE(cn) ((INT_MAX/4)/cn) // HAL implementation accepts 'int' len, so INT_MAX doesn't work here

/****************************************************************************************\
* split & merge *
Expand Down Expand Up @@ -93,8 +94,8 @@ void cv::split(const Mat& src, Mat* mv)
SplitFunc func = getSplitFunc(depth);
CV_Assert( func != 0 );

int esz = (int)src.elemSize(), esz1 = (int)src.elemSize1();
int blocksize0 = (BLOCK_SIZE + esz-1)/esz;
size_t esz = src.elemSize(), esz1 = src.elemSize1();
size_t blocksize0 = (BLOCK_SIZE + esz-1)/esz;
AutoBuffer<uchar> _buf((cn+1)*(sizeof(Mat*) + sizeof(uchar*)) + 16);
const Mat** arrays = (const Mat**)(uchar*)_buf;
uchar** ptrs = (uchar**)alignPtr(arrays + cn + 1, 16);
Expand All @@ -107,14 +108,15 @@ void cv::split(const Mat& src, Mat* mv)
}

NAryMatIterator it(arrays, ptrs, cn+1);
int total = (int)it.size, blocksize = cn <= 4 ? total : std::min(total, blocksize0);
size_t total = it.size;
size_t blocksize = std::min((size_t)CV_SPLIT_MERGE_MAX_BLOCK_SIZE(cn), cn <= 4 ? total : std::min(total, blocksize0));

for( size_t i = 0; i < it.nplanes; i++, ++it )
{
for( int j = 0; j < total; j += blocksize )
for( size_t j = 0; j < total; j += blocksize )
{
int bsz = std::min(total - j, blocksize);
func( ptrs[0], &ptrs[1], bsz, cn );
size_t bsz = std::min(total - j, blocksize);
func( ptrs[0], &ptrs[1], (int)bsz, cn );

if( j + blocksize < total )
{
Expand Down Expand Up @@ -241,8 +243,11 @@ void cv::merge(const Mat* mv, size_t n, OutputArray _dst)
return;
}

MergeFunc func = getMergeFunc(depth);
CV_Assert( func != 0 );

size_t esz = dst.elemSize(), esz1 = dst.elemSize1();
int blocksize0 = (int)((BLOCK_SIZE + esz-1)/esz);
size_t blocksize0 = (int)((BLOCK_SIZE + esz-1)/esz);
AutoBuffer<uchar> _buf((cn+1)*(sizeof(Mat*) + sizeof(uchar*)) + 16);
const Mat** arrays = (const Mat**)(uchar*)_buf;
uchar** ptrs = (uchar**)alignPtr(arrays + cn + 1, 16);
Expand All @@ -252,15 +257,15 @@ void cv::merge(const Mat* mv, size_t n, OutputArray _dst)
arrays[k+1] = &mv[k];

NAryMatIterator it(arrays, ptrs, cn+1);
int total = (int)it.size, blocksize = cn <= 4 ? total : std::min(total, blocksize0);
MergeFunc func = getMergeFunc(depth);
size_t total = (int)it.size;
size_t blocksize = std::min((size_t)CV_SPLIT_MERGE_MAX_BLOCK_SIZE(cn), cn <= 4 ? total : std::min(total, blocksize0));

for( i = 0; i < it.nplanes; i++, ++it )
{
for( int j = 0; j < total; j += blocksize )
for( size_t j = 0; j < total; j += blocksize )
{
int bsz = std::min(total - j, blocksize);
func( (const uchar**)&ptrs[1], ptrs[0], bsz, cn );
size_t bsz = std::min(total - j, blocksize);
func( (const uchar**)&ptrs[1], ptrs[0], (int)bsz, cn );

if( j + blocksize < total )
{
Expand Down
26 changes: 26 additions & 0 deletions modules/core/test/test_mat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1483,3 +1483,29 @@ TEST(Mat, regression_5991)
EXPECT_EQ(sz[2], mat.size[2]);
EXPECT_EQ(0, cvtest::norm(mat, Mat(3, sz, CV_8U, Scalar(1)), NORM_INF));
}

#ifdef OPENCV_TEST_BIGDATA
TEST(Mat, regression_6696_BigData_8Gb)
{
int width = 60000;
int height = 10000;

Mat destImageBGR = Mat(height, width, CV_8UC3, Scalar(1, 2, 3, 0));
Mat destImageA = Mat(height, width, CV_8UC1, Scalar::all(4));

vector<Mat> planes;
split(destImageBGR, planes);
planes.push_back(destImageA);
merge(planes, destImageBGR);

EXPECT_EQ(1, destImageBGR.at<Vec4b>(0)[0]);
EXPECT_EQ(2, destImageBGR.at<Vec4b>(0)[1]);
EXPECT_EQ(3, destImageBGR.at<Vec4b>(0)[2]);
EXPECT_EQ(4, destImageBGR.at<Vec4b>(0)[3]);

EXPECT_EQ(1, destImageBGR.at<Vec4b>(height-1, width-1)[0]);
EXPECT_EQ(2, destImageBGR.at<Vec4b>(height-1, width-1)[1]);
EXPECT_EQ(3, destImageBGR.at<Vec4b>(height-1, width-1)[2]);
EXPECT_EQ(4, destImageBGR.at<Vec4b>(height-1, width-1)[3]);
}
#endif

0 comments on commit 5f269d0

Please sign in to comment.