Disable redundant border initialization in findContours
authorVladislav Sovrasov <sovrasov.vlad@gmail.com>
Tue, 25 Oct 2016 09:20:36 +0000 (12:20 +0300)
committerVladislav Sovrasov <sovrasov.vlad@gmail.com>
Fri, 28 Oct 2016 08:05:54 +0000 (11:05 +0300)
modules/imgproc/src/contours.cpp

index 427cd05..4c78621 100644 (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,33 +1807,11 @@ icvFindContoursInInterval( const CvArr* src,
     return count;
 }
 
-
-
-/*F///////////////////////////////////////////////////////////////////////////////////////
-//    Name: cvFindContours
-//    Purpose:
-//      Finds all the contours on the bi-level image.
-//    Context:
-//    Parameters:
-//      img  - source image.
-//             Non-zero pixels are considered as 1-pixels
-//             and zero pixels as 0-pixels.
-//      step - full width of source image in bytes.
-//      size - width and height of the image in pixels
-//      storage - pointer to storage where will the output contours be placed.
-//      header_size - header size of resulting contours
-//      mode - mode of contour retrieval.
-//      method - method of approximation that is applied to contours
-//      first_contour - pointer to first contour pointer
-//    Returns:
-//      CV_OK or error code
-//    Notes:
-//F*/
-CV_IMPL int
-cvFindContours( void*  img,  CvMemStorage*  storage,
+static int
+cvFindContours_Impl( void*  img,  CvMemStorage*  storage,
                 CvSeq**  firstContour, int  cntHeaderSize,
                 int  mode,
-                int  method, CvPoint offset )
+                int  method, CvPoint offset, int needFillBorder )
 {
     CvContourScanner scanner = 0;
     CvSeq *contour = 0;
@@ -1845,7 +1834,8 @@ cvFindContours( void*  img,  CvMemStorage*  storage,
     {
         try
         {
-            scanner = cvStartFindContours( img, storage, cntHeaderSize, mode, method, offset );
+            scanner = cvStartFindContours_Impl( img, storage, cntHeaderSize, mode, method, offset,
+                                            needFillBorder);
 
             do
             {
@@ -1867,6 +1857,35 @@ cvFindContours( void*  img,  CvMemStorage*  storage,
     return count;
 }
 
+/*F///////////////////////////////////////////////////////////////////////////////////////
+//    Name: cvFindContours
+//    Purpose:
+//      Finds all the contours on the bi-level image.
+//    Context:
+//    Parameters:
+//      img  - source image.
+//             Non-zero pixels are considered as 1-pixels
+//             and zero pixels as 0-pixels.
+//      step - full width of source image in bytes.
+//      size - width and height of the image in pixels
+//      storage - pointer to storage where will the output contours be placed.
+//      header_size - header size of resulting contours
+//      mode - mode of contour retrieval.
+//      method - method of approximation that is applied to contours
+//      first_contour - pointer to first contour pointer
+//    Returns:
+//      CV_OK or error code
+//    Notes:
+//F*/
+CV_IMPL int
+cvFindContours( void*  img,  CvMemStorage*  storage,
+                CvSeq**  firstContour, int  cntHeaderSize,
+                int  mode,
+                int  method, CvPoint offset )
+{
+    return cvFindContours_Impl(img, storage, firstContour, cntHeaderSize, mode, method, offset, 1);
+}
+
 void cv::findContours( InputOutputArray _image, OutputArrayOfArrays _contours,
                    OutputArray _hierarchy, int mode, int method, Point offset )
 {
@@ -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();