代码已经开源到github上,https://github.com/alibaba/simpleimage项目,其中的 analyze模块中。
原始图片为:
主要调用方法:
BufferedImage img = ImageIO.read(logoFile);
RenderImage ri = new RenderImage(img);
SIFT sift = new SIFT();
sift.detectFeatures(ri.toPixelFloatArray(null));
List<KDFeaturePoint> al = sift.getGlobalKDFeaturePoints();
同样可以再读另一个张图得到另一个 List<KDFeaturePoint> al1,然后两个List进行match
List<Match> ms = MatchKeys.findMatchesBBF(al, al1);
ms = MatchKeys.filterMore(ms);
先从上面的调用入口,详细讲解图sift的特征点生,至于match,有空再说。其中最难理解的是极值点的查找,主要对这部分讲解。
一.构建尺度空间,检测极值点,获得尺度不变性
ImagePixelArray就是保存一张图片的象素点进行灰度化后的数组。在RenderImage的toPixelFloatArray方法中默认灰度处理只是简单将rgb的值换成r,g,b的平均值并做归一化处理(除以255);
从调用入口我们进入主类SIFT的用户接口detectFeatures方法,它实际调用了detectFeaturesDownscaled(ImageMap img, int bothDimHi, double startScale) ,我们看随了开始的几行init工作,最后对图片使用preprocSigma(1.5)的参数进行高斯模数预处理。
if (preprocSigma > 0.0) {
GaussianArray gaussianPre = new GaussianArray(preprocSigma);
img = gaussianPre.convolve(img);
}
进行高斯模糊的目的是为了使大片的灰度相近的点连成一片,而使一些比较突出的点更加区别于其它点,就象我们把一张灰度图片使用“版画”效果会把大量的连片点去掉只留下轮廓。
经过上面的预处理效果为: