Question

I am working on a project that I need to detect features on images using opencv.

I am using

SURF detector;
SURF extractor;
BFMatcher matcher;

for detection, extraction and matching points. It works well for some images, but fails on some other images.

For example, the system fails on this image:

enter image description here

Apparently, this image has some texture and the feature detector should detect them, but no feature is detected and consequently no match is generated.

How can I improve this feature detection?

Can I use any image processing technique for this?

Is there any other detector that I can use which help in this problem?

Was it helpful?

Solution

I haven't used SURF, but used ORB algorithm. And to improve feature detection I've experimented several filters. The best results I've obtained was with combination of filters Equalize Histogram and Fast Fourier Transform.

Equalize Histogram filter: It enhances meaningless detail and hides important but small high-contrast pixels, which are assumed as noise. Histogram equalization employs a monotonic, non-linear mapping which re-assigns the intensity values of pixels in the input image such that the output image contains a uniform distribution of intensities (i.e. a flat histogram)

Fast Fourier Transform filter: It decomposes the image into its sine and cosine components. The output of the transformation performed by this filter represents the image in the frequency domain, while the input image is the spatial domain equivalent. In the Fourier domain image, each point represents a particular frequency contained in the spatial domain image.

I'm not sure, but I think that in OpenCV there is no FFT filter, so probably you will need to use another library.

Edit1: I have a code, but unfortunately it is in Java and not in C++. But if you will apply the same filters, the result will be the same. Here is the documentation of Eqaulize Histogram. And to apply FFT filter I've used ImageJ, which is Java library. You can try to find something similar to this library, like this one.

Edit2: ImageJ code to apply FFT filter

import ij.plugin.filter.FFTFilter;
...
FFTFilter fft = new FFTFilter();
ImageProcessor ip = new ColorProcessor(bufImage);
ImagePlus imgPlus = new ImagePlus();

imgPlus.setImage(bufImage);

try{
   fft.setup(null, imgPlus); 
}catch(Exception e){e.printStackTrace();}
fft.run(ip);

Edit3: Here are examples of detected features before and after applying mentioned filters.

  1. SURF without any filter: enter image description here
  2. SURF with EH + FFT: enter image description here
  3. ORB with EH + FFT: enter image description here

As you can see with SURF algorithm, there are too many redundant information to perform matching. So I suggest you to use ORB algorithm. Also the advantages of ORB is that it is free to use, efficient and stable to image rotation and scale. You can also smooth the image before applying EH+FFT to detect features only on corners.

Edit4: I've also found useful information about FFT. According to this topic FFT is an efficient implementation of DFT. Which is described here. It is also could be the answer four your recent question.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top