fixed bug for #1496 and correctness tests for function CheckRange
This commit is contained in:
parent
8fcd0d9222
commit
32b9bc1d00
@ -1996,10 +1996,89 @@ void sqrt(InputArray a, OutputArray b)
|
|||||||
|
|
||||||
/************************** CheckArray for NaN's, Inf's *********************************/
|
/************************** CheckArray for NaN's, Inf's *********************************/
|
||||||
|
|
||||||
bool checkRange(InputArray _src, bool quiet, Point* pt,
|
template<int cv_mat_type> struct mat_type_assotiations{};
|
||||||
double minVal, double maxVal)
|
|
||||||
|
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();
|
Mat src = _src.getMat();
|
||||||
|
|
||||||
if ( src.dims > 2 )
|
if ( src.dims > 2 )
|
||||||
{
|
{
|
||||||
const Mat* arrays[] = {&src, 0};
|
const Mat* arrays[] = {&src, 0};
|
||||||
@ -2023,19 +2102,10 @@ bool checkRange(InputArray _src, bool quiet, Point* pt,
|
|||||||
|
|
||||||
if (depth < CV_32F)
|
if (depth < CV_32F)
|
||||||
{
|
{
|
||||||
double m = 0, M = 0;
|
int minVali = cvFloor(minVal);
|
||||||
Point mp, MP;
|
int maxVali = cvCeil(maxVal);
|
||||||
minMaxLoc(src.reshape(1,0), &m, &M, &mp, &MP);
|
|
||||||
if( M >= maxVal )
|
(check_range_functions[depth])(src, badPt, minVali, maxVali, badValue);
|
||||||
{
|
|
||||||
badPt = MP;
|
|
||||||
badValue = M;
|
|
||||||
}
|
|
||||||
else if( m < minVal )
|
|
||||||
{
|
|
||||||
badPt = mp;
|
|
||||||
badValue = m;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
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