我正在开发一个项目,我需要使用opencv检测图像上的功能。
我正在使用
SURF detector;
SURF extractor;
BFMatcher matcher;
用于检测,提取和匹配点。它适用于某些图像,但在其他图像上失败。
例如,系统在此图像上失败:
显然,此图像具有一些纹理,并且特征检测器应检测它们,但未检测到任何特征,因此不会生成匹配。
如何改进此功能检测?
我可以使用任何图像处理技术吗?
我可以使用哪种其他探测器来帮助解决这个问题吗?
答案 0 :(得分:6)
我没有使用过SURF,但是使用了ORB算法。为了改进功能检测,我尝试了几种过滤器。我获得的最好结果是使用滤波器Equalize Histogram和Fast Fourier Transform的组合。
均衡直方图滤镜:它增强了无意义的细节,并隐藏了重要但很小的高对比度像素,这些像素被假设为噪声。直方图均衡采用单调非线性映射,重新分配输入图像中像素的强度值,使输出图像包含均匀的强度分布(即平直方图)
快速傅立叶变换滤镜:它将图像分解为正弦和余弦分量。由此滤波器执行的变换的输出表示频域中的图像,而输入图像是等效的空间域。在傅里叶域图像中,每个点表示空间域图像中包含的特定频率。
我不确定,但我认为在OpenCV中没有FFT过滤器,所以你可能需要使用另一个库。
EDIT1 : 我有一个代码,但遗憾的是它是用Java而不是用C ++编写的。但是,如果您将应用相同的过滤器,结果将是相同的。 Here是Eqaulize Histogram的文档。为了应用FFT滤波器,我使用了ImageJ,它是Java库。您可以尝试查找类似于此库的内容,例如this一个。
Edit2 :应用FFT过滤器的ImageJ代码
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 :以下是应用上述过滤器之前和之后检测到的功能的示例。
正如您在SURF算法中所看到的,执行匹配的冗余信息太多。所以我建议你使用ORB算法。 ORB的优点还在于它可以自由使用,高效且稳定的图像旋转和缩放。您还可以在应用EH + FFT之前平滑图像,以便仅检测角落上的特征。
Edit4 :我还找到了有关FFT的有用信息。根据{{3}},FFT是DFT的有效实现。其中描述了this topic。这也可能是最近四个here问题的答案。