python图像特征检测方法——SIFT,实现过程无法找到sift文件,请大神帮助

BunryIce 2018-08-17 03:27:05
以下是我的sift.py代码

from PIL import Image
from numpy import *
from numpy.core.multiarray import ndarray
from pylab import *
from scipy.ndimage import filters
import os

def process_image(imagename, resultname, params = "--edge-thresh 10 "
"--peak-thresh 5"):
"""处理一幅图像,然后将结果保存在文件中"""

if imagename[-3:] != 'pgm':
#创建一个pgm文件
im = Image.open(imagename).convert('L')
im.save('tmp.pgm')
imagename = 'tmp.pgm'

cmmd = str("C:/Users/qiy8/PycharmProjects/learning_computer_version"
"/VLFeat/win32/sift.exe " + imagename +
"--output=" + resultname
+ " " + params)
os.system(cmmd)
print('processed', imagename, 'to', resultname)

def read_features_from_file(filename):
"""读取特征属性值,然后将其以矩阵的形式返回"""

f = loadtxt(filename)
return f[:, :4], f[:, 4:] #特征位置,描述子

def write_features_to_file(filename, locs, desc):
"""将特征位置和描述子保存在文件中"""
savetxt(filename, hstack((locs, desc)))

def plot_features(im, locs, circle = False):
"""显示带有特征的图像
输入:im(数组图像),locs(每个特征的行、列、尺度和朝向"""

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 match(desc1, desc2):
"""对于第一幅图像中的每个描述子,选取其在第二幅图像中的匹配
输入:desc1(第一幅图像中的描述子),desc2(第二幅图像中的描述子)"""

desc1 = array([d / linalg.norm(d) for d in desc1])
desc2 = array([d / linalg.norm(d) for d in desc2])
dist_ratio = 0.6
desc1_size = desc1.shape

matchscores = zeros((desc1_size[0], 1), 'int')
desc2t = desc2.T #预先计算矩阵转置
for i in range(desc1_size[0]):
dotprods = dot(desc1[i, :], desc2t) #向量点乘
dotprods = 0.9999 * dotprods
#反余弦和反排序,返回第二幅图像中特征的索引
indx = argsort(arccos(dotprods))

#检查最相邻的角度是否小于dist_radio乘以第二近邻的角度
if arccos(dotprods)[indx[0]] < dist_ratio * arccos(dotprods)[indx[1]]:
matchscores[i] = int(indx[0])

return matchscores

def match_twosided(desc1, desc2):
"""双向对称版本的match"""

matches_12 = match(desc1, desc2)
matches_21 = match(desc2, desc1)

ndx_12 = matches_12.nonzero()[0]

#去除不对称的匹配
for n in ndx_12:
if matches_12[int(matches_12[n])] != n:
matches_12[n] = 0

return matches_12

def appendimages(im1, im2):
"""返回将两幅图像并列拼接成一幅的新图像"""

#选取具有最少行数的图像,然后填充足够的空行
rows1 = im1.shape[0]
rows2 = im2.shape[0]

if rows1 < rows2:
im1 = concatenate((im1,zeros((rows2 - rows1, im1.shape[1]))), axis=0)
else:
im2 = concatenate((im2, zeros((rows1 - rows2, im2.shape[1]))), axis=0)
#如果这些情况都没有,那么他们的行数相同,不需要进行填充

return concatenate((im1, im2), axis=1)

def plot_matches(im1, im2, locs1, locs2, matchscores, show_below = True):
"""显示一幅带有连接匹配之间连线的图片
输入:im1,im2(数组图像),locs1,locs2(特征位置),matchscores(match()的输出),
show_below(如果图像应该先是在匹配的下方)"""

im3 = appendimages(im1, im2)
if show_below:
im3 = vstack((im3, im3))

imshow(im3)

cols1 = im1.shape[1]
for i, m in enumerate(matchscores):
if m > 0:
plot([locs1[i][1], locs2[m][1] + cols1], [locs1[i][0], locs2[m][
0]], 'c')
axis('off')


以下是我用来做验证实践的代码

from PIL import Image
from numpy import *
from numpy.core.multiarray import ndarray
from pylab import *
from scipy.ndimage import filters
import sift
imname = 'empire.jpg'
im1 = array(Image.open(imname).convert('L'))
sift.process_image(imname, 'empire.sift')
l1, d1 = sift.read_features_from_file('empire.sift')

figure()
gray()
sift.plot_featrues(im1, l1, circle=True)
show()

这是我的代码报错截图
已经尝试过https://blog.csdn.net/lilai619/article/details/48523647该帖中最后提到的解决方法 但是实在是没用,从错误上看,貌似还是cmmd那一行没有正常工作,我的电脑是win764位系统,而且在公司做实习生这个电脑的权限有很大的约束,不知道对我这个程序的实现有没有什么影响,希望各位大佬帮忙解决一下
...全文
856 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
wbaini748 2020-03-30
  • 打赏
  • 举报
回复
1、先卸载原先的opencv pip uninstall opencv-python 2、接着安装3.4.2版本的opencv和contrib包 pip install opencv_python==3.4.2.16 pip install opencv-contrib-python==3.4.2.16 新版本中已经不能再使用SIFT了 , 或者你再降低点opencv-contrib-python 版本
自圆其说 2019-03-25
  • 打赏
  • 举报
回复
请问sift怎么生成,我一直报错:
Traceback (most recent call last):
File "/home/aaron/python/procedure/ch02/p43-sift.py", line 17, in <module>
l1, d1 = sift.read_features_from_file('im0.sift')
File "/usr/local/lib/python3.5/dist-packages/PCV/localdescriptors/sift.py", line 25, in read_features_from_file
f = loadtxt(filename)
File "/usr/lib/python3/dist-packages/numpy/lib/npyio.py", line 927, in loadtxt
% line_num)
ValueError: Wrong number of columns at line 2
limmmy 2019-03-17
  • 打赏
  • 举报
回复
我也是这个问题,找不到sift.exe所以没法生成empire.sift,后来我把那个win64vlfeat里面的sift.exe存放在和sift.py同一个目录下, cmmd = str("sift.exe " + imagename +
"--output=" + resultname
+ " " + params)
BunryIce 2018-08-20
  • 打赏
  • 举报
回复
请各位大佬帮帮我啊 实在不知道怎么回事啊

37,719

社区成员

发帖
与我相关
我的任务
社区描述
JavaScript,VBScript,AngleScript,ActionScript,Shell,Perl,Ruby,Lua,Tcl,Scala,MaxScript 等脚本语言交流。
社区管理员
  • 脚本语言(Perl/Python)社区
  • IT.BOB
加入社区
  • 近7日
  • 近30日
  • 至今

试试用AI创作助手写篇文章吧