Move the sources to trunk
[opencv] / tests / cv / src / athresh.cpp
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 //                        Intel License Agreement
11 //                For Open Source Computer Vision Library
12 //
13 // Copyright (C) 2000, Intel Corporation, all rights reserved.
14 // Third party copyrights are property of their respective owners.
15 //
16 // Redistribution and use in source and binary forms, with or without modification,
17 // are permitted provided that the following conditions are met:
18 //
19 //   * Redistribution's of source code must retain the above copyright notice,
20 //     this list of conditions and the following disclaimer.
21 //
22 //   * Redistribution's in binary form must reproduce the above copyright notice,
23 //     this list of conditions and the following disclaimer in the documentation
24 //     and/or other materials provided with the distribution.
25 //
26 //   * The name of Intel Corporation may not be used to endorse or promote products
27 //     derived from this software without specific prior written permission.
28 //
29 // This software is provided by the copyright holders and contributors "as is" and
30 // any express or implied warranties, including, but not limited to, the implied
31 // warranties of merchantability and fitness for a particular purpose are disclaimed.
32 // In no event shall the Intel Corporation or contributors be liable for any direct,
33 // indirect, incidental, special, exemplary, or consequential damages
34 // (including, but not limited to, procurement of substitute goods or services;
35 // loss of use, data, or profits; or business interruption) however caused
36 // and on any theory of liability, whether in contract, strict liability,
37 // or tort (including negligence or otherwise) arising in any way out of
38 // the use of this software, even if advised of the possibility of such damage.
39 //
40 //M*/
41
42 #include "cvtest.h"
43
44 static const char* thresh_param_names[] = { "size", "depth", "thresh_type", 0 };
45 static const CvSize thresh_sizes[] = {{30,30}, {320, 240}, {720,480}, {-1,-1}};
46 static const CvSize thresh_whole_sizes[] = {{320,240}, {320, 240}, {720,480}, {-1,-1}};
47 static const int thresh_depths[] = { CV_8U, CV_32F, -1 };
48 static const char* thresh_types[] = { "binary", "binary_inv", "trunc", "tozero", "tozero_inv", 0 };
49
50 class CV_ThreshTest : public CvArrTest
51 {
52 public:
53     CV_ThreshTest();
54
55 protected:
56     void get_test_array_types_and_sizes( int test_case_idx, CvSize** sizes, int** types );
57     double get_success_error_level( int test_case_idx, int i, int j );
58     void run_func();
59     void prepare_to_validation( int );
60     
61     int write_default_params(CvFileStorage* fs);
62     void get_timing_test_array_types_and_sizes( int test_case_idx, CvSize** sizes, int** types,
63                                                 CvSize** whole_sizes, bool *are_images );
64     void print_timing_params( int test_case_idx, char* ptr, int params_left );
65
66     int thresh_type;
67     float thresh_val;
68     float max_val;
69 };
70
71
72 CV_ThreshTest::CV_ThreshTest()
73     : CvArrTest( "thresh-simple", "cvThreshold", "" )
74 {
75     test_array[INPUT].push(NULL);
76     test_array[OUTPUT].push(NULL);
77     test_array[REF_OUTPUT].push(NULL);
78     optional_mask = false;
79     element_wise_relative_error = true;
80
81     default_timing_param_names = thresh_param_names;
82     depth_list = thresh_depths;
83     size_list = thresh_sizes;
84     whole_size_list = thresh_whole_sizes;
85     cn_list = 0;
86 }
87
88
89 void CV_ThreshTest::get_test_array_types_and_sizes( int test_case_idx,
90                                                 CvSize** sizes, int** types )
91 {
92     CvRNG* rng = ts->get_rng();
93     int depth = cvTsRandInt(rng) % 2, cn = cvTsRandInt(rng) % 4 + 1;
94     CvArrTest::get_test_array_types_and_sizes( test_case_idx, sizes, types );
95     depth = depth == 0 ? CV_8U : CV_32F;
96
97     types[INPUT][0] = types[OUTPUT][0] = types[REF_OUTPUT][0] = CV_MAKETYPE(depth,cn);
98     thresh_type = cvTsRandInt(rng) % 5;
99
100     if( depth == CV_8U )
101     {
102         thresh_val = (float)(cvTsRandReal(rng)*350. - 50.);
103         max_val = (float)(cvTsRandReal(rng)*350. - 50.);
104         if( cvTsRandInt(rng)%4 == 0 )
105             max_val = 255;
106     }
107     else
108     {
109         thresh_val = (float)(cvTsRandReal(rng)*1000. - 500.);
110         max_val = (float)(cvTsRandReal(rng)*1000. - 500.);
111     }
112 }
113
114
115 double CV_ThreshTest::get_success_error_level( int /*test_case_idx*/, int /*i*/, int /*j*/ )
116 {
117     return FLT_EPSILON*10;
118 }
119
120
121 void CV_ThreshTest::run_func()
122 {
123     cvThreshold( test_array[INPUT][0], test_array[OUTPUT][0],
124                  thresh_val, max_val, thresh_type );
125 }
126
127
128 static void cvTsThreshold( const CvMat* _src, CvMat* _dst,
129                            float thresh, float maxval, int thresh_type )
130 {
131     int i, j;
132     int depth = CV_MAT_DEPTH(_src->type), cn = CV_MAT_CN(_src->type);
133     int width_n = _src->cols*cn, height = _src->rows;
134     int ithresh = cvFloor(thresh), ithresh2, imaxval = cvRound(maxval);
135     const uchar* src = _src->data.ptr;
136     uchar* dst = _dst->data.ptr;
137     
138     ithresh2 = CV_CAST_8U(ithresh);
139     imaxval = CV_CAST_8U(imaxval);
140
141     assert( depth == CV_8U || depth == CV_32F );
142     
143     switch( thresh_type )
144     {
145     case CV_THRESH_BINARY:
146         for( i = 0; i < height; i++, src += _src->step, dst += _dst->step )
147         {
148             if( depth == CV_8U )
149                 for( j = 0; j < width_n; j++ )
150                     dst[j] = (uchar)(src[j] > ithresh ? imaxval : 0);
151             else
152                 for( j = 0; j < width_n; j++ )
153                     ((float*)dst)[j] = ((const float*)src)[j] > thresh ? maxval : 0.f;
154         }
155         break;
156     case CV_THRESH_BINARY_INV:
157         for( i = 0; i < height; i++, src += _src->step, dst += _dst->step )
158         {
159             if( depth == CV_8U )
160                 for( j = 0; j < width_n; j++ )
161                     dst[j] = (uchar)(src[j] > ithresh ? 0 : imaxval);
162             else
163                 for( j = 0; j < width_n; j++ )
164                     ((float*)dst)[j] = ((const float*)src)[j] > thresh ? 0.f : maxval;
165         }
166         break;
167     case CV_THRESH_TRUNC:
168         for( i = 0; i < height; i++, src += _src->step, dst += _dst->step )
169         {
170             if( depth == CV_8U )
171                 for( j = 0; j < width_n; j++ )
172                 {
173                     int s = src[j];
174                     dst[j] = (uchar)(s > ithresh ? ithresh2 : s);
175                 }
176             else
177                 for( j = 0; j < width_n; j++ )
178                 {
179                     float s = ((const float*)src)[j];
180                     ((float*)dst)[j] = s > thresh ? thresh : s;
181                 }
182         }
183         break;
184     case CV_THRESH_TOZERO:
185         for( i = 0; i < height; i++, src += _src->step, dst += _dst->step )
186         {
187             if( depth == CV_8U )
188                 for( j = 0; j < width_n; j++ )
189                 {
190                     int s = src[j];
191                     dst[j] = (uchar)(s > ithresh ? s : 0);
192                 }
193             else
194                 for( j = 0; j < width_n; j++ )
195                 {
196                     float s = ((const float*)src)[j];
197                     ((float*)dst)[j] = s > thresh ? s : 0.f;
198                 }
199         }
200         break;
201     case CV_THRESH_TOZERO_INV:
202         for( i = 0; i < height; i++, src += _src->step, dst += _dst->step )
203         {
204             if( depth == CV_8U )
205                 for( j = 0; j < width_n; j++ )
206                 {
207                     int s = src[j];
208                     dst[j] = (uchar)(s > ithresh ? 0 : s);
209                 }
210             else
211                 for( j = 0; j < width_n; j++ )
212                 {
213                     float s = ((const float*)src)[j];
214                     ((float*)dst)[j] = s > thresh ? 0.f : s;
215                 }
216         }
217         break;
218     default:
219         assert(0);
220     }
221 }
222
223
224 void CV_ThreshTest::prepare_to_validation( int /*test_case_idx*/ )
225 {
226     cvTsThreshold( &test_mat[INPUT][0], &test_mat[REF_OUTPUT][0],
227                    thresh_val, max_val, thresh_type );
228 }
229
230
231 int CV_ThreshTest::write_default_params( CvFileStorage* fs )
232 {
233     int code = CvArrTest::write_default_params( fs );
234     if( code < 0 )
235         return code;
236     
237     if( ts->get_testing_mode() == CvTS::TIMING_MODE )
238     {
239         start_write_param( fs );        
240         write_string_list( fs, "thresh_type", thresh_types );
241     }
242
243     return code;
244 }
245
246
247 void CV_ThreshTest::get_timing_test_array_types_and_sizes( int test_case_idx,
248                 CvSize** sizes, int** types, CvSize** whole_sizes, bool *are_images )
249 {
250     CvArrTest::get_timing_test_array_types_and_sizes( test_case_idx, sizes, types,
251                                                       whole_sizes, are_images );
252     const char* thresh_str = cvReadString( find_timing_param( "thresh_type" ), "binary" );
253     thresh_type = strcmp( thresh_str, "binary" ) == 0 ? CV_THRESH_BINARY :
254         strcmp( thresh_str, "binary_inv" ) == 0 ? CV_THRESH_BINARY_INV :
255         strcmp( thresh_str, "trunc" ) == 0 ? CV_THRESH_TRUNC :
256         strcmp( thresh_str, "tozero" ) == 0 ? CV_THRESH_TOZERO :
257         CV_THRESH_TOZERO_INV;
258
259     if( CV_MAT_DEPTH(types[INPUT][0]) == CV_8U )
260     {
261         thresh_val = 128;
262         max_val = 255;
263     }
264     else
265     {
266         thresh_val = 500.;
267         max_val = 1.;
268     }
269 }
270
271
272 void CV_ThreshTest::print_timing_params( int test_case_idx, char* ptr, int params_left )
273 {
274     sprintf( ptr, "%s,", cvReadString( find_timing_param( "thresh_type" ), "binary" ) );
275     ptr += strlen(ptr);
276     params_left--;
277
278     CvArrTest::print_timing_params( test_case_idx, ptr, params_left );
279 }
280
281
282 CV_ThreshTest thresh_test;
283