当前位置:   article > 正文

RANSAC+SIFT影像特征匹配(python-opencv)_python ransac筛选特征匹配点

python ransac筛选特征匹配点

首先读入图片

  1. import cv2
  2. import numpy as np
  3. img1=cv2.imread("./picture1/picture1/1/14x00424.JPG")
  4. img2=cv2.imread("./picture1/picture1/1/14x00425.JPG")

然后识别影像特征点及其特征点描述子

  1. sift = cv2.SIFT_create(1000)
  2. kp1, des1 = sift.detectAndCompute(img1, None)
  3. kp2, des2 = sift.detectAndCompute(img2, None)

构建匹配器,执行KNN匹配。

  1. bf=cv2.BFMatcher()
  2. matches = bf.knnMatch(des1,des2,k=2)
  3. """
  4. 这里有个大坑,当你想这里直接画出所有的匹配时,
  5. 这里面的matches返回的是最近距离和次近距离的两个Dmacther元组。
  6. 如下图,直接用drawMatches函数时,matches1 to matches2就会是含有两个值的元组,然后出现BUG。
  7. """

但是在后续粗匹配时,我们又需要最近邻次距离之比做粗匹配筛选错点。如果不需要,建议直接用matches直接做暴力匹配。

但是,为了同时对比未筛选匹配和粗筛之后的匹配,我这里直接在近次邻中提取了最近距离。

  1. # 画出暴力匹配初步匹配后的所有匹配
  2. matches1=[]
  3. for i in matches:
  4. matches1.append(i[0])
  5. img_matches=cv2.drawMatches(img1,kp1,img2,kp2,matches1,None,flags=2)

然后根据最近邻次比做粗筛,画出粗筛之后的匹配。

  1. good_matches=[]
  2. for m,n in matches:
  3. if m.distance < 0.7 * n.distance:
  4. good_matches.append(m)
  5. img_good_matches=cv2.drawMatches(img1,kp1,img2,kp2,good_matches, None, flags=cv2.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS)

仔细观察依旧存在很多误匹配的点。 

这时,我们采用RANSAC算法进行最后的精匹配。 

  1. MIN_MATCH_COUNT = 10
  2. if len(good_matches)>MIN_MATCH_COUNT:
  3. src_pts = np.float32([kp1[m.queryIdx].pt for m in good_matches]).reshape(-1, 1, 2)
  4. dst_pts = np.float32([kp2[m.trainIdx].pt for m in good_matches]).reshape(-1, 1, 2)
  5. M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 4.0)
  6. matchesMask = mask.ravel().tolist()
  7. ransac = []
  8. for i in range(0,len(matchesMask)):
  9. if matchesMask[i]==1:
  10. # print(i)
  11. ransac.append(good_matches[i]) #单独取出内点
  12. print(ransac)
  13. """
  14. 这里的cv2.findHomography()返回值有两个.
  15. 第一个是变换所需要的单应矩阵M,
  16. 第二个返回的是一个掩膜值mask,这个掩模确定了RANSAC算法筛选之后的内点和外点。
  17. """

可以发现这个掩膜的值为0或者1,掩膜通常是一个与原始图像大小相同的二值或布尔图像,其中,选定的区域被标记为1(或True),而其余区域被标记为0(或False)。也就是值为1所对应的good_matches是筛选之后的内点。

最后输出精匹配的成果图即可。

完整代码如下: 

  1. import cv2
  2. import numpy as np
  3. img1=cv2.imread("./picture1/picture1/1/14x00424.JPG")
  4. img2=cv2.imread("./picture1/picture1/1/14x00425.JPG")
  5. sift = cv2.SIFT_create(1000)
  6. kp1, des1 = sift.detectAndCompute(img1, None)
  7. kp2, des2 = sift.detectAndCompute(img2, None)
  8. bf=cv2.BFMatcher()
  9. matches = bf.knnMatch(des1,des2,k=2)
  10. # 画出暴力匹配初步匹配后的所有匹配
  11. matches1=[] # 最近距离
  12. for i in matches:
  13. matches1.append(i[0])
  14. img_matches=cv2.drawMatches(img1,kp1,img2,kp2,matches1,None,flags=2)
  15. good_matches=[]
  16. for m,n in matches:
  17. if m.distance < 0.7 * n.distance:
  18. good_matches.append(m)
  19. img_good_matches=cv2.drawMatches(img1,kp1,img2,kp2,good_matches, None, flags=cv2.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS)
  20. MIN_MATCH_COUNT = 10
  21. if len(good_matches)>MIN_MATCH_COUNT:
  22. src_pts = np.float32([kp1[m.queryIdx].pt for m in good_matches]).reshape(-1, 1, 2)
  23. dst_pts = np.float32([kp2[m.trainIdx].pt for m in good_matches]).reshape(-1, 1, 2)
  24. M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 4.0)
  25. matchesMask = mask.ravel().tolist()
  26. ransac = [] # 筛选出RANSAC之后的内点
  27. for i in range(0,len(matchesMask)):
  28. if matchesMask[i]==1:
  29. # print(i)
  30. ransac.append(good_matches[i])
  31. print(ransac)
  32. # h,w = img1.shape[:2]
  33. # pts = np.float32([[0, 0], [0, h - 1], [w - 1, h - 1], [w - 1, 0]]
  34. # ).reshape(-1, 1, 2)
  35. # dst = cv2.perspectiveTransform(pts, M)
  36. # # img2 = cv2.polylines(img2, [np.int32(dst)], True, 255, 5, cv2.LINE_AA)
  37. img_ransac=cv2.drawMatches(img1, kp1, img2, kp2, good_matches, None)
  38. "未经过筛选的匹配"
  39. cv2.namedWindow("matches1",cv2.WINDOW_NORMAL)
  40. cv2.imshow("matches1",img_matches)
  41. cv2.imwrite("img_matches.jpg",img_matches)
  42. "粗筛之后的匹配"
  43. cv2.namedWindow("good_matches",cv2.WINDOW_NORMAL)
  44. cv2.imshow("good_matches",img_good_matches)
  45. cv2.imwrite("./good_matches.jpg",img_good_matches)
  46. "使用RANSAC算法筛选过后的匹配"
  47. ransac_result=cv2.drawMatches(img1,kp1,img2,kp2,ransac,None,flags=2)
  48. cv2.namedWindow("ransac_result",cv2.WINDOW_NORMAL)
  49. cv2.imshow("ransac_result",ransac_result)
  50. cv2.imwrite("./ransac_result.jpg",ransac_result)
  51. cv2.waitKey(0)
  52. cv2.destroyAllWindows()

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/代码探险家/article/detail/940203
推荐阅读
相关标签
  

闽ICP备14008679号