It's been two years already that I see the same subject that hangs on several times concerning SIFT and SURF which cause problems for some. there is always a post about these two.
First of all, you need to understand something:
OpenCV is an open source library, which implements algorithms designed by researchers, some of these algorithms are free to use whether for personal or commercial use, others are free for personal use.
Beginning with a small explanation depending on the versions of OpenCV: opencv2 -> opencv3 -> opencv4 -> new_versions of opencv
- We’re not going to talk about opencv 2 (I guess hardly anyone uses it right now). The only thing you have to remember from this version is that SIFT and SURF worked fine.
- Since the release of OpenCV3, the SIFT and SURF implementations have been removed from the default installation of OpenCV 3, same for OpenCV 4.
The reason for removing SIFT and SURF is because of what OpenCV calls “non-free” algorithms. SIFT and SURF are (summer) both proprietary and patented algorithms, which means that you must technically obtain permission to use them in commercial algorithms (they are, however, free for academic and research purposes).
For this reason, OpenCV made the decision to move patented algorithms (with experimental implementations) to the package named "opencv_contrib". This means to access SIFT and SURF.
Case of OpenCV in C++:
you have to compile and install OpenCV from source with opencv-contrib support enabled. (We will see this later)
Case of OpenCV in python:
you need to install via pip the opencv-contrib-python package as follows:
pip install opencv-contrib-python
however, in some of the versions of OpenCV 3, (the one you are having trouble with in python), both SIFT and SURF algorithms do not want to work, and you get this error: "module 'cv2.cv2' has no attribute 'xfeatures2d' ”
.
I can give you an explanation (which is my own opinion), but before that you should know that the OpenCV python package is built by compiling the OpenCV source.
Pythons packages are Wheel type files so the extension is ".whl".
So when you do ** pip install opencv-python **, you will actually consult this https://pypi.org/project/opencv-python/#files which will choose the wheel file corresponding to your configuration (operating system as well as the version of python), same for opencv-contrib-python whose link is the following https://pypi.org/project/opencv-contrib-python/#files.
So why don't SIFT and SURF work in all versions of OpenCV?
Hypothesis 1: Forget about activating extra modules, and non-free algorithms from the developers when compiling the source and building the opencv-contrib-python package. But since this problem is not present in just one release, but in ten, this generates a second hypothesis.
Hypothesis 2: it was done on purpose, but why?
Note: this is just my opinion, if anyone has the exact reason, please share it with us.
Version history and operation: from SIFT and SURF.
1- For SIFT (Tested):
sift = cv2.sift_create() # work in:
# 3.4.11, 4.4.0, 4.5.x, 4.6.0 ==> Sift became free since March 2020
sift = cv2.xfeatures2D.SIFT_create () # work in:
# 3.2.x, 3.3.x, 3.4.0, 3.4.1, 3.4.2, 3.4.10, 4.3.0
sift = cv2.xfeatures2D.SIFT_create () # ==> Set OPENCV_ENABLE_NONFREE CMake option and rebuild the library in function 'create' (the versions where the problem is present)
# 3.4.3, 3.4.4, 3.4.5, 3.4.6, 3.4.7, 3.4.8, 3.4.9, 4.0.x, 4.1.x, 4.2.x
2- For SURF (Supposed (Not test all)):
SURF = cv2.xfeatures2D.SURF_create () # work in :
# 3.2.x, 3.3.x, 3.4.0, 3.4.1, 3.4.2
SURF = cv2.xfeatures2D.SURF_create () # ==> Set OPENCV_ENABLE_NONFREE CMake option and rebuild the library in function 'create' (the versions where the problem is present)
# 3.4.3, 3.4.4, 3.4.5, 3.4.6, 3.4.7, 3.4.8, 3.4.9, 3.4.10, 3.4.11, 4.0.x, 4.1.x, 4.2.x, 4.3.0, 4.4.0, 4.5.x, 4.6.0
SOLUTION:
1- The easiest solution as mentioned in a lot of forums (if you are looking for a little bit instead of posting the same problem each time) is to downgrade the openCV version to version 3.4.2.17 (if you need SIFT and SURF work just with pip install), because the problems start from version 3.4.3.
2- If you need a particular version knowing that it is a problem with SIFT or SURF, you can correct it, by installing OpenCV with enable opencv-contrib and NONFREE algorithms from source. here is a tutorial to follow:Tutorial
For compilation OpenCV With enable opencv-contrib and NONFREE algorithms you need this:
cmake -D CMAKE_BUILD_TYPE = RELEASE \
-D CMAKE_INSTALL_PREFIX = /usr/local \
-D INSTALL_PYTHON_EXAMPLES = ON \
-D INSTALL_C_EXAMPLES = OFF \
-D OPENCV_ENABLE_NONFREE = ON \
-D OPENCV_EXTRA_MODULES_PATH=(Path_to_opencv-contrib)/opencv_contrib/modules \
-D PYTHON_EXECUTABLE=~/.virtualenvs/(Python_environement)/bin/python \
-D BUILD_EXAMPLES=ON ..
Tested with opencv 3.4.9 under python 3.6.9 (Works fine for SIFT and SURF)
All existing releases of opencv 3 and 4 are here Releases
All versions of openCV3 >= 3.4.11 include the free version of SIFT
All versions of openCV4 >= 4.4.0 include the free version of SIFT