关于计算机全景图的试题,计算机视觉实战篇—全景图制作

什么是全景图

全景图功能已经成为手机厂家和相机软件必备的功能,我们根据友好的提示很容易就能拍摄出一张不错的全景照片。

今天我们就来介绍一下如何通过缝合多张不同角度拍摄图片来完成一张全景图。其实这里简单总结一下做这件事的几个步骤

提取特征点

匹配特征点

图片对齐

提取特征点

这些特征点需要我们从左右图像上分别进行检测,我们希望这些特征点具有以下性质

可重复性(Repeatability),也就是我们希望

我们需要什么技术呢, opencv, 需要了解特征点。

1对1特征匹配

a5ee99a8376b

1对1的特征匹配

k对最佳匹配

a5ee99a8376b

k对最佳匹配

随机抽样一致算法 RANSAC

基本思路是我们找到特征点,也就是两张图共同特征点。然后我们通过筛选得到几对特征点来计算出相机模型,最后就可以进拼合。

import cv2

import numpy as np

class Stitcher:

#

def stitch(self,images,ratio=0.75,reprojThresh=4.0,showMatches=False):

(imageA, imageB) = images

print imageA

(kpsA,featuresA) = self.detectAndDescribe(imageA)

(kpsB,featuresB) = self.detectAndDescribe(imageB)

M = self.matchKeypoints(kpsA,kpsB,featuresA,featuresB,ratio,reprojThresh)

if M is None:

return None

(matches, H, status) = M

result = cv2.warpPerspective(imageA,H,(imageA.shape[1] + imageB.shape[1],imageA.shape[0]))

cv2.imshow("res",result)

cv2.waitKey(1)

cv2.destroyAllWindows()

result[0:imageB.shape[0],0:imageB.shape[1]] = imageB

if showMatches:

pass

# vis = self.drawMatches(imageA,imageB,kpsA,kpsB,matches,status)

return result

def detectAndDescribe(self,image):

gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)

sift = cv2.xfeatures2d.SIFT_create()

(kps,features) = sift.detectAndCompute(gray,None)

kps = np.float32([kp.pt for kp in kps])

return (kps,features)

def matchKeypoints(self,kpsA,kpsB,featuresA,featuresB,ratio,reprojThresh):

matcher = cv2.BFMatcher()

rawMatches = matcher.knnMatch(featuresA,featuresB,2)

matches = []

for m in rawMatches:

if len(m) == 2 and m[0].distance < m[1].distance * ratio:

matches.append((m[0].trainIdx,m[0].queryIdx))

if len(matches) > 4:

ptsA = np.float32([kpsA[i] for (_,i) in matches])

ptsB = np.float32([kpsB[i] for (i,_) in matches])

(H,status) = cv2.findHomography(ptsA,ptsB,cv2.RANSAC,reprojThresh)

return (matches, H, status)

这里有三个方法 stitch 负责缝合图片,这里我们提取特征点使用 SIFT 这个。注意在新版的 opencv 这些功能因为一些技术专利的问题,不再免费提供了。我们需要使用较早的版本来使用 SIFT功能。

(kps,features) = sift.detectAndCompute(gray,None)

这里分为两个部分检测和计算。我们也可以使用单独使用检测。

(H,status) = cv2.findHomography(ptsA,ptsB,cv2.RANSAC,reprojThresh)

这里需要一些计算机几何知识,只有理解单应变相机模型的只是

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
import cv2 as cv import numpy as np def cv_show(name,img): cv.imshow(name,img) cv.waitKey(0) cv.destroyAllWindows() def detectAndDescribe(image): gray = cv.cvtColor(image,cv.COLOR_BGR2GRAY) sift = cv.xfeatures2d.SIFT_create() (kps,features)=sift.detectAndCompute(image,None)#这里的kps是一个特征点对象,,属性有.pt关键点坐标 #.angle关键点方向 .response响应强度 .size该点的直径大小 kps = np.float32([kp.pt for kp in kps])#此刻得到kps特征点对象中每一个特征点的坐标。 return (kps,features) def matchKeypoints(kpsA,kpsB,features1,features2,ratio): bf = cv.BFMatcher() rawMatches = bf.knnMatch(features1,features2,2)#rawMatcher是一个Dmatch型对象,属性有.distance描述符间距离 #.trainIdx样本像特征点标识符,.queryIdx测试像的特征点标识符,.imgIdx训练像的索引 matches = [] for m,n in rawMatches: if m.distance 4: pts1 = np.float32([kpsA[i] for (_,i) in matches])#将测试像的坐标储存到Pts1里 pts2 = np.float32([kpsB[i] for (i,_) in matches])#将样本像的坐标储存到pts2里 # 计算视角变换矩阵H #参数一,测试像的特征点坐标,参数二,样本像的特征点坐标,参数三,RANSAC算法: #RANSCA原理, 因为拟合一条直线只需要两个点,因此我们每次随机选取两个点,做出直线,划定一个距离,判断落在直线周围距离范围点的个数, # 不断的迭代,直到找出拟合的直线,使得点落在上面最多的拟合曲线 #参数四:参数范围1~10,原像的点经过变换后点与目标像上对应点的误差,超过了就是outlier (H, status) = cv.findHomography(pts1, pts2, cv.RANSAC, 5) return (matches, H, status) return None imageA = cv.imread("E:/opencv/picture/right1.jpg") imageB = cv.imread("E:/opencv/picture/left1.png") (kpsA,features1)=detectAndDescribe(imageA) (kpsB,features2)=detectAndDescribe(imageB) M = matchKeypoints(kpsA, kpsB, features1, features2, 0.75) (matches, H, status) = M # 将片A进行视角变换,result是变换后片 result = cv.warpPerspective(imageA, H, (imageA.shape[1] + imageB.shape[1], imageB.shape[0])) cv_show('result1',result) result[0:imageB.shape[0], 0:imageB.shape[1]] = imageB cv_show('result2', result) 经常遇到的一个错误: new style getargs format but argument is not a tuple 针对这句代码:result = cv.warpPerspective(imageA,M,[imageA.shape[1]+imageB.shape[1],max(imageA.shape[0],imageB.shape[0])]) 原因是size那个参数应该是tuple(),而不是list[]。即应该是()而不是[]。 下面讲一下这个案例的大体过程: 1.首先我们是通过SIFT算法找到两张(right,left)的特征点及特征向量,并把特征点的坐标储存起来。 2.通过蛮力匹配算法的得到kWmatches对象,将kWmatches对象的queryIdx和trainIdx给存起来,其中features1对应的像为样本像 3.求出样本像的特征点坐标和测试像的特征点坐标,找出这两坐标矩阵的H变换公式(利用RANSAC算法),将H变换公式对right像做透视变换,得到拼接后的右边像 4.将left原赋给result对应的ROI区域,大功告成。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值