SIFT floating point exception (Bugfix #2580)


Added by Stefan Fiel over 12 years ago. Updated about 12 years ago.


Status:Done Start date:2012-11-28
Priority:Normal Due date:
Assignee:Vadim Pisarevsky % Done:

0%

Category:nonfree
Target version:2.4.4
Affected version:branch '2.4' Operating System:
Difficulty: HW Platform:
Pull request:

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

Revision c69312ea
Added by Vadim Pisarevsky about 12 years ago

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.

Revision 6f055d7a
Added by Roman Donchenko almost 11 years ago

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

Also available in: Atom PDF