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