SIFT floating point exception (Bugfix #2580)
Description
Currently, SIFT triggers a floating point exception (_EM_INVALID) in sift.cpp:376 adjustLocalExtrema
(2.4.2 & master) if the Hesse matrix has a very small determinant. Our Hesse matrix is:
dxx = 0.000000000 dxy = 6.12745134e-005 dyy = 0.00220588245 dxs = 2.04248372e-005 dys = 0.00208333344 dss = 0.00114379090
The issue seems to be related with casting the cvRound
value which is xr = -77489432.0 (if the value is not casted no exception is thrown). In our case cvRound
uses this define: #elif defined _MSC_VER && defined _M_IX86 (hence we use visual studio and compile x86 code)
Since these values get rejected anyway in line 379, one could fix that issue by writing this statement:
if( xi+layer < 1 || xi+layer > nOctaveLayers || c+xc < SIFT_IMG_BORDER || c+xc >= img.cols - SIFT_IMG_BORDER || r+xr < SIFT_IMG_BORDER || r+xr >= img.rows - SIFT_IMG_BORDER ) return false;
in line 374 -> checking for a valid border & layer condition before rounding & casting the values
cheers stefan
Associated revisions
fixed #2580, #2210. some work on #2025.
modified SIFT to 1) double image before finding keypoints, 2) use floating-point internally instead of 16-bit integers, 3) set the keypoint response to the abs(interpolated_DoG_value). step 1) increases the number of detected keypoints significantly and together with 2) and 3) it improves some detection benchmarks. On the other hand, the stability of the small keypoints is lower, so the rotation and scale invariance tests now struggle a bit. In 2.5 need to make this feature optional and add some more intelligence to the algorithm.
added test that finds a planar object using SIFT.
Merge pull request #2580 from SpecLad:merge-2.4
History
Updated by Kirill Kornyakov over 12 years ago
Changed tracker type to Patch, since author suggests a fix. Also set the 2.4.4 version, it is possible that the fix will be usable not only in master.
@Stefan, thank you for the report, and if you want to speed up the fixing process, I would suggest you to make a pull request.
- Description changed from currently, sift triggers a floating point exception (_EM_INVALID) in sift.cpp... to Currently, SIFT triggers a floating point exception (_EM_INVALID) in sift.cpp... More
- Category set to nonfree
- Target version set to 2.4.4
- Assignee set to Vadim Pisarevsky
- Tracker changed from Bug to Patch
Updated by Kirill Kornyakov over 12 years ago
- Tracker changed from Patch to Bugfix
Updated by Vadim Pisarevsky about 12 years ago
- Target version deleted (
2.4.4)
Updated by Vadim Pisarevsky about 12 years ago
- Assignee deleted (
Vadim Pisarevsky)
Updated by Vadim Pisarevsky about 12 years ago
- Assignee set to Vadim Pisarevsky
Updated by Andrey Kamaev about 12 years ago
The fix is pushed to 2.4
- Affected version set to branch '2.4'
- Status changed from Open to Done
Updated by Sergey Popov about 12 years ago
Hello, the fix could be a bit refined to also reject the local extrema when xi, xr or xc is NaN by replacing lines 391-393 in sift.cpp with
if( !(std::abs(xi) < (float)(INT_MAX/3) &&
std::abs(xr) < (float)(INT_MAX/3) &&
std::abs(xc) < (float)(INT_MAX/3)) )
Updated by Kirill Kornyakov about 12 years ago
- Target version set to 2.4.4