【opencv】图像拼接实验

实验环境:anaconda、jupyter notebook

实验用到的包:opencv、matplotlib、numpy

注:opencv在3.4.2之后sift就不是免费的了

我用的是3.4.1.15版本

实验使用到的图片

book

pile

ml

mr

一、sift函数获取特征值

读入图片

book = cv2.imread('book.png', cv2.IMREAD_GRAYSCALE)
pile = cv2.imread('pile.png', cv2.IMREAD_GRAYSCALE)

plt.imshow(book,'gray')
plt.show()
plt.imshow(pile,'gray')
plt.show()

书和书堆

获取特征点和特征向量

# 计算特征点和特征向量
sift = cv2.xfeatures2d.SIFT_create()

kp1,des1 = sift.detectAndCompute(book, None)
kp2,des2 = sift.detectAndCompute(pile, None)

一对一匹配

# 一对一
bf = cv2.BFMatcher(crossCheck=True)

matches = bf.match(des1,des2)
matches = sorted(matches, key=lambda x : x.distance)

res = cv2.drawMatches(book, kp1, pile, kp2, matches[:10],None, flags=2)

plt.figure(figsize=(12,8))
plt.imshow(res,'gray')
plt.show()

显示前十个匹配

一对一匹配

k对最佳匹配

# k对最佳匹配
bf = cv2.BFMatcher()
matches = bf.knnMatch(des1,des2, k=2)

# 把距离小于阈值的记录下来
good = []
for m,n in matches:
    if m.distance < 0.75 * n.distance:
        good.append([m])

res = cv2.drawMatchesKnn(book, kp1, pile, kp2,good,None, flags=2)

plt.figure(figsize=(12,8))
plt.imshow(res,'gray')
plt.show()

n对n匹配

二、图像拼接实验

读入图片

ml = cv2.imread('ml.png')
ml_gray = cv2.cvtColor(ml, cv2.COLOR_BGR2GRAY)
mr = cv2.imread('mr.png')
mr_gray = cv2.cvtColor(mr, cv2.COLOR_BGR2GRAY)

plt.imshow(ml_gray, 'gray')
plt.show()

plt.imshow(mr_gray, 'gray')
plt.show()

待拼接图片

获取特征点和特征向量

# 获取特征点和特征向量
sift = cv2.xfeatures2d.SIFT_create()
kpl,desl = sift.detectAndCompute(ml_gray, None)
kpl_f = np.float32([kp.pt for kp in kpl])
kpr,desr = sift.detectAndCompute(mr_gray, None)
kpr_f = np.float32([kp.pt for kp in kpr])

# 匹配并显示
bf = cv2.BFMatcher(crossCheck=True)

matches = bf.match(desl,desr)
matches = sorted(matches, key=lambda x : x.distance)

res = cv2.drawMatches(ml_gray, kpl, mr_gray, kpr, matches[:100],None, flags=2)

plt.figure(figsize=(12,8))
plt.imshow(res,'gray')
plt.show()

匹配特征点

拼接图片

拼接图片实质上就是把一张图片的一部分变化到匹配另一张图片后,把另一张图片覆盖到变化的部分上

matcher = cv2.BFMatcher()

raw_matches = matcher.knnMatch(desr, desl, 2)

H = None

matches = []
for m in raw_matches:
    # 保留合适的特征值
    if len(m) == 2 and m[0].distance < m[1].distance * 0.75 :
        matches.append([m[0].trainIdx, m[0].queryIdx])

# 配对大于4时,计算时间变换矩阵
if len(matches) > 4:
    # 获取配对的点坐标
    ptsl = np.float32([kpl_f[i] for (i,_) in matches])
    ptsr = np.float32([kpr_f[i] for (_,i) in matches])
    # 计算视角变换矩阵
    (H, status) = cv2.findHomography(ptsr, ptsl, cv2.RANSAC, 4)



#对右图进行变换
result = cv2.warpPerspective(mr,H,(mr.shape[1] + ml.shape[1],mr.shape[0]))

plt.title('before')
plt.imshow(cv2.cvtColor(result, cv2.COLOR_BGR2RGB))
plt.show() 

# 左图覆盖
result[0:ml.shape[0], 0:ml.shape[1]] = ml

plt.title('after')
plt.imshow(cv2.cvtColor(result, cv2.COLOR_BGR2RGB))
plt.show() 

拼接结果

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值