Home | History | Annotate | Download | only in test
      1 /*M///////////////////////////////////////////////////////////////////////////////////////
      2 //
      3 //  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
      4 //
      5 //  By downloading, copying, installing or using the software you agree to this license.
      6 //  If you do not agree to this license, do not download, install,
      7 //  copy or use the software.
      8 //
      9 //
     10 //                           License Agreement
     11 //                For Open Source Computer Vision Library
     12 //
     13 // Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
     14 // Copyright (C) 2009, Willow Garage Inc., all rights reserved.
     15 // Third party copyrights are property of their respective owners.
     16 //
     17 // Redistribution and use in source and binary forms, with or without modification,
     18 // are permitted provided that the following conditions are met:
     19 //
     20 //   * Redistribution's of source code must retain the above copyright notice,
     21 //     this list of conditions and the following disclaimer.
     22 //
     23 //   * Redistribution's in binary form must reproduce the above copyright notice,
     24 //     this list of conditions and the following disclaimer in the documentation
     25 //     and/or other materials provided with the distribution.
     26 //
     27 //   * The name of the copyright holders may not be used to endorse or promote products
     28 //     derived from this software without specific prior written permission.
     29 //
     30 // This software is provided by the copyright holders and contributors "as is" and
     31 // any express or implied warranties, including, but not limited to, the implied
     32 // warranties of merchantability and fitness for a particular purpose are disclaimed.
     33 // In no event shall the Intel Corporation or contributors be liable for any direct,
     34 // indirect, incidental, special, exemplary, or consequential damages
     35 // (including, but not limited to, procurement of substitute goods or services;
     36 // loss of use, data, or profits; or business interruption) however caused
     37 // and on any theory of liability, whether in contract, strict liability,
     38 // or tort (including negligence or otherwise) arising in any way out of
     39 // the use of this software, even if advised of the possibility of such damage.
     40 //
     41 //M*/
     42 
     43 #include "test_precomp.hpp"
     44 
     45 #ifdef HAVE_CUDA
     46 
     47 namespace
     48 {
     49     struct GreedyLabeling
     50     {
     51         struct dot
     52         {
     53             int x;
     54             int y;
     55 
     56             static dot make(int i, int j)
     57             {
     58                 dot d; d.x = i; d.y = j;
     59                 return d;
     60             }
     61         };
     62 
     63         struct InInterval
     64         {
     65             InInterval(const int& _lo, const int& _hi) : lo(-_lo), hi(_hi) {}
     66             const int lo, hi;
     67 
     68             bool operator() (const unsigned char a, const unsigned char b) const
     69             {
     70                 int d = a - b;
     71                 return lo <= d && d <= hi;
     72             }
     73         };
     74 
     75         GreedyLabeling(cv::Mat img)
     76         : image(img), _labels(image.size(), CV_32SC1, cv::Scalar::all(-1)) {}
     77 
     78         void operator() (cv::Mat labels) const
     79         {
     80             InInterval inInt(0, 2);
     81             dot* stack = new dot[image.cols * image.rows];
     82 
     83             int cc = -1;
     84 
     85             int* dist_labels = (int*)labels.data;
     86             int pitch = (int) labels.step1();
     87 
     88             unsigned char* source = (unsigned char*)image.data;
     89             int width = image.cols;
     90             int height = image.rows;
     91             int step1 = (int)image.step1();
     92 
     93             for (int j = 0; j < image.rows; ++j)
     94                 for (int i = 0; i < image.cols; ++i)
     95                 {
     96                     if (dist_labels[j * pitch + i] != -1) continue;
     97 
     98                     dot* top = stack;
     99                     dot p = dot::make(i, j);
    100                     cc++;
    101 
    102                     dist_labels[j * pitch + i] = cc;
    103 
    104                     while (top >= stack)
    105                     {
    106                         int*  dl = &dist_labels[p.y * pitch + p.x];
    107                         unsigned char* sp = &source[p.y * step1 + p.x];
    108 
    109                         dl[0] = cc;
    110 
    111                         //right
    112                         if( p.x < (width - 1) && dl[ +1] == -1 && inInt(sp[0], sp[+1]))
    113                             *top++ = dot::make(p.x + 1, p.y);
    114 
    115                         //left
    116                         if( p.x > 0 && dl[-1] == -1 && inInt(sp[0], sp[-1]))
    117                             *top++ = dot::make(p.x - 1, p.y);
    118 
    119                         //bottom
    120                         if( p.y < (height - 1) && dl[+pitch] == -1 && inInt(sp[0], sp[+step1]))
    121                             *top++ = dot::make(p.x, p.y + 1);
    122 
    123                         //top
    124                         if( p.y > 0 && dl[-pitch] == -1 && inInt(sp[0], sp[-step1]))
    125                             *top++ = dot::make(p.x, p.y - 1);
    126 
    127                         p = *--top;
    128                     }
    129                 }
    130             delete[] stack;
    131         }
    132 
    133         void checkCorrectness(cv::Mat gpu)
    134         {
    135             cv::Mat diff = gpu - _labels;
    136 
    137             int outliers = 0;
    138             for (int j = 0; j < image.rows; ++j)
    139                 for (int i = 0; i < image.cols - 1; ++i)
    140                 {
    141                     if ( (_labels.at<int>(j,i) == gpu.at<int>(j,i + 1)) && (diff.at<int>(j, i) != diff.at<int>(j,i + 1)))
    142                     {
    143                         outliers++;
    144                     }
    145                 }
    146             ASSERT_TRUE(outliers < gpu.cols + gpu.rows);
    147         }
    148 
    149         cv::Mat image;
    150         cv::Mat _labels;
    151     };
    152 }
    153 
    154 struct Labeling : testing::TestWithParam<cv::cuda::DeviceInfo>
    155 {
    156     cv::cuda::DeviceInfo devInfo;
    157 
    158     virtual void SetUp()
    159     {
    160         devInfo = GetParam();
    161         cv::cuda::setDevice(devInfo.deviceID());
    162     }
    163 
    164     cv::Mat loat_image()
    165     {
    166         return cv::imread(std::string( cvtest::TS::ptr()->get_data_path() ) + "labeling/label.png");
    167     }
    168 };
    169 
    170 CUDA_TEST_P(Labeling, DISABLED_ConnectedComponents)
    171 {
    172     cv::Mat image;
    173     cvtColor(loat_image(), image, cv::COLOR_BGR2GRAY);
    174 
    175     cv::threshold(image, image, 150, 255, cv::THRESH_BINARY);
    176 
    177     ASSERT_TRUE(image.type() == CV_8UC1);
    178 
    179     GreedyLabeling host(image);
    180     host(host._labels);
    181 
    182     cv::cuda::GpuMat mask;
    183     mask.create(image.rows, image.cols, CV_8UC1);
    184 
    185     cv::cuda::GpuMat components;
    186     components.create(image.rows, image.cols, CV_32SC1);
    187 
    188     cv::cuda::connectivityMask(cv::cuda::GpuMat(image), mask, cv::Scalar::all(0), cv::Scalar::all(2));
    189 
    190     cv::cuda::labelComponents(mask, components);
    191 
    192     host.checkCorrectness(cv::Mat(components));
    193 }
    194 
    195 INSTANTIATE_TEST_CASE_P(CUDA_ConnectedComponents, Labeling, ALL_DEVICES);
    196 
    197 #endif // HAVE_CUDA
    198