如何使用OpenCV-Python实现图像的缝合?(附源码)

如何使用OpenCV-Python实现图像的缝合?(附源码),第1张

如何使用OpenCV-Python实现图像缝合?(附源码) OpenCV杂谈_14
一. 为什么需要图像的缝合?

解决相机视角有限的问题,实现不使用全景相机也能获得全景图像的目的。

二. 图像缝合的过程中需要注意什么?

保证各个相机获取图像的分辨率(或者说是Size)相同

三. 环境配置
  1. Python版本:3.9
  2. 功能包:opencv-python(4.5.1.48)、 numpy (1.20.1)
  3. 文件夹配置:
四. 源码如下
"""实现对图像的缝合(注意点:需要保证左右两张图像的size一样)"""

import cv2
import numpy as np

# 设置一个至少10个匹配的条件(有MinMatchNum指定)来找目标
MinMatchNum = 20

# 读取照片
L = cv2.imread('11.jpg')  # 左半部分
R = cv2.imread('12.jpg')  # 右半部分

# 高斯滤波
L = cv2.GaussianBlur(L, (3, 3), 0)
R = cv2.GaussianBlur(R, (3, 3), 0)

# 创建sift检测器
sift = cv2.xfeatures2d.SIFT_create()

# 计算所有特征点的特征值kp和特征向量des并获取
left_kp, left_des = sift.detectAndCompute(R, None)
right_kp, right_des = sift.detectAndCompute(L, None)

# BFMatcher解决匹配,但是不好的特征值匹配较多
bf = cv2.BFMatcher()
matches = bf.knnMatch(left_des, right_des, k=2)

# 进行特征点匹配筛选
BetterChoose = []
for i, j in matches:
    # 认为第一近的点小于第二近的点一倍以上是好的匹配BetterChoose
    if i.distance < 0.5 * j.distance:
        BetterChoose.append(i)

# 使用Ransac优化匹配结果
BetterChooseAdd = np.expand_dims(BetterChoose, 1)
match = cv2.drawMatchesKnn(L, left_kp, R, right_kp, BetterChooseAdd[:30], None, flags=2)

# 判断是否当前模型已经符合超过MinMatchNum个点
if len(BetterChoose) > MinMatchNum:
    # 获取关键点的坐标
    src_pts = np.float32([left_kp[m.queryIdx].pt for m in BetterChoose]).reshape(-1, 1, 2)
    dst_pts = np.float32([right_kp[m.trainIdx].pt for m in BetterChoose]).reshape(-1, 1, 2)
    # 在这里调用RANSAC方法得到解H
    H, module = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 5.0)
    wrap = cv2.warpPerspective(R, H, (R.shape[1] + R.shape[1], R.shape[0] + R.shape[0]))
    wrap[0:R.shape[0], 0:R.shape[1]] = L
    # 得到新的位置
    rows, cols = np.where(wrap[:, :, 0] != 0)
    min_row, max_row = min(rows), max(rows) + 1
    min_col, max_col = min(cols), max(cols) + 1
    # 去除黑色无用部分
    LeftAndRight = wrap[min_row:max_row, min_col:max_col, :]

# 结果显示
scale = 0.5
cv2.imshow('Left', cv2.resize(L, (0, 0), fx=scale, fy=scale, interpolation=cv2.INTER_NEAREST))  # 左半部分
cv2.imshow('Right', cv2.resize(R, (0, 0), fx=scale, fy=scale, interpolation=cv2.INTER_NEAREST))  # 右半部分
cv2.imshow('Match', cv2.resize(match, (0, 0), fx=scale, fy=scale, interpolation=cv2.INTER_NEAREST))  # 匹配结果
cv2.imshow('LeftAndRight', cv2.resize(LeftAndRight, (0, 0), fx=scale, fy=scale, interpolation=cv2.INTER_NEAREST))  # 拼接结果
cv2.waitKey(0)
cv2.destroyAllWindows()
五. 结果展示
如有问题,敬请指正。欢迎转载,但请注明出处。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5658651.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-16
下一篇 2022-12-16

发表评论

登录后才能评论

评论列表(0条)

保存