fixed build warnings from VS; hopefully, fixes Android build too
authorVadim Pisarevsky <vadim.pisarevsky@gmail.com>
Sat, 15 Dec 2012 19:14:50 +0000 (23:14 +0400)
committerVadim Pisarevsky <vadim.pisarevsky@gmail.com>
Sat, 15 Dec 2012 19:14:50 +0000 (23:14 +0400)
modules/imgproc/include/opencv2/imgproc/imgproc.hpp
modules/imgproc/src/connectedcomponents.cpp

index 6be7ef6..284b254 100644 (file)
@@ -1104,12 +1104,17 @@ CV_EXPORTS_W void matchTemplate( InputArray image, InputArray templ,
 
 enum { CC_STAT_LEFT=0, CC_STAT_TOP=1, CC_STAT_WIDTH=2, CC_STAT_HEIGHT=3, CC_STAT_AREA=4, CC_STAT_MAX = 5};
 
-//! computes the connected components labeled image of boolean image I with 4 or 8 way connectivity - returns N, the total
-//number of labels [0, N-1] where 0 represents the background label. L's value type determines the label type, an important
-//consideration based on the total number of labels or alternatively the total number of pixels.
-CV_EXPORTS_W int connectedComponents(InputArray image, OutputArray labels, int connectivity = 8, int ltype=CV_32S);
-CV_EXPORTS_W int connectedComponentsWithStats(InputArray image, OutputArray labels, OutputArray stats, OutputArray centroids, int connectivity = 8, int ltype=CV_32S);
-
+// computes the connected components labeled image of boolean image I
+// with 4 or 8 way connectivity - returns N, the total
+// number of labels [0, N-1] where 0 represents the background label.
+// L's value type determines the label type, an important
+// consideration based on the total number of labels or
+// alternatively the total number of pixels.
+CV_EXPORTS_W int connectedComponents(InputArray image, OutputArray labels,
+                                     int connectivity = 8, int ltype=CV_32S);
+CV_EXPORTS_W int connectedComponentsWithStats(InputArray image, OutputArray labels,
+                                              OutputArray stats, OutputArray centroids,
+                                              int connectivity = 8, int ltype=CV_32S);
 
 //! mode of the contour retrieval algorithm
 enum
index 97da882..d6bd125 100644 (file)
 #include "precomp.hpp"
 #include <vector>
 
-#if defined _MSC_VER
-#pragma warning(disable: 4127)
-#endif
-
 namespace cv{
     namespace connectedcomponents{
 
-    template<typename LabelT>
     struct NoOp{
         NoOp(){
         }
-        void init(const LabelT labels){
-            (void) labels;
+        void init(int /*labels*/){
         }
         inline
-        void operator()(int r, int c, LabelT l){
+        void operator()(int r, int c, int l){
             (void) r;
             (void) c;
             (void) l;
@@ -69,38 +63,35 @@ namespace cv{
         uint64 x, y;
         Point2ui64(uint64 _x, uint64 _y):x(_x), y(_y){}
     };
-    template<typename LabelT>
+
     struct CCStatsOp{
-        OutputArray _mstatsv;
+        const _OutputArray* _mstatsv;
         cv::Mat statsv;
-        OutputArray _mcentroidsv;
+        const _OutputArray* _mcentroidsv;
         cv::Mat centroidsv;
         std::vector<Point2ui64> integrals;
 
-        CCStatsOp(OutputArray _statsv, OutputArray _centroidsv): _mstatsv(_statsv), _mcentroidsv(_centroidsv){
+        CCStatsOp(OutputArray _statsv, OutputArray _centroidsv): _mstatsv(&_statsv), _mcentroidsv(&_centroidsv){
         }
         inline
-        void init(const LabelT nlabels){
-            _mstatsv.create(cv::Size(nlabels, CC_STAT_MAX), cv::DataType<int>::type);
-            statsv = _mstatsv.getMat();
-            _mcentroidsv.create(cv::Size(nlabels, 2), cv::DataType<double>::type);
-            centroidsv = _mcentroidsv.getMat();
+        void init(int nlabels){
+            _mstatsv->create(cv::Size(nlabels, CC_STAT_MAX), cv::DataType<int>::type);
+            statsv = _mstatsv->getMat();
+            _mcentroidsv->create(cv::Size(nlabels, 2), cv::DataType<double>::type);
+            centroidsv = _mcentroidsv->getMat();
 
             for(int l = 0; l < (int) nlabels; ++l){
-                unsigned int *row = (unsigned int *) &statsv.at<int>(l, 0);
-                row[CC_STAT_LEFT] = std::numeric_limits<LabelT>::max();
-                row[CC_STAT_TOP] = std::numeric_limits<LabelT>::max();
-                row[CC_STAT_WIDTH] = std::numeric_limits<LabelT>::min();
-                row[CC_STAT_HEIGHT] = std::numeric_limits<LabelT>::min();
-                //row[CC_STAT_CX] = 0;
-                //row[CC_STAT_CY] = 0;
+                int *row = (int *) &statsv.at<int>(l, 0);
+                row[CC_STAT_LEFT] = INT_MAX;
+                row[CC_STAT_TOP] = INT_MAX;
+                row[CC_STAT_WIDTH] = INT_MIN;
+                row[CC_STAT_HEIGHT] = INT_MIN;
                 row[CC_STAT_AREA] = 0;
             }
             integrals.resize(nlabels, Point2ui64(0, 0));
         }
-        void operator()(int r, int c, LabelT l){
+        void operator()(int r, int c, int l){
             int *row = &statsv.at<int>(l, 0);
-            unsigned int *urow = (unsigned int *) row;
             if(c > row[CC_STAT_WIDTH]){
                 row[CC_STAT_WIDTH] = c;
             }else{
@@ -115,14 +106,14 @@ namespace cv{
                     row[CC_STAT_TOP] = r;
                 }
             }
-            urow[CC_STAT_AREA]++;
+            row[CC_STAT_AREA]++;
             Point2ui64 &integral = integrals[l];
             integral.x += c;
             integral.y += r;
         }
         void finish(){
             for(int l = 0; l < statsv.rows; ++l){
-                unsigned int *row = (unsigned int *) &statsv.at<int>(l, 0);
+                int *row = &statsv.at<int>(l, 0);
                 row[CC_STAT_LEFT] = std::min(row[CC_STAT_LEFT], row[CC_STAT_WIDTH]);
                 row[CC_STAT_WIDTH] = row[CC_STAT_WIDTH] - row[CC_STAT_LEFT] + 1;
                 row[CC_STAT_TOP] = std::min(row[CC_STAT_TOP], row[CC_STAT_HEIGHT]);
@@ -130,8 +121,9 @@ namespace cv{
 
                 Point2ui64 &integral = integrals[l];
                 double *centroid = &centroidsv.at<double>(l, 0);
-                centroid[0] = double(integral.x) / row[CC_STAT_AREA];
-                centroid[1] = double(integral.y) / row[CC_STAT_AREA];
+                double area = ((unsigned*)row)[CC_STAT_AREA];
+                centroid[0] = double(integral.x) / area;
+                centroid[1] = double(integral.y) / area;
             }
         }
     };
@@ -207,11 +199,12 @@ namespace cv{
     const int G4[2][2] = {{1, 0}, {0, -1}};//b, d neighborhoods
     //reference for 8-way: {{-1, -1}, {-1, 0}, {-1, 1}, {0, -1}};//a, b, c, d neighborhoods
     const int G8[4][2] = {{1, -1}, {1, 0}, {1, 1}, {0, -1}};//a, b, c, d neighborhoods
-    template<typename LabelT, typename PixelT, typename StatsOp = NoOp<LabelT>, int connectivity = 8>
+    template<typename LabelT, typename PixelT, typename StatsOp = NoOp >
     struct LabelingImpl{
-    LabelT operator()(const cv::Mat &I, cv::Mat &L, StatsOp &sop){
+    LabelT operator()(const cv::Mat &I, cv::Mat &L, int connectivity, StatsOp &sop){
         CV_Assert(L.rows == I.rows);
         CV_Assert(L.cols == I.cols);
+        CV_Assert(connectivity == 8 || connectivity == 4);
         const int rows = L.rows;
         const int cols = L.cols;
         size_t Plength = (size_t(rows + 3 - 1)/3) * (size_t(cols + 3 - 1)/3);
@@ -295,7 +288,6 @@ namespace cv{
                 }
             }else{
                 //B & D only
-                assert(connectivity == 4);
                 const int b = 0;
                 const int d = 1;
                 const bool T_b_r = (r_i - G4[b][0]) >= 0;
@@ -368,70 +360,52 @@ int connectedComponents_sub1(const cv::Mat &I, cv::Mat &L, int connectivity, Sta
     using connectedcomponents::LabelingImpl;
     //warn if L's depth is not sufficient?
 
+    CV_Assert(iDepth == CV_8U || iDepth == CV_8S);
+
     if(lDepth == CV_8U){
-        if(iDepth == CV_8U || iDepth == CV_8S){
-            if(connectivity == 4){
-                return (int) LabelingImpl<uchar, uchar, StatsOp, 4>()(I, L, sop);
-            }else{
-                return (int) LabelingImpl<uchar, uchar, StatsOp, 8>()(I, L, sop);
-            }
-        }else{
-            CV_Assert(false);
-        }
+        return (int) LabelingImpl<uchar, uchar, StatsOp>()(I, L, connectivity, sop);
     }else if(lDepth == CV_16U){
-        if(iDepth == CV_8U || iDepth == CV_8S){
-            if(connectivity == 4){
-                return (int) LabelingImpl<ushort, uchar, StatsOp, 4>()(I, L, sop);
-            }else{
-                return (int) LabelingImpl<ushort, uchar, StatsOp, 8>()(I, L, sop);
-            }
-        }else{
-            CV_Assert(false);
-        }
+        return (int) LabelingImpl<ushort, uchar, StatsOp>()(I, L, connectivity, sop);
     }else if(lDepth == CV_32S){
         //note that signed types don't really make sense here and not being able to use unsigned matters for scientific projects
         //OpenCV: how should we proceed?  .at<T> typechecks in debug mode
-        if(iDepth == CV_8U || iDepth == CV_8S){
-            if(connectivity == 4){
-                return (int) LabelingImpl<int, uchar, StatsOp, 4>()(I, L, sop);
-            }else{
-                return (int) LabelingImpl<int, uchar, StatsOp, 8>()(I, L, sop);
-            }
-        }else{
-            CV_Assert(false);
-        }
+        return (int) LabelingImpl<int, uchar, StatsOp>()(I, L, connectivity, sop);
     }
 
     CV_Error(CV_StsUnsupportedFormat, "unsupported label/image type");
     return -1;
 }
 
-int connectedComponents(InputArray _I, OutputArray _L, int connectivity, int ltype){
+}
+
+int cv::connectedComponents(InputArray _I, OutputArray _L, int connectivity, int ltype){
     const cv::Mat I = _I.getMat();
-    _L.create(I.size(), CV_MAT_TYPE(ltype));
+    _L.create(I.size(), CV_MAT_DEPTH(ltype));
     cv::Mat L = _L.getMat();
+    connectedcomponents::NoOp sop;
     if(ltype == CV_16U){
-        connectedcomponents::NoOp<ushort> sop; return connectedComponents_sub1(I, L, connectivity, sop);
+        return connectedComponents_sub1(I, L, connectivity, sop);
     }else if(ltype == CV_32S){
-        connectedcomponents::NoOp<unsigned> sop; return connectedComponents_sub1(I, L, connectivity, sop);
+        return connectedComponents_sub1(I, L, connectivity, sop);
     }else{
-        CV_Assert(false);
+        CV_Error(CV_StsUnsupportedFormat, "the type of labels must be 16u or 32s");
         return 0;
     }
 }
 
-int connectedComponentsWithStats(InputArray _I, OutputArray _L, OutputArray statsv, OutputArray centroids, int connectivity, int ltype){
+int cv::connectedComponentsWithStats(InputArray _I, OutputArray _L, OutputArray statsv,
+                                     OutputArray centroids, int connectivity, int ltype)
+{
     const cv::Mat I = _I.getMat();
-    _L.create(I.size(), CV_MAT_TYPE(ltype));
+    _L.create(I.size(), CV_MAT_DEPTH(ltype));
     cv::Mat L = _L.getMat();
+    connectedcomponents::CCStatsOp sop(statsv, centroids); 
     if(ltype == CV_16U){
-        connectedcomponents::CCStatsOp<ushort> sop(statsv, centroids); return connectedComponents_sub1(I, L, connectivity, sop);
+        return connectedComponents_sub1(I, L, connectivity, sop);
     }else if(ltype == CV_32S){
-        connectedcomponents::CCStatsOp<unsigned> sop(statsv, centroids); return connectedComponents_sub1(I, L, connectivity, sop);
+        return connectedComponents_sub1(I, L, connectivity, sop);
     }else{
-        CV_Assert(false);
+        CV_Error(CV_StsUnsupportedFormat, "the type of labels must be 16u or 32s");
         return 0;
     }
 }
-
-}