Disable redundant border initialization in findContours

This commit is contained in:
Vladislav Sovrasov 2016-10-25 12:20:36 +03:00
parent c55890f637
commit 56c133d459

View File

@ -199,10 +199,10 @@ _CvContourScanner;
Initializes scanner structure.
Prepare image for scanning ( clear borders and convert all pixels to 0-1.
*/
CV_IMPL CvContourScanner
cvStartFindContours( void* _img, CvMemStorage* storage,
static CvContourScanner
cvStartFindContours_Impl( void* _img, CvMemStorage* storage,
int header_size, int mode,
int method, CvPoint offset )
int method, CvPoint offset, int needFillBorder )
{
if( !storage )
CV_Error( CV_StsNullPtr, "" );
@ -310,15 +310,18 @@ cvStartFindContours( void* _img, CvMemStorage* storage,
CV_Assert(size.height >= 1);
/* make zero borders */
int esz = CV_ELEM_SIZE(mat->type);
memset( img, 0, size.width*esz );
memset( img + static_cast<size_t>(step) * (size.height - 1), 0, size.width*esz );
img += step;
for( int y = 1; y < size.height - 1; y++, img += step )
if(needFillBorder)
{
for( int k = 0; k < esz; k++ )
img[k] = img[(size.width - 1)*esz + k] = (schar)0;
int esz = CV_ELEM_SIZE(mat->type);
memset( img, 0, size.width*esz );
memset( img + static_cast<size_t>(step) * (size.height - 1), 0, size.width*esz );
img += step;
for( int y = 1; y < size.height - 1; y++, img += step )
{
for( int k = 0; k < esz; k++ )
img[k] = img[(size.width - 1)*esz + k] = (schar)0;
}
}
/* converts all pixels to 0 or 1 */
@ -328,6 +331,14 @@ cvStartFindContours( void* _img, CvMemStorage* storage,
return scanner;
}
CV_IMPL CvContourScanner
cvStartFindContours( void* _img, CvMemStorage* storage,
int header_size, int mode,
int method, CvPoint offset )
{
return cvStartFindContours_Impl(_img, storage, header_size, mode, method, offset, 1);
}
/*
Final stage of contour processing.
Three variants possible:
@ -1796,7 +1807,55 @@ icvFindContoursInInterval( const CvArr* src,
return count;
}
static int
cvFindContours_Impl( void* img, CvMemStorage* storage,
CvSeq** firstContour, int cntHeaderSize,
int mode,
int method, CvPoint offset, int needFillBorder )
{
CvContourScanner scanner = 0;
CvSeq *contour = 0;
int count = -1;
if( !firstContour )
CV_Error( CV_StsNullPtr, "NULL double CvSeq pointer" );
*firstContour = 0;
if( method == CV_LINK_RUNS )
{
if( offset.x != 0 || offset.y != 0 )
CV_Error( CV_StsOutOfRange,
"Nonzero offset is not supported in CV_LINK_RUNS yet" );
count = icvFindContoursInInterval( img, storage, firstContour, cntHeaderSize );
}
else
{
try
{
scanner = cvStartFindContours_Impl( img, storage, cntHeaderSize, mode, method, offset,
needFillBorder);
do
{
count++;
contour = cvFindNextContour( scanner );
}
while( contour != 0 );
}
catch(...)
{
if( scanner )
cvEndFindContours(&scanner);
throw;
}
*firstContour = cvEndFindContours( &scanner );
}
return count;
}
/*F///////////////////////////////////////////////////////////////////////////////////////
// Name: cvFindContours
@ -1824,47 +1883,7 @@ cvFindContours( void* img, CvMemStorage* storage,
int mode,
int method, CvPoint offset )
{
CvContourScanner scanner = 0;
CvSeq *contour = 0;
int count = -1;
if( !firstContour )
CV_Error( CV_StsNullPtr, "NULL double CvSeq pointer" );
*firstContour = 0;
if( method == CV_LINK_RUNS )
{
if( offset.x != 0 || offset.y != 0 )
CV_Error( CV_StsOutOfRange,
"Nonzero offset is not supported in CV_LINK_RUNS yet" );
count = icvFindContoursInInterval( img, storage, firstContour, cntHeaderSize );
}
else
{
try
{
scanner = cvStartFindContours( img, storage, cntHeaderSize, mode, method, offset );
do
{
count++;
contour = cvFindNextContour( scanner );
}
while( contour != 0 );
}
catch(...)
{
if( scanner )
cvEndFindContours(&scanner);
throw;
}
*firstContour = cvEndFindContours( &scanner );
}
return count;
return cvFindContours_Impl(img, storage, firstContour, cntHeaderSize, mode, method, offset, 1);
}
void cv::findContours( InputOutputArray _image, OutputArrayOfArrays _contours,
@ -1885,7 +1904,7 @@ void cv::findContours( InputOutputArray _image, OutputArrayOfArrays _contours,
CvSeq* _ccontours = 0;
if( _hierarchy.needed() )
_hierarchy.clear();
cvFindContours(&_cimage, storage, &_ccontours, sizeof(CvContour), mode, method, offset + Point(-1, -1));
cvFindContours_Impl(&_cimage, storage, &_ccontours, sizeof(CvContour), mode, method, offset + Point(-1, -1), 0);
if( !_ccontours )
{
_contours.clear();