1 | initial version |
NaN
's are not explicitely handled by remap()
.
What it happens there is that you convert a floating point value of NaN to integer (to use it as index in the src matrix). Cf to the C standard,
6.3.1.4 Real floating and integer
When a finite value of real floating type is converted to an integer type other than _Bool, the fractional part is discarded (i.e., the value is truncated toward zero). If the value of the integral part cannot be represented by the integer type, the behavior is undefined.50)
Probably, in your case, the undefined behavoiur is to map NaN's to 0. So, when you access src(NaN, NaN) you actually see src(0, 0), but it's a good chance that it will crash with a different compiler/architecture/processor
The intended way to handle pixels that are not defined in the source image is to set them as real values outside the src image:
x,y < 0, 0
or
x, y > width-1, height-1
When this happens, they are treated according to the two border parameters (borderType, borderValue)
Bonus
If you really want to know what's inside, here is the OpenCV procedure called by saturate_cast<int>
, which is called by convertMaps()
which in turn is called by remap()
:
CV_INLINE int cvRound( double value )
{
#if (defined _MSC_VER && defined _M_X64) || (defined __GNUC__ && defined __x86_64__ && defined __SSE2__ && !defined __APPLE__)
__m128d t = _mm_set_sd( value );
return _mm_cvtsd_si32(t);
#elif defined _MSC_VER && defined _M_IX86
int t;
__asm
{
fld value;
fistp t;
}
return t;
#elif defined HAVE_LRINT || defined CV_ICC || defined __GNUC__
# ifdef HAVE_TEGRA_OPTIMIZATION
TEGRA_ROUND(value);
# else
return (int)lrint(value);
# endif
#else
// while this is not IEEE754-compliant rounding, it's usually a good enough approximation
return (int)(value + (value >= 0 ? 0.5 : -0.5));
#endif
}
2 | No.2 Revision |
NaN
's are not explicitely handled by remap()
.
What it happens there is that you convert a floating point value of NaN to integer (to use it as index in the src matrix). Cf to the C standard,
6.3.1.4 Real floating and integer
When a finite value of real floating type is converted to an integer type other than _Bool, the fractional part is discarded (i.e., the value is truncated toward zero). If the value of the integral part cannot be represented by the integer type, the behavior is undefined.50)
Probably, in your case, the undefined behavoiur is to map NaN's to 0. So, when you access src(NaN, NaN) you actually see src(0, 0), but it's a good chance that it will crash with a different compiler/architecture/processor
The intended way to handle pixels that are not defined in the source image is to set them as real values outside the src image:
x,y < 0, 0
or
x, y > width-1, height-1
When this happens, they are treated according to the two border parameters (borderType, borderValue)
Bonus
If you really want to know what's inside, here is the OpenCV procedure called by saturate_cast<int>
, which is called by convertMaps()
which in turn is called by remap()
:. It converts the float coordinates into a complicated mesh of integer math, by rounding and shifts.
CV_INLINE int cvRound( double value )
{
#if (defined _MSC_VER && defined _M_X64) || (defined __GNUC__ && defined __x86_64__ && defined __SSE2__ && !defined __APPLE__)
__m128d t = _mm_set_sd( value );
return _mm_cvtsd_si32(t);
#elif defined _MSC_VER && defined _M_IX86
int t;
__asm
{
fld value;
fistp t;
}
return t;
#elif defined HAVE_LRINT || defined CV_ICC || defined __GNUC__
# ifdef HAVE_TEGRA_OPTIMIZATION
TEGRA_ROUND(value);
# else
return (int)lrint(value);
# endif
#else
// while this is not IEEE754-compliant rounding, it's usually a good enough approximation
return (int)(value + (value >= 0 ? 0.5 : -0.5));
#endif
}
3 | No.3 Revision |
NaN
's are not explicitely handled by remap()
.
What it happens there is that you convert a floating point value of NaN to integer (to use it as index in the src matrix). Cf to the C standard,
6.3.1.4 Real floating and integer
When a finite value of real floating type is converted to an integer type other than _Bool, the fractional part is discarded (i.e., the value is truncated toward zero). If the value of the integral part cannot be represented by the integer type, the behavior is undefined.50)
Probably, in your case, the behavoiur is to map NaN's to 0. So, when you access src(NaN, NaN) you actually see src(0, 0), but it's a good chance that it will crash with a different compiler/architecture/processor
The intended way to handle pixels that are not defined in the source image is to set them as real values outside the src image:
x,y < 0, 0
or
x, y > width-1, height-1
When this happens, they are treated according to the two border parameters (borderType, borderValue)
Update
I've checked on Win7, VS2010, and (int)NaN
is 0
, confirming your finding.
Bonus
If you really want to know what's inside, here is the OpenCV procedure called by saturate_cast<int>
, which is called by convertMaps()
which in turn is called by remap()
. It converts the float coordinates into a complicated mesh of integer math, by rounding and shifts.
CV_INLINE int cvRound( double value )
{
#if (defined _MSC_VER && defined _M_X64) || (defined __GNUC__ && defined __x86_64__ && defined __SSE2__ && !defined __APPLE__)
__m128d t = _mm_set_sd( value );
return _mm_cvtsd_si32(t);
#elif defined _MSC_VER && defined _M_IX86
int t;
__asm
{
fld value;
fistp t;
}
return t;
#elif defined HAVE_LRINT || defined CV_ICC || defined __GNUC__
# ifdef HAVE_TEGRA_OPTIMIZATION
TEGRA_ROUND(value);
# else
return (int)lrint(value);
# endif
#else
// while this is not IEEE754-compliant rounding, it's usually a good enough approximation
return (int)(value + (value >= 0 ? 0.5 : -0.5));
#endif
}
4 | No.4 Revision |
NaN
's are not explicitely handled by remap()
.
What it happens there is that you convert a floating point value of NaN to integer (to use it as index in the src matrix). Cf to the C standard,
6.3.1.4 Real floating and integer
When a finite value of real floating type is converted to an integer type other than _Bool, the fractional part is discarded (i.e., the value is truncated toward zero). If the value of the integral part cannot be represented by the integer type, the behavior is undefined.50)
Probably, in your case, the behavoiur is to map NaN's to 0. So, when you access src(NaN, NaN) you actually see src(0, 0), but it's a good chance that it will crash with a different compiler/architecture/processor
The intended way to handle pixels that are not defined in the source image is to set them as real values outside the src image:
x,y < 0, 0
or
x, y > width-1, height-1
When this happens, they are treated according to the two border parameters (borderType, borderValue)
Update
I've checked on Win7, VS2010, and
is (int)NaN(unsigned int)NaN0
, confirming your finding.
Bonus
If you really want to know what's inside, here is the OpenCV procedure called by saturate_cast<int>
, which is called by convertMaps()
which in turn is called by remap()
. It converts the float coordinates into a complicated mesh of integer math, by rounding and shifts.
CV_INLINE int cvRound( double value )
{
#if (defined _MSC_VER && defined _M_X64) || (defined __GNUC__ && defined __x86_64__ && defined __SSE2__ && !defined __APPLE__)
__m128d t = _mm_set_sd( value );
return _mm_cvtsd_si32(t);
#elif defined _MSC_VER && defined _M_IX86
int t;
__asm
{
fld value;
fistp t;
}
return t;
#elif defined HAVE_LRINT || defined CV_ICC || defined __GNUC__
# ifdef HAVE_TEGRA_OPTIMIZATION
TEGRA_ROUND(value);
# else
return (int)lrint(value);
# endif
#else
// while this is not IEEE754-compliant rounding, it's usually a good enough approximation
return (int)(value + (value >= 0 ? 0.5 : -0.5));
#endif
}