fixed bug for #1496 and correctness tests for function CheckRange
This commit is contained in:
parent
8fcd0d9222
commit
32b9bc1d00
@ -1996,19 +1996,98 @@ void sqrt(InputArray a, OutputArray b)
|
||||
|
||||
/************************** CheckArray for NaN's, Inf's *********************************/
|
||||
|
||||
bool checkRange(InputArray _src, bool quiet, Point* pt,
|
||||
double minVal, double maxVal)
|
||||
template<int cv_mat_type> struct mat_type_assotiations{};
|
||||
|
||||
template<> struct mat_type_assotiations<CV_8U>
|
||||
{
|
||||
typedef unsigned char type;
|
||||
static const type min_allowable = 0x0;
|
||||
static const type max_allowable = 0xFF;
|
||||
};
|
||||
|
||||
template<> struct mat_type_assotiations<CV_8S>
|
||||
{
|
||||
typedef signed char type;
|
||||
static const type min_allowable = SCHAR_MIN;
|
||||
static const type max_allowable = SCHAR_MAX;
|
||||
};
|
||||
|
||||
template<> struct mat_type_assotiations<CV_16U>
|
||||
{
|
||||
typedef unsigned short type;
|
||||
static const type min_allowable = 0x0;
|
||||
static const type max_allowable = USHRT_MAX;
|
||||
};
|
||||
template<> struct mat_type_assotiations<CV_16S>
|
||||
{
|
||||
typedef signed short type;
|
||||
static const type min_allowable = SHRT_MIN;
|
||||
static const type max_allowable = SHRT_MAX;
|
||||
};
|
||||
|
||||
template<> struct mat_type_assotiations<CV_32S>
|
||||
{
|
||||
typedef int type;
|
||||
static const type min_allowable = (-INT_MAX - 1);
|
||||
static const type max_allowable = INT_MAX;
|
||||
};
|
||||
|
||||
template<int depth>
|
||||
bool chackIntegerRang(cv::Mat src, Point& bad_pt, int minVal, int maxVal, double& bad_value)
|
||||
{
|
||||
typedef mat_type_assotiations<depth> type_ass;
|
||||
|
||||
if (minVal < type_ass::min_allowable && maxVal > type_ass::max_allowable)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (minVal >= type_ass::max_allowable || maxVal <= type_ass::min_allowable || maxVal <= minVal)
|
||||
{
|
||||
bad_pt = cv::Point(0,0);
|
||||
return false;
|
||||
}
|
||||
cv::Mat as_one_channel = src.reshape(1,0);
|
||||
|
||||
for (int j = 0; j < as_one_channel.rows; ++j)
|
||||
for (int i = 0; i < as_one_channel.cols; ++i)
|
||||
{
|
||||
if (as_one_channel.at<typename type_ass::type>(j ,i) <= minVal || as_one_channel.at<typename type_ass::type>(j ,i) >= maxVal)
|
||||
{
|
||||
bad_pt.y = j ;
|
||||
bad_pt.x = i % src.channels();
|
||||
bad_value = as_one_channel.at<typename type_ass::type>(j ,i);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
bad_value = 0.0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
typedef bool (*check_pange_function)(cv::Mat src, Point& bad_pt, int minVal, int maxVal, double& bad_value);
|
||||
|
||||
check_pange_function check_range_functions[] =
|
||||
{
|
||||
&chackIntegerRang<CV_8U>,
|
||||
&chackIntegerRang<CV_8S>,
|
||||
&chackIntegerRang<CV_16U>,
|
||||
&chackIntegerRang<CV_16S>,
|
||||
&chackIntegerRang<CV_32S>
|
||||
};
|
||||
|
||||
bool checkRange(InputArray _src, bool quiet, Point* pt, double minVal, double maxVal)
|
||||
{
|
||||
Mat src = _src.getMat();
|
||||
if( src.dims > 2 )
|
||||
|
||||
if ( src.dims > 2 )
|
||||
{
|
||||
const Mat* arrays[] = {&src, 0};
|
||||
Mat planes[1];
|
||||
NAryMatIterator it(arrays, planes);
|
||||
|
||||
for( size_t i = 0; i < it.nplanes; i++, ++it )
|
||||
for ( size_t i = 0; i < it.nplanes; i++, ++it )
|
||||
{
|
||||
if( !checkRange( it.planes[0], quiet, pt, minVal, maxVal ))
|
||||
if (!checkRange( it.planes[0], quiet, pt, minVal, maxVal ))
|
||||
{
|
||||
// todo: set index properly
|
||||
return false;
|
||||
@ -2021,21 +2100,12 @@ bool checkRange(InputArray _src, bool quiet, Point* pt,
|
||||
Point badPt(-1, -1);
|
||||
double badValue = 0;
|
||||
|
||||
if( depth < CV_32F )
|
||||
if (depth < CV_32F)
|
||||
{
|
||||
double m = 0, M = 0;
|
||||
Point mp, MP;
|
||||
minMaxLoc(src.reshape(1,0), &m, &M, &mp, &MP);
|
||||
if( M >= maxVal )
|
||||
{
|
||||
badPt = MP;
|
||||
badValue = M;
|
||||
}
|
||||
else if( m < minVal )
|
||||
{
|
||||
badPt = mp;
|
||||
badValue = m;
|
||||
}
|
||||
int minVali = cvFloor(minVal);
|
||||
int maxVali = cvCeil(maxVal);
|
||||
|
||||
(check_range_functions[depth])(src, badPt, minVali, maxVali, badValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2347,6 +2347,93 @@ void Core_SolvePolyTest::run( int )
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T> class Core_CheckRange : public testing::Test {};
|
||||
|
||||
template<typename type> struct depth_for_type{};
|
||||
|
||||
template<> struct depth_for_type<unsigned char>
|
||||
{
|
||||
static const int depth = CV_8U;
|
||||
};
|
||||
|
||||
template<> struct depth_for_type<signed char>
|
||||
{
|
||||
static const int depth = CV_8S;
|
||||
};
|
||||
|
||||
template<> struct depth_for_type<unsigned short>
|
||||
{
|
||||
static const int depth = CV_16U;
|
||||
};
|
||||
|
||||
template<> struct depth_for_type<signed short>
|
||||
{
|
||||
static const int depth = CV_16S;
|
||||
};
|
||||
|
||||
template<> struct depth_for_type<signed int>
|
||||
{
|
||||
static const int depth = CV_32S;
|
||||
};
|
||||
|
||||
|
||||
TYPED_TEST_CASE_P(Core_CheckRange);
|
||||
|
||||
TYPED_TEST_P(Core_CheckRange, Negative)
|
||||
{
|
||||
double min_bound = 4.5;
|
||||
double max_bound = 16.0;
|
||||
|
||||
TypeParam data[] = {5, 10, 15, 4, 10 ,2, 8, 12, 14};
|
||||
cv::Mat src = cv::Mat(3,3, depth_for_type<TypeParam>::depth, data);
|
||||
|
||||
cv::Point* bad_pt = new cv::Point(0, 0);
|
||||
|
||||
ASSERT_FALSE(checkRange(src, true, bad_pt, min_bound, max_bound));
|
||||
ASSERT_EQ(bad_pt->x,0);
|
||||
ASSERT_EQ(bad_pt->y,1);
|
||||
|
||||
delete bad_pt;
|
||||
}
|
||||
|
||||
TYPED_TEST_P(Core_CheckRange, Positive)
|
||||
{
|
||||
double min_bound = -1;
|
||||
double max_bound = 16.0;
|
||||
|
||||
TypeParam data[] = {5, 10, 15, 4, 10 ,2, 8, 12, 14};
|
||||
cv::Mat src = cv::Mat(3,3, depth_for_type<TypeParam>::depth, data);
|
||||
|
||||
cv::Point* bad_pt = new cv::Point(0, 0);
|
||||
|
||||
ASSERT_TRUE(checkRange(src, true, bad_pt, min_bound, max_bound));
|
||||
ASSERT_EQ(bad_pt->x,0);
|
||||
ASSERT_EQ(bad_pt->y,0);
|
||||
|
||||
delete bad_pt;
|
||||
}
|
||||
|
||||
TYPED_TEST_P(Core_CheckRange, Bounds)
|
||||
{
|
||||
double min_bound = 24.5;
|
||||
double max_bound = 1.0;
|
||||
|
||||
TypeParam data[] = {5, 10, 15, 4, 10 ,2, 8, 12, 14};
|
||||
cv::Mat src = cv::Mat(3,3, depth_for_type<TypeParam>::depth, data);
|
||||
|
||||
cv::Point* bad_pt = new cv::Point(0, 0);
|
||||
|
||||
ASSERT_FALSE(checkRange(src, true, bad_pt, min_bound, max_bound));
|
||||
ASSERT_EQ(bad_pt->x,0);
|
||||
ASSERT_EQ(bad_pt->y,0);
|
||||
|
||||
delete bad_pt;
|
||||
}
|
||||
|
||||
REGISTER_TYPED_TEST_CASE_P(Core_CheckRange, Negative, Positive, Bounds);
|
||||
|
||||
typedef ::testing::Types<signed char,unsigned char, signed short, unsigned short, signed int> mat_data_types;
|
||||
INSTANTIATE_TYPED_TEST_CASE_P(Negative_Test, Core_CheckRange, mat_data_types);
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user