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 #include <time.h> 45 #include <limits> 46 using namespace cv; 47 using namespace std; 48 49 #define CORE_COUNTNONZERO_ERROR_COUNT 1 50 51 #define MESSAGE_ERROR_COUNT "Count non zero elements returned by OpenCV function is incorrect." 52 53 #define sign(a) a > 0 ? 1 : a == 0 ? 0 : -1 54 55 #define MAX_WIDTH 100 56 #define MAX_HEIGHT 100 57 58 class CV_CountNonZeroTest: public cvtest::BaseTest 59 { 60 public: 61 CV_CountNonZeroTest(); 62 ~CV_CountNonZeroTest(); 63 64 protected: 65 void run (int); 66 67 private: 68 float eps_32; 69 double eps_64; 70 Mat src; 71 int current_type; 72 73 void generate_src_data(cv::Size size, int type); 74 void generate_src_data(cv::Size size, int type, int count_non_zero); 75 void generate_src_stat_data(cv::Size size, int type, int distribution); 76 77 int get_count_non_zero(); 78 79 void print_information(int right, int result); 80 }; 81 82 CV_CountNonZeroTest::CV_CountNonZeroTest(): eps_32(std::numeric_limits<float>::min()), eps_64(std::numeric_limits<double>::min()), src(Mat()), current_type(-1) {} 83 CV_CountNonZeroTest::~CV_CountNonZeroTest() {} 84 85 void CV_CountNonZeroTest::generate_src_data(cv::Size size, int type) 86 { 87 src.create(size, CV_MAKETYPE(type, 1)); 88 89 for (int j = 0; j < size.width; ++j) 90 for (int i = 0; i < size.height; ++i) 91 switch (type) 92 { 93 case CV_8U: { src.at<uchar>(i, j) = cv::randu<uchar>(); break; } 94 case CV_8S: { src.at<char>(i, j) = cv::randu<uchar>() - 128; break; } 95 case CV_16U: { src.at<ushort>(i, j) = cv::randu<ushort>(); break; } 96 case CV_16S: { src.at<short>(i, j) = cv::randu<short>(); break; } 97 case CV_32S: { src.at<int>(i, j) = cv::randu<int>(); break; } 98 case CV_32F: { src.at<float>(i, j) = cv::randu<float>(); break; } 99 case CV_64F: { src.at<double>(i, j) = cv::randu<double>(); break; } 100 default: break; 101 } 102 } 103 104 void CV_CountNonZeroTest::generate_src_data(cv::Size size, int type, int count_non_zero) 105 { 106 src = Mat::zeros(size, CV_MAKETYPE(type, 1)); 107 108 int n = 0; RNG& rng = ts->get_rng(); 109 110 while (n < count_non_zero) 111 { 112 int i = rng.next()%size.height, j = rng.next()%size.width; 113 114 switch (type) 115 { 116 case CV_8U: { if (!src.at<uchar>(i, j)) {src.at<uchar>(i, j) = cv::randu<uchar>(); n += (src.at<uchar>(i, j) > 0);} break; } 117 case CV_8S: { if (!src.at<char>(i, j)) {src.at<char>(i, j) = cv::randu<uchar>() - 128; n += abs(sign(src.at<char>(i, j)));} break; } 118 case CV_16U: { if (!src.at<ushort>(i, j)) {src.at<ushort>(i, j) = cv::randu<ushort>(); n += (src.at<ushort>(i, j) > 0);} break; } 119 case CV_16S: { if (!src.at<short>(i, j)) {src.at<short>(i, j) = cv::randu<short>(); n += abs(sign(src.at<short>(i, j)));} break; } 120 case CV_32S: { if (!src.at<int>(i, j)) {src.at<int>(i, j) = cv::randu<int>(); n += abs(sign(src.at<int>(i, j)));} break; } 121 case CV_32F: { if (fabs(src.at<float>(i, j)) <= eps_32) {src.at<float>(i, j) = cv::randu<float>(); n += (fabs(src.at<float>(i, j)) > eps_32);} break; } 122 case CV_64F: { if (fabs(src.at<double>(i, j)) <= eps_64) {src.at<double>(i, j) = cv::randu<double>(); n += (fabs(src.at<double>(i, j)) > eps_64);} break; } 123 124 default: break; 125 } 126 } 127 128 } 129 130 void CV_CountNonZeroTest::generate_src_stat_data(cv::Size size, int type, int distribution) 131 { 132 src.create(size, CV_MAKETYPE(type, 1)); 133 134 double mean = 0.0, sigma = 1.0; 135 double left = -1.0, right = 1.0; 136 137 RNG& rng = ts->get_rng(); 138 139 if (distribution == RNG::NORMAL) 140 rng.fill(src, RNG::NORMAL, Scalar::all(mean), Scalar::all(sigma)); 141 else if (distribution == RNG::UNIFORM) 142 rng.fill(src, RNG::UNIFORM, Scalar::all(left), Scalar::all(right)); 143 } 144 145 int CV_CountNonZeroTest::get_count_non_zero() 146 { 147 int result = 0; 148 149 for (int i = 0; i < src.rows; ++i) 150 for (int j = 0; j < src.cols; ++j) 151 { 152 if (current_type == CV_8U) result += (src.at<uchar>(i, j) > 0); 153 else if (current_type == CV_8S) result += abs(sign(src.at<char>(i, j))); 154 else if (current_type == CV_16U) result += (src.at<ushort>(i, j) > 0); 155 else if (current_type == CV_16S) result += abs(sign(src.at<short>(i, j))); 156 else if (current_type == CV_32S) result += abs(sign(src.at<int>(i, j))); 157 else if (current_type == CV_32F) result += (fabs(src.at<float>(i, j)) > eps_32); 158 else result += (fabs(src.at<double>(i, j)) > eps_64); 159 } 160 161 return result; 162 } 163 164 void CV_CountNonZeroTest::print_information(int right, int result) 165 { 166 cout << endl; cout << "Checking for the work of countNonZero function..." << endl; cout << endl; 167 cout << "Type of Mat: "; 168 switch (current_type) 169 { 170 case 0: {cout << "CV_8U"; break;} 171 case 1: {cout << "CV_8S"; break;} 172 case 2: {cout << "CV_16U"; break;} 173 case 3: {cout << "CV_16S"; break;} 174 case 4: {cout << "CV_32S"; break;} 175 case 5: {cout << "CV_32F"; break;} 176 case 6: {cout << "CV_64F"; break;} 177 default: break; 178 } 179 cout << endl; 180 cout << "Number of rows: " << src.rows << " Number of cols: " << src.cols << endl; 181 cout << "True count non zero elements: " << right << " Result: " << result << endl; 182 cout << endl; 183 } 184 185 void CV_CountNonZeroTest::run(int) 186 { 187 const size_t N = 1500; 188 189 for (int k = 1; k <= 3; ++k) 190 for (size_t i = 0; i < N; ++i) 191 { 192 RNG& rng = ts->get_rng(); 193 194 int w = rng.next()%MAX_WIDTH + 1, h = rng.next()%MAX_HEIGHT + 1; 195 196 current_type = rng.next()%7; 197 198 switch (k) 199 { 200 case 1: { 201 generate_src_data(Size(w, h), current_type); 202 int right = get_count_non_zero(), result = countNonZero(src); 203 if (result != right) 204 { 205 cout << "Number of experiment: " << i << endl; 206 cout << "Method of data generation: RANDOM" << endl; 207 print_information(right, result); 208 CV_Error(CORE_COUNTNONZERO_ERROR_COUNT, MESSAGE_ERROR_COUNT); 209 return; 210 } 211 212 break; 213 } 214 215 case 2: { 216 int count_non_zero = rng.next()%(w*h); 217 generate_src_data(Size(w, h), current_type, count_non_zero); 218 int result = countNonZero(src); 219 if (result != count_non_zero) 220 { 221 cout << "Number of experiment: " << i << endl; 222 cout << "Method of data generation: HALF-RANDOM" << endl; 223 print_information(count_non_zero, result); 224 CV_Error(CORE_COUNTNONZERO_ERROR_COUNT, MESSAGE_ERROR_COUNT); 225 return; 226 } 227 228 break; 229 } 230 231 case 3: { 232 int distribution = cv::randu<uchar>()%2; 233 generate_src_stat_data(Size(w, h), current_type, distribution); 234 int right = get_count_non_zero(), result = countNonZero(src); 235 if (right != result) 236 { 237 cout << "Number of experiment: " << i << endl; 238 cout << "Method of data generation: STATISTIC" << endl; 239 print_information(right, result); 240 CV_Error(CORE_COUNTNONZERO_ERROR_COUNT, MESSAGE_ERROR_COUNT); 241 return; 242 } 243 244 break; 245 } 246 247 default: break; 248 } 249 } 250 } 251 252 TEST (Core_CountNonZero, accuracy) { CV_CountNonZeroTest test; test.safe_run(); } 253