Python图像特征检测算法(1):Python实现SIFT和Harris
Python图像特征检测算法(1):Python实现SIFT和Harris
本文将介绍用于图像匹配的两种局部描述子算法,SIFT[论文链接]和Harris,它们在很多应用中都有比较重要的作用,比如目标匹配、目标跟踪、创建全景图、增强现实技术以及计算图像的三维重建等,而常用的特征有颜色、角点、特征点、轮廓、纹理等,很多内容中都会用到这些特征。Harris角点检测算法(也称Harris&Stephens角点检测器)是特征点检测的基础,是一个极为简单的角点检测算法。Harris提出了应用邻近像素点灰度差值的概念,从而进行判断是否为角点(兴趣点)、边缘、平滑区域。Harris角点检测原理是利用移动的窗口在图像中计算灰度变化值,其中关键流程包括转化为灰度图像、计算差分图像、高斯平滑、计算局部极值、确认角点(关键点)。SIFT[主页],即尺度不变特征变换(Scale-invariantfeature transform,SIFT),是用于图像处理领域的一种描述。这种描述具有尺度不变性,可在图像中检测出关键点,是一种局部特征描述子。该方法于1999年由David Lowe[主页]首先发表于计算机视觉国际会议(InternationalConference on Computer Vision,ICCV),2004年再次经David Lowe整理完善后发表于International journal of computer vision(IJCV)。截止2014年8月,该论文单篇被引次数达25000余次。
一、前期准备
1.安装配置Python及其相关软件包(推荐使用Anaconda,其自带完整的库,无需费时费力安装)
2.安装配置VLFeat开源工具包(windows10/64位系统为例)
我们使开源工具包VLFeat提供的二进制文件来计算图像的SIFT特征,VLFeat工具包可以从http://www.vlfeat.org/下载,二进制文件可以在所有的主要平台上运行。VLFeat的主页如下图所示,可以看出VLFeat工具包中含有大量的完整的代码实现。VLFeat库是用C语言来写的,但是我们可以使用该库提供的命令行接口。
在此界面上下载文件vlfeat-0.9.20-bin,解压缩后,将vlfeat-0.9.20/bin/win32(win64下的测试不兼容)文件夹下的sift.exe和vl.dll拷贝到当前工程目录下。这样,前期工作就已完成。
二、编写代码
Python实现SIFT和Harris的具体代码如下:
# -*- coding: utf-8 -*-
# Yan Zhenguo
from PIL import Image
from pylab import *
from numpy import *
import os
from scipy.ndimage import filters
def process_image(imagename, resultname, params="--edge-thresh 10 --peak-thresh 5"):
""" Process an image and save the results in a file. """
if imagename[-3:] != 'pgm':
# create a pgm file
im = Image.open(imagename).convert('L')
im.save('tmp.pgm')
imagename = 'tmp.pgm'
cmmd = str("sift " + imagename + " --output=" + resultname + " " + params)
os.system(cmmd)
print('processed', imagename, 'to', resultname)
def read_features_from_file(filename):
""" Read feature properties and return in matrix form. """
f = loadtxt(filename)
return f[:, :4], f[:, 4:] # feature locations, descriptors
def write_features_to_file(filename, locs, desc):
""" Save feature location and descriptor to file. """
savetxt(filename, hstack((locs, desc)))
def plot_features(im, locs, circle=False):
""" Show image with features. input: im (image as array),
locs (row, col, scale, orientation of each feature). """
def draw_circle(c, r):
t = arange(0, 1.01, .01) * 2 * pi
x = r * cos(t) + c[0]
y = r * sin(t) + c[1]
plot(x, y, 'b', linewidth=2)
imshow(im)
if circle:
for p in locs:
draw_circle(p[:2], p[2])
else:
plot(locs[:, 0], locs[:, 1], 'ob')
axis('off')
def compute_harris_response(im, sigma=3):
""" Compute the Harris corner detector response function
for each pixel in a graylevel image. """
# derivatives
imx = zeros(im.shape)
filters.gaussian_filter(im, (sigma, sigma), (0, 1), imx)
imy = zeros(im.shape)
filters.gaussian_filter(im, (sigma, sigma), (1, 0), imy)
# compute components of the Harris matrix
Wxx = filters.gaussian_filter(imx * imx, sigma)
Wxy = filters.gaussian_filter(imx * imy, sigma)
Wyy = filters.gaussian_filter(imy * imy, sigma)
# determinant and trace
Wdet = Wxx * Wyy - Wxy ** 2
Wtr = Wxx + Wyy
return Wdet / Wtr
def get_harris_points(harrisim, min_dist=10, threshold=0.1):
""" Return corners from a Harris response image
min_dist is the minimum number of pixels separating
corners and image boundary. """
# find top corner candidates above a threshold
corner_threshold = harrisim.max() * threshold
harrisim_t = (harrisim > corner_threshold) * 1
# get coordinates of candidates
coords = array(harrisim_t.nonzero()).T
# ...and their values
candidate_values = [harrisim[c[0], c[1]] for c in coords]
# sort candidates (reverse to get descending order)
index = argsort(candidate_values)[::-1]
# store allowed point locations in array
allowed_locations = zeros(harrisim.shape)
allowed_locations[min_dist:-min_dist, min_dist:-min_dist] = 1
# select the best points taking min_distance into account
filtered_coords = []
for i in index:
if allowed_locations[coords[i, 0], coords[i, 1]] == 1:
filtered_coords.append(coords[i])
allowed_locations[(coords[i, 0] - min_dist):(coords[i, 0] + min_dist),
(coords[i, 1] - min_dist):(coords[i, 1] + min_dist)] = 0
return filtered_coords
def plot_harris_points(image, filtered_coords):
""" Plots corners found in image. """
figure()
gray()
imshow(image)
plot([p[1] for p in filtered_coords],[p[0] for p in filtered_coords], '*')
axis('off')
title('Harris-Features')
show()
imname = 'building.jpg'
im = array(Image.open(imname).convert('L'))
process_image(imname, 'building.sift')
l1, d1 = read_features_from_file('building.sift')
figure()
gray()
"""Figure1:SIFT特征"""
plot_features(im, l1, circle=False)
title('SIFT-Features')
"""Figure2:使用圆圈表示特征尺度的SIFT特征"""
figure()
gray()
plot_features(im, l1, circle=True)
title('Detect-SIFT-Features')
"""Figure3:Harris角点检测的结果"""
harrisim = compute_harris_response(im)
filtered_coords = get_harris_points(harrisim, 6, 0.05)
plot_harris_points(im, filtered_coords)
三、运行结果
1、SIFT特征
2、使用圆圈表示特征尺度的SIFT特征
3、Harris角点
在后续工作中,我将继续为大家展现图像特征检测相关得到工作和深度学习网络带来的无尽乐趣,我将和大家一起探讨图像世界和深度学习的奥秘。当然,如果你感兴趣,我的Weibo将与你一起分享最前沿的人工智能、机器学习、深度学习与计算机视觉方面的技术。
四、参考文献
1.Python计算机视觉编程
2.百度百科SIFT:https://baike.baidu.com/item/SIFT/1396275?fr=aladdin