Path: blob/master/modules/imgproc/test/test_thresh.cpp
16354 views
/*M///////////////////////////////////////////////////////////////////////////////////////1//2// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.3//4// By downloading, copying, installing or using the software you agree to this license.5// If you do not agree to this license, do not download, install,6// copy or use the software.7//8//9// Intel License Agreement10// For Open Source Computer Vision Library11//12// Copyright (C) 2000, Intel Corporation, all rights reserved.13// Third party copyrights are property of their respective owners.14//15// Redistribution and use in source and binary forms, with or without modification,16// are permitted provided that the following conditions are met:17//18// * Redistribution's of source code must retain the above copyright notice,19// this list of conditions and the following disclaimer.20//21// * Redistribution's in binary form must reproduce the above copyright notice,22// this list of conditions and the following disclaimer in the documentation23// and/or other materials provided with the distribution.24//25// * The name of Intel Corporation may not be used to endorse or promote products26// derived from this software without specific prior written permission.27//28// This software is provided by the copyright holders and contributors "as is" and29// any express or implied warranties, including, but not limited to, the implied30// warranties of merchantability and fitness for a particular purpose are disclaimed.31// In no event shall the Intel Corporation or contributors be liable for any direct,32// indirect, incidental, special, exemplary, or consequential damages33// (including, but not limited to, procurement of substitute goods or services;34// loss of use, data, or profits; or business interruption) however caused35// and on any theory of liability, whether in contract, strict liability,36// or tort (including negligence or otherwise) arising in any way out of37// the use of this software, even if advised of the possibility of such damage.38//39//M*/4041#include "test_precomp.hpp"4243namespace opencv_test { namespace {4445class CV_ThreshTest : public cvtest::ArrayTest46{47public:48CV_ThreshTest();4950protected:51void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types );52double get_success_error_level( int test_case_idx, int i, int j );53void run_func();54void prepare_to_validation( int );5556int thresh_type;57double thresh_val;58double max_val;59};606162CV_ThreshTest::CV_ThreshTest()63{64test_array[INPUT].push_back(NULL);65test_array[OUTPUT].push_back(NULL);66test_array[REF_OUTPUT].push_back(NULL);67optional_mask = false;68element_wise_relative_error = true;69}707172void CV_ThreshTest::get_test_array_types_and_sizes( int test_case_idx,73vector<vector<Size> >& sizes, vector<vector<int> >& types )74{75RNG& rng = ts->get_rng();76int depth = cvtest::randInt(rng) % 5, cn = cvtest::randInt(rng) % 4 + 1;77cvtest::ArrayTest::get_test_array_types_and_sizes( test_case_idx, sizes, types );78depth = depth == 0 ? CV_8U : depth == 1 ? CV_16S : depth == 2 ? CV_16U : depth == 3 ? CV_32F : CV_64F;7980types[INPUT][0] = types[OUTPUT][0] = types[REF_OUTPUT][0] = CV_MAKETYPE(depth,cn);81thresh_type = cvtest::randInt(rng) % 5;8283if( depth == CV_8U )84{85thresh_val = (cvtest::randReal(rng)*350. - 50.);86max_val = (cvtest::randReal(rng)*350. - 50.);87if( cvtest::randInt(rng)%4 == 0 )88max_val = 255.f;89}90else if( depth == CV_16S )91{92double min_val = SHRT_MIN-100.f;93max_val = SHRT_MAX+100.f;94thresh_val = (cvtest::randReal(rng)*(max_val - min_val) + min_val);95max_val = (cvtest::randReal(rng)*(max_val - min_val) + min_val);96if( cvtest::randInt(rng)%4 == 0 )97max_val = (double)SHRT_MAX;98}99else if( depth == CV_16U )100{101double min_val = -100.f;102max_val = USHRT_MAX+100.f;103thresh_val = (cvtest::randReal(rng)*(max_val - min_val) + min_val);104max_val = (cvtest::randReal(rng)*(max_val - min_val) + min_val);105if( cvtest::randInt(rng)%4 == 0 )106max_val = (double)USHRT_MAX;107}108else109{110thresh_val = (cvtest::randReal(rng)*1000. - 500.);111max_val = (cvtest::randReal(rng)*1000. - 500.);112}113}114115116double CV_ThreshTest::get_success_error_level( int /*test_case_idx*/, int /*i*/, int /*j*/ )117{118return FLT_EPSILON*10;119}120121122void CV_ThreshTest::run_func()123{124cvThreshold( test_array[INPUT][0], test_array[OUTPUT][0],125thresh_val, max_val, thresh_type );126}127128129static void test_threshold( const Mat& _src, Mat& _dst,130double thresh, double maxval, int thresh_type )131{132int i, j;133int depth = _src.depth(), cn = _src.channels();134int width_n = _src.cols*cn, height = _src.rows;135int ithresh = cvFloor(thresh);136int imaxval, ithresh2;137138if( depth == CV_8U )139{140ithresh2 = saturate_cast<uchar>(ithresh);141imaxval = saturate_cast<uchar>(maxval);142}143else if( depth == CV_16S )144{145ithresh2 = saturate_cast<short>(ithresh);146imaxval = saturate_cast<short>(maxval);147}148else if( depth == CV_16U )149{150ithresh2 = saturate_cast<ushort>(ithresh);151imaxval = saturate_cast<ushort>(maxval);152}153else154{155ithresh2 = cvRound(ithresh);156imaxval = cvRound(maxval);157}158159assert( depth == CV_8U || depth == CV_16S || depth == CV_16U || depth == CV_32F || depth == CV_64F );160161switch( thresh_type )162{163case CV_THRESH_BINARY:164for( i = 0; i < height; i++ )165{166if( depth == CV_8U )167{168const uchar* src = _src.ptr<uchar>(i);169uchar* dst = _dst.ptr<uchar>(i);170for( j = 0; j < width_n; j++ )171dst[j] = (uchar)(src[j] > ithresh ? imaxval : 0);172}173else if( depth == CV_16S )174{175const short* src = _src.ptr<short>(i);176short* dst = _dst.ptr<short>(i);177for( j = 0; j < width_n; j++ )178dst[j] = (short)(src[j] > ithresh ? imaxval : 0);179}180else if( depth == CV_16U )181{182const ushort* src = _src.ptr<ushort>(i);183ushort* dst = _dst.ptr<ushort>(i);184for( j = 0; j < width_n; j++ )185dst[j] = (ushort)(src[j] > ithresh ? imaxval : 0);186}187else if( depth == CV_32F )188{189const float* src = _src.ptr<float>(i);190float* dst = _dst.ptr<float>(i);191for( j = 0; j < width_n; j++ )192dst[j] = (float)(src[j] > thresh ? maxval : 0.f);193}194else195{196const double* src = _src.ptr<double>(i);197double* dst = _dst.ptr<double>(i);198for( j = 0; j < width_n; j++ )199dst[j] = src[j] > thresh ? maxval : 0.0;200}201}202break;203case CV_THRESH_BINARY_INV:204for( i = 0; i < height; i++ )205{206if( depth == CV_8U )207{208const uchar* src = _src.ptr<uchar>(i);209uchar* dst = _dst.ptr<uchar>(i);210for( j = 0; j < width_n; j++ )211dst[j] = (uchar)(src[j] > ithresh ? 0 : imaxval);212}213else if( depth == CV_16S )214{215const short* src = _src.ptr<short>(i);216short* dst = _dst.ptr<short>(i);217for( j = 0; j < width_n; j++ )218dst[j] = (short)(src[j] > ithresh ? 0 : imaxval);219}220else if( depth == CV_16U )221{222const ushort* src = _src.ptr<ushort>(i);223ushort* dst = _dst.ptr<ushort>(i);224for( j = 0; j < width_n; j++ )225dst[j] = (ushort)(src[j] > ithresh ? 0 : imaxval);226}227else if( depth == CV_32F )228{229const float* src = _src.ptr<float>(i);230float* dst = _dst.ptr<float>(i);231for( j = 0; j < width_n; j++ )232dst[j] = (float)(src[j] > thresh ? 0.f : maxval);233}234else235{236const double* src = _src.ptr<double>(i);237double* dst = _dst.ptr<double>(i);238for( j = 0; j < width_n; j++ )239dst[j] = src[j] > thresh ? 0.0 : maxval;240}241}242break;243case CV_THRESH_TRUNC:244for( i = 0; i < height; i++ )245{246if( depth == CV_8U )247{248const uchar* src = _src.ptr<uchar>(i);249uchar* dst = _dst.ptr<uchar>(i);250for( j = 0; j < width_n; j++ )251{252int s = src[j];253dst[j] = (uchar)(s > ithresh ? ithresh2 : s);254}255}256else if( depth == CV_16S )257{258const short* src = _src.ptr<short>(i);259short* dst = _dst.ptr<short>(i);260for( j = 0; j < width_n; j++ )261{262int s = src[j];263dst[j] = (short)(s > ithresh ? ithresh2 : s);264}265}266else if( depth == CV_16U )267{268const ushort* src = _src.ptr<ushort>(i);269ushort* dst = _dst.ptr<ushort>(i);270for( j = 0; j < width_n; j++ )271{272int s = src[j];273dst[j] = (ushort)(s > ithresh ? ithresh2 : s);274}275}276else if( depth == CV_32F )277{278const float* src = _src.ptr<float>(i);279float* dst = _dst.ptr<float>(i);280for( j = 0; j < width_n; j++ )281{282float s = src[j];283dst[j] = (float)(s > thresh ? thresh : s);284}285}286else287{288const double* src = _src.ptr<double>(i);289double* dst = _dst.ptr<double>(i);290for( j = 0; j < width_n; j++ )291{292double s = src[j];293dst[j] = s > thresh ? thresh : s;294}295}296}297break;298case CV_THRESH_TOZERO:299for( i = 0; i < height; i++ )300{301if( depth == CV_8U )302{303const uchar* src = _src.ptr<uchar>(i);304uchar* dst = _dst.ptr<uchar>(i);305for( j = 0; j < width_n; j++ )306{307int s = src[j];308dst[j] = (uchar)(s > ithresh ? s : 0);309}310}311else if( depth == CV_16S )312{313const short* src = _src.ptr<short>(i);314short* dst = _dst.ptr<short>(i);315for( j = 0; j < width_n; j++ )316{317int s = src[j];318dst[j] = (short)(s > ithresh ? s : 0);319}320}321else if( depth == CV_16U )322{323const ushort* src = _src.ptr<ushort>(i);324ushort* dst = _dst.ptr<ushort>(i);325for( j = 0; j < width_n; j++ )326{327int s = src[j];328dst[j] = (ushort)(s > ithresh ? s : 0);329}330}331else if( depth == CV_32F )332{333const float* src = _src.ptr<float>(i);334float* dst = _dst.ptr<float>(i);335for( j = 0; j < width_n; j++ )336{337float s = src[j];338dst[j] = s > thresh ? s : 0.f;339}340}341else342{343const double* src = _src.ptr<double>(i);344double* dst = _dst.ptr<double>(i);345for( j = 0; j < width_n; j++ )346{347double s = src[j];348dst[j] = s > thresh ? s : 0.0;349}350}351}352break;353case CV_THRESH_TOZERO_INV:354for( i = 0; i < height; i++ )355{356if( depth == CV_8U )357{358const uchar* src = _src.ptr<uchar>(i);359uchar* dst = _dst.ptr<uchar>(i);360for( j = 0; j < width_n; j++ )361{362int s = src[j];363dst[j] = (uchar)(s > ithresh ? 0 : s);364}365}366else if( depth == CV_16S )367{368const short* src = _src.ptr<short>(i);369short* dst = _dst.ptr<short>(i);370for( j = 0; j < width_n; j++ )371{372int s = src[j];373dst[j] = (short)(s > ithresh ? 0 : s);374}375}376else if( depth == CV_16U )377{378const ushort* src = _src.ptr<ushort>(i);379ushort* dst = _dst.ptr<ushort>(i);380for( j = 0; j < width_n; j++ )381{382int s = src[j];383dst[j] = (ushort)(s > ithresh ? 0 : s);384}385}386else if (depth == CV_32F)387{388const float* src = _src.ptr<float>(i);389float* dst = _dst.ptr<float>(i);390for( j = 0; j < width_n; j++ )391{392float s = src[j];393dst[j] = s > thresh ? 0.f : s;394}395}396else397{398const double* src = _src.ptr<double>(i);399double* dst = _dst.ptr<double>(i);400for( j = 0; j < width_n; j++ )401{402double s = src[j];403dst[j] = s > thresh ? 0.0 : s;404}405}406}407break;408default:409assert(0);410}411}412413414void CV_ThreshTest::prepare_to_validation( int /*test_case_idx*/ )415{416test_threshold( test_mat[INPUT][0], test_mat[REF_OUTPUT][0],417thresh_val, max_val, thresh_type );418}419420TEST(Imgproc_Threshold, accuracy) { CV_ThreshTest test; test.safe_run(); }421422BIGDATA_TEST(Imgproc_Threshold, huge)423{424Mat m(65000, 40000, CV_8U);425ASSERT_FALSE(m.isContinuous());426427uint64 i, n = (uint64)m.rows*m.cols;428for( i = 0; i < n; i++ )429m.data[i] = (uchar)(i & 255);430431cv::threshold(m, m, 127, 255, cv::THRESH_BINARY);432int nz = cv::countNonZero(m); // FIXIT 'int' is not enough here (overflow is possible with other inputs)433ASSERT_EQ((uint64)nz, n / 2);434}435436}} // namespace437438439