一. 为什么需要图像的缝合?
解决相机视角有限的问题,实现不使用全景相机也能获得全景图像的目的。
二. 图像缝合的过程中需要注意什么?保证各个相机获取图像的分辨率(或者说是Size)相同
三. 环境配置- Python版本:3.9
- 功能包:opencv-python(4.5.1.48)、 numpy (1.20.1)
- 文件夹配置:
"""实现对图像的缝合(注意点:需要保证左右两张图像的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()五. 结果展示
如有问题,敬请指正。欢迎转载,但请注明出处。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)