大家好,我是第一次写CSDN博客,也是刚开始学习用Python进行计算机视觉编程,有很多不懂和不足的地方,希望大家多包涵。以下纯粹是我个人的一些实际操作经历。
在《Python计算机视觉编程》一书中,有关于增强现实AR的一部分编程程序。尤其是一段在相片上显示一个虚拟茶壶的程序,在网上(包括CSDN)有很多程序。这里我个人觉得这2篇文章算不错的,给出链接。第一个是https://blog.csdn.net/Dujing2019/article/details/91691202,第二个是https://blog.csdn.net/titansm/article/details/89057184。但直接使用这些程序,不一定能得到它们说的同样的效果和结果(至少我不是),所以我贴出自己的代码,以供大家参考。
1、一些基本的我就不说了,例如软件和包的安装等,大家参考以上两个链接和其他文章,这里我说点和其它文章不一样的地方。对了,我的环境是Win7 64位,装了anaconda3和python3.6。
2、首先是以上两个链接中都会提到的sift.process_image等等函数,你会发现文章中根本没细说这写函数的内容是什么。其实这些函数在《Python计算机视觉编程》一书中有详细提及,只是以上链接文章没提罢了,这里我把所有相关的程序待会在下面都列出来。
3、sift.process_image函数是将.bmp文件转变成.sift文件。那么如何转变呢?这里你需要下载一个vlfeat-0.9.20-bin.tar.gz压缩包(注意必须是0.9.20版本,0.9.21版本没用),解压缩后将其中/bin/win32中的sift.exe、vl.dll、vl.lib拷贝到和你这个AR python程序同一个文件夹下。很奇怪我是64位版本为什么用win32中的文件吧?其实我也奇怪,但我试过了,用win64根本不行,只有win32可以,我也不知道为什么。
4、另外,你在安装完PyOpenGL后,需要将OpenGL库文件(由于我安装了anaconda3,因此我的OpenGL库文件在Continuum\anaconda3\Lib\site-packages\OpenGL)下的DLLS文件夹中的部分东西删除,只保留gle_AUTHORS、gle_COPYING、gle_COPYING.src、gle64.vc14.dll、glut64.vc14.dll这六个文件即可。否则在编译函数draw_teapot时会跳出一个莫名其妙的错误。
5、这一点非常关键,我找遍了好多文章,最后终于在第二个链接中找到了,也就是width和height的值。一定不能用大多数文章里使用的1000和747,要用你自己那个.bmp的像素。比如我的.bmp文件的像素是553和369(可以点击右键–>属性–>详细信息看到该文件的像素)。
另外关于这一点,我做了若干次尝试:当width,height = 553,369时,效果OK;当width,height = 553,300时,效果也OK;当width不是553时,哪怕是554或552,出来的背景效果都是极度扭曲的。
还有,width和height的值不能太大,否则编译时就会报错,什么内存读取溢出或错误OSError: exception: access violation reading 0x0000000008FC7000。网上很多人说这是64位版本问题,算是一个bug,具体我也搞不清楚。所以你在生成.bmp图片时,就要记住图片像素值不能太大。
好,接下来我就贴代码了。
首先生成一个空文件sift.py,将它和其它AR python程序放在同一个文件夹。sift.py里的程序是:
from PIL import Image
from numpy import *
from pylab import *
import os
def process_image(imagename, resultname, params='--edge-thresh 10 --peak-thresh 5'):
if imagename[-3:] != 'pgm':
im = Image.open(imagename).convert('L')
im.save('tmp.pgm')
imagename = 'tmp.pgm'
cmmd = str("sift " + imagename + " --output=" + resultname + " " + params)
os.system(cmmd)
print(str("processed " + imagename + " to " + resultname))
def read_features_from_file(filename):
f = loadtxt(filename)
return (f[:, :4], f[:, 4:])
def match(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))
if arccos(dotprods)[indx[0]] < dist_ratio*arccos(dotprods)[indx[1]]:
matchscores[i] = int(indx[0])
return matchscores
def match_twosided(desc1,desc2):
matches_12 = match(desc1, desc2)
matches_21 = match(desc2, desc1)
ndx_12 = matches_12.nonzero()[0]
for n in ndx_12:
if matches_21[matches_12[n]] != n:
matches_12[n] = 0
return matches_12
然后生成一个空文件homography.py,将它和其它AR python程序放在同一个文件夹。homography.py里的程序是:
import os
from PIL import Image
from numpy import *
from pylab import *
from scipy import ndimage
import ransac
def make_homog(points):
return vstack((points,ones((1,points.shape[1]))))
class RansacModel(object):
def __init__(self,debug=False):
self.debug = debug
def fit(self,data):
data = data