图像算法之三:特征提取算子之SIFT

SIFT(Scale-invariant feature transform)是一种检测局部特征的算法,该算法通过求一幅图中的特征点(interest points,or corner points)及其有关scale 和 orientation 的描述子得到特征并进行图像特征点匹配,获得了良好效果,详细解析如下:

1、算法描述
SIFT特征不只具有尺度不变性,即使改变旋转角度,图像亮度或拍摄视角,仍然能够得到好的检测效果。整个算法分为以下几个部分:
(1)构造尺度空间:DoG尺度空间
(2)检测DoG尺度空间极值点
(3)去除不好的特征点
(4)给特征点赋值一个128维的方向参数。每个关键点都包含三个信息:位置、尺度和方向。
(5)关键点描述子的生成:
首先将坐标轴旋转为关键点的方向,以确保旋转不变性。以关键点为中心取8×8的窗口。
(6)最后进行特征匹配。当两幅图像的SIFT特征向量(128维)生成后,采用关键点特征向量的欧式聚类来作为相似性判定度量。
取图像1中的某个关键点,并找出其与图像2中欧式距离最近的前两个关键点,在这两个关键点中,如果最近的距离除以次近的距离少于某个比例阈值,则接受这一对匹配点。降低这个比例阈值,SIFT匹配点数目会减少,但更加稳定。

2、算法实现:
(一) SIFT的Matlab代码实现:

% [image, descriptors, locs] = sift(imageFile)
%
% This function reads an image and returns its SIFT keypoints.
%   Input parameters:
%     imageFile: the file name for the image.
%
%   Returned:
%     image: the image array in double format
%     descriptors: a K-by-128 matrix, where each row gives an invariant
%         descriptor for one of the K keypoints.  The descriptor is a vector
%         of 128 values normalized to unit length.
%     locs: K-by-4 matrix, in which each row has the 4 values for a
%         keypoint location (row, column, scale, orientation).  The
%         orientation is in the range [-PI, PI] radians.
%
% Credits: Thanks for initial version of this program to D. Alvaro and
%          J.J. Guerrero, Universidad de Zaragoza (modified by D. Lowe)

function [image, descriptors, locs] = sift(imageFile)

% Load image
image = imread(imageFile);

% If you have the Image Processing Toolbox, you can uncomment the following
%   lines to allow input of color images, which will be converted to grayscale.
% if isrgb(image)
%    image = rgb2gray(image);
% end

[rows, cols] = size(image);

% Convert into PGM imagefile, readable by "keypoints" executable
f = fopen('tmp.pgm', 'w');
if f == -1
    error('Could not create file tmp.pgm.');
end
fprintf(f, 'P5\n%d\n%d\n255\n', cols, rows);
fwrite(f, image', 'uint8');
fclose(f);

% Call keypoints executable
if isunix
    command = '!./sift ';
else
    command = '!siftWin32 ';
end
command = [command ' tmp.key'];
eval(command);

% Open tmp.key and check its header
g = fopen('tmp.key', 'r');
if g == -1
    error('Could not open file tmp.key.');
end
[header, count] = fscanf(g, '%d %d', [1 2]);
if count ~= 2
    error('Invalid keypoint file beginning.');
end
num = header(1);
len = header(2);
if len ~= 128
    error('Keypoint descriptor length invalid (should be 128).');
end

% Creates the two output matrices (use known size for efficiency)
locs = double(zeros(num, 4));
descriptors = double(zeros(num, 128));

% Parse tmp.key
for i = 1:num
    [vector, count] = fscanf(g, '%f %f %f %f', [1 4]); %row col scale ori
    if count ~= 4
        error('Invalid keypoint file format');
    end
    locs(i, :) = vector(1, :);

    [descrip, count] = fscanf(g, '%d', [1 len]);
    if (count ~= 128)
        error('Invalid keypoint file value.');
    end
    % Normalize each input vector to unit length
    descrip = descrip / sqrt(sum(descrip.^2));
    descriptors(i, :) = descrip(1, :);
end
fclose(g);

使用方法:
1.寻找图像中的sift特征:

[image,descrips,locs] = sift('scene.pgm');
showkeys(image,locs);

图像算法之三:特征提取算子之SIFT_第1张图片
scene.pgm
图像算法之三:特征提取算子之SIFT_第2张图片
book.pgm

2、对两幅图中的sift特征进行匹配
图像算法之三:特征提取算子之SIFT_第3张图片

match(‘scene.pgm’,’book.pgm’);
由于scene和book两幅图中有相同的一本书,但是方向和尺度都不同,从匹配结果可以看出去sift特征匹配检测效果非常好滴!

关于SIFT的其他讲解:
http://blog.csdn.net/abcjennifer/article/details/7639681

http://blog.csdn.net/abcjennifer/article/details/7372880

http://blog.csdn.net/abcjennifer/article/details/7365882

(二)SIFT的Python实现:

import cv2
import numpy as np
import pdb
pdb.set_trace()#turn on the pdb prompt

#read image
img = cv2.imread('E:\OpenCV\Picture\sky.jpg',cv2.IMREAD_COLOR)
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
cv2.imshow('origin',img);

#SIFT
detector = cv2.SIFT() #调用SIFT特征描述子
keypoints = detector.detect(gray,None)#检测兴趣点
img = cv2.drawKeypoints(gray,keypoints)#画出兴趣点
#img = cv2.drawKeypoints(gray,keypoints,flags = cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
cv2.imshow('test',img);
cv2.waitKey(0)
cv2.destroyAllWindows()

测试:

实验结果:

(三)SIFT的OpenCV实现

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
using namespace cv;
int main(void)
{
       cout << "当前使用的OpenCV版本:" << CV_VERSION << endl;
       Mat image = imread("scene.pgm");
       Mat image2 = imread("book.pgm");
       if (image.empty())
       {
              fprintf(stderr, "Cannot load image %s \n", "scene.pgm");
              return -1;
       }
       if (image2.empty())
       {
              fprintf(stderr, "Cannot load image %s \n", "book.pgm");
              return -1;
       }
       //显示图像
       imshow("image before", image);
       waitKey(10);
       imshow("image2 before", image2);
       waitKey(10);
       //sift特征点检测
       SiftFeatureDetector siftdtc;
       vector kp1, kp2;
       siftdtc.detect(image, kp1);
       Mat outimg1;
       drawKeypoints(image, kp1, outimg1);
       imshow("image1 keypoints", outimg1);
       siftdtc.detect(image2, kp2);
       Mat outimg2;
       drawKeypoints(image2, kp2, outimg2);
       imshow("image2 keypoints", outimg2);
       //生成描述子
       SiftDescriptorExtractor ext;
       Mat descp1, descp2;
       BruteForceMatcherfloat>> matcher;
       vector matches;
       Mat img_matches;
       ext.compute(image, kp1, descp1);
       ext.compute(image2, kp2, descp2);
       imshow("desc", descp1);
       waitKey(10);
       //cout << endl << descp1 << endl;
       matcher.match(descp1, descp2, matches);

       drawMatches(image, kp1, image2, kp2, matches, img_matches);
       imshow("matches", img_matches);
       waitKey(10);
       //namedWindow("My Image");
       //imshow("My Image",image);
       //waitKey(0);
       //Mat result,image2,image3;
       //result = image;
       //image2 = result;
       //result.copyTo(image3);
       //flip(image, result, 1);//正数水平翻转,0表示垂直翻转,负数表示既有水平也有垂直翻转
       //namedWindow("Output window");
       //imshow("Output window", result);
       //namedWindow("1");
       //imshow("1", image2);
       //namedWindow("2");
       //imshow("2", image3);
       waitKey(0);
       return 0;
}

图像算法之三:特征提取算子之SIFT_第4张图片

图像算法之三:特征提取算子之SIFT_第5张图片

图像算法之三:特征提取算子之SIFT_第6张图片

你可能感兴趣的:(【计算机视觉与图像处理】,【计算机视觉与模式识别】)