cv2.drawmatchesknn匹配后如何确认匹配点
时间: 2024-04-07 22:30:56 浏览: 65
在使用cv2.drawmatchesknn函数进行匹配后,可以通过以下步骤确认匹配点:
1. 首先,根据cv2.drawmatchesknn函数的返回值,获取匹配点的信息。通常情况下,可以使用DMatch对象来表示匹配点,DMatch对象包含了匹配点的特征描述子的索引和距离等信息。
2. 接着,可以通过设置一个阈值来筛选出合适的匹配点。一般来说,距离较小的匹配点更加可靠,因此可以根据距离来进行筛选。例如,可以只保留距离最小的10%的匹配点,而剩下的匹配点可以舍弃。
3. 最后,可以使用cv2.drawMatches函数将保留下来的匹配点可视化出来,以便进一步检查匹配的准确性。
总之,确认匹配点的过程需要结合实际应用场景和数据特征来进行,需要灵活运用各种工具和方法。
相关问题
def mspp(self): file_path1= filedialog.askopenfilename() file_path2 = filedialog.askopenfilename() queryImage = cv2.imread(file_path1, 0) trainingImage = cv2.imread(file_path2, 0) # 只使用SIFT 或 SURF 检测角点 sift = cv2.SIFT_create() # sift = cv2.xfeatures2d.SURF_create(float(4000)) kp1, des1 = sift.detectAndCompute(queryImage, None) kp2, des2 = sift.detectAndCompute(trainingImage, None) # 设置FLANN匹配器参数 # algorithm设置可参考https://docs.opencv.org/3.1.0/dc/d8c/namespacecvflann.html indexParams = dict(algorithm=0, trees=5) searchParams = dict(checks=50) # 定义FLANN匹配器 flann = cv2.FlannBasedMatcher(indexParams, searchParams) # 使用 KNN 算法实现匹配 matches = flann.knnMatch(des1, des2, k=2) # 根据matches生成相同长度的matchesMask列表,列表元素为[0,0] matchesMask = [[0, 0] for i in range(len(matches))] # 去除错误匹配 for i, (m, n) in enumerate(matches): if m.distance < 0.7 * n.distance: matchesMask[i] = [1, 0] # 将图像显示 # matchColor是两图的匹配连接线,连接线与matchesMask相关 # singlePointColor是勾画关键点 drawParams = dict(matchColor=(0, 255, 0), singlePointColor=(255, 0, 0), matchesMask=matchesMask, flags=0) resultImage = cv2.drawMatchesKnn(queryImage, kp1, trainingImage, kp2, matches, None, **drawParams) plt.imshow(resultImage, ), plt.show()
这段代码实现了图像特征点匹配的功能,使用的是 OpenCV 库。首先通过 filedialog 选择两个要进行匹配的图像,然后使用 SIFT 算法检测两个图像的特征点。接着,使用 FLANN 算法对两张图像的特征点进行匹配,并去除错误匹配。最后,将匹配结果可视化并显示出来。其中,kp1、des1、kp2、des2 分别表示两张图像检测出的特征点和对应的特征描述子向量。matches 表示 FLANN 算法匹配得到的特征点对,matchesMask 表示筛选后的匹配对应的掩码,resultImage 表示可视化后的匹配结果图像。
import numpy as np import cv2 as cv import matplotlib.pyplot as plt img1 = cv.imread('D:/junzhi/3-7000-10k.png', ) img2 = cv.imread('D:/junzhi/3-7000-10y.png', ) 初始化 AKAZE 探测器 akaze = cv.AKAZE_create() 使用 SIFT 查找关键点和描述 kp1, des1 = akaze.detectAndCompute(img1, None) kp2, des2 = akaze.detectAndCompute(img2, None) BFMatcher 默认参数 bf = cv.BFMatcher() matches = bf.knnMatch(des1, des2, k=2) 旋转测试 good_matches = [] for m,n in matches: if m.distance < 0.75*n.distance: good_matches.append([m]) 画匹配点 img3 = cv.drawMatchesKnn(img1,kp1,img2,kp2,good_matches,None,flags=cv.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS) #cv.imwrite('matches.png', img3) 选择匹配关键点 ref_matched_kpts = np.float32([kp1[m[0].queryIdx].pt for m in good_matches]).reshape(-1,1,2) sensed_matched_kpts = np.float32([kp2[m[0].trainIdx].pt for m in good_matches]).reshape(-1,1,2) 计算 homography H, status = cv.findHomography(ref_matched_kpts, sensed_matched_kpts, cv.RANSAC,1.0) 变换 warped_image = cv.warpPerspective( img2, H, (img2.shape[1], img2.shape[0])) cv.imwrite('warped.png', warped_image)改进这个程序使变换图像前后位深度一致
要确保变换前后的图像具有相同的位深度,可以通过使用 `cv2.bitwise_and` 函数来实现。这将确保变换后的图像与原始图像具有相同的位深度。以下是改进后的代码示例:
```python
import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt
img1 = cv.imread('D:/junzhi/3-7000-10k.png')
img2 = cv.imread('D:/junzhi/3-7000-10y.png')
# 初始化 AKAZE 探测器
akaze = cv.AKAZE_create()
# 使用 AKAZE 查找关键点和描述子
kp1, des1 = akaze.detectAndCompute(img1, None)
kp2, des2 = akaze.detectAndCompute(img2, None)
# BFMatcher 默认参数
bf = cv.BFMatcher()
matches = bf.knnMatch(des1, des2, k=2)
# 旋转测试
good_matches = []
for m, n in matches:
if m.distance < 0.75 * n.distance:
good_matches.append([m])
# 画匹配点
img3 = cv.drawMatchesKnn(img1, kp1, img2, kp2, good_matches, None, flags=cv.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS)
# 选择匹配关键点
ref_matched_kpts = np.float32([kp1[m[0].queryIdx].pt for m in good_matches]).reshape(-1, 1, 2)
sensed_matched_kpts = np.float32([kp2[m[0].trainIdx].pt for m in good_matches]).reshape(-1, 1, 2)
# 计算 homography
H, status = cv.findHomography(ref_matched_kpts, sensed_matched_kpts, cv.RANSAC, 1.0)
# 变换
warped_image = cv.warpPerspective(img2, H, (img1.shape[1], img1.shape[0]))
# 确保变换后的图像与原始图像具有相同的位深度
warped_image = cv.bitwise_and(warped_image, np.ones_like(img1) * 255)
cv.imwrite('warped.png', warped_image)
```
在上述代码中,我们使用 `cv2.bitwise_and` 函数将变换后的图像与一个全白图像进行按位与操作,以确保它们具有相同的位深度。这里我们使用 `np.ones_like(img1) * 255` 创建了一个与原始图像 `img1` 相同大小的全白图像,然后将其与变换后的图像进行按位与操作。这将确保变换后的图像的位深度与原始图像相同。
阅读全文