How do I use the relationships between Flann matches to determine a sensible homography?

前端 未结 1 469
太阳男子
太阳男子 2020-12-10 18:50

I have a panorama image, and a smaller image of buildings seen within that panorama image. What I want to do is recognise if the buildings in that smaller image are in that

相关标签:
1条回答
  • 2020-12-10 19:39

    I wrote a blog in about finding object in scene last year( 2017.11.11). Maybe it helps. Here is the link. https://zhuanlan.zhihu.com/p/30936804

    Env: OpenCV 3.3 + Python 3.5


    Found matches:

    The found object in the scene:


    The code:

    #!/usr/bin/python3
    # 2017.11.11 01:44:37 CST
    # 2017.11.12 00:09:14 CST
    """
    使用Sift特征点检测和匹配查找场景中特定物体。
    """
    
    import cv2
    import numpy as np
    MIN_MATCH_COUNT = 4
    
    imgname1 = "box.png"
    imgname2 = "box_in_scene.png"
    
    ## (1) prepare data
    img1 = cv2.imread(imgname1)
    img2 = cv2.imread(imgname2)
    gray1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
    gray2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
    
    
    ## (2) Create SIFT object
    sift = cv2.xfeatures2d.SIFT_create()
    
    ## (3) Create flann matcher
    matcher = cv2.FlannBasedMatcher(dict(algorithm = 1, trees = 5), {})
    
    ## (4) Detect keypoints and compute keypointer descriptors
    kpts1, descs1 = sift.detectAndCompute(gray1,None)
    kpts2, descs2 = sift.detectAndCompute(gray2,None)
    
    ## (5) knnMatch to get Top2
    matches = matcher.knnMatch(descs1, descs2, 2)
    # Sort by their distance.
    matches = sorted(matches, key = lambda x:x[0].distance)
    
    ## (6) Ratio test, to get good matches.
    good = [m1 for (m1, m2) in matches if m1.distance < 0.7 * m2.distance]
    
    canvas = img2.copy()
    
    ## (7) find homography matrix
    ## 当有足够的健壮匹配点对(至少4个)时
    if len(good)>MIN_MATCH_COUNT:
        ## 从匹配中提取出对应点对
        ## (queryIndex for the small object, trainIndex for the scene )
        src_pts = np.float32([ kpts1[m.queryIdx].pt for m in good ]).reshape(-1,1,2)
        dst_pts = np.float32([ kpts2[m.trainIdx].pt for m in good ]).reshape(-1,1,2)
        ## find homography matrix in cv2.RANSAC using good match points
        M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC,5.0)
        ## 掩模,用作绘制计算单应性矩阵时用到的点对
        #matchesMask2 = mask.ravel().tolist()
        ## 计算图1的畸变,也就是在图2中的对应的位置。
        h,w = img1.shape[:2]
        pts = np.float32([ [0,0],[0,h-1],[w-1,h-1],[w-1,0] ]).reshape(-1,1,2)
        dst = cv2.perspectiveTransform(pts,M)
        ## 绘制边框
        cv2.polylines(canvas,[np.int32(dst)],True,(0,255,0),3, cv2.LINE_AA)
    else:
        print( "Not enough matches are found - {}/{}".format(len(good),MIN_MATCH_COUNT))
    
    
    ## (8) drawMatches
    matched = cv2.drawMatches(img1,kpts1,canvas,kpts2,good,None)#,**draw_params)
    
    ## (9) Crop the matched region from scene
    h,w = img1.shape[:2]
    pts = np.float32([ [0,0],[0,h-1],[w-1,h-1],[w-1,0] ]).reshape(-1,1,2)
    dst = cv2.perspectiveTransform(pts,M)
    perspectiveM = cv2.getPerspectiveTransform(np.float32(dst),pts)
    found = cv2.warpPerspective(img2,perspectiveM,(w,h))
    
    ## (10) save and display
    cv2.imwrite("matched.png", matched)
    cv2.imwrite("found.png", found)
    cv2.imshow("matched", matched);
    cv2.imshow("found", found);
    cv2.waitKey();cv2.destroyAllWindows()
    
    0 讨论(0)
提交回复
热议问题