地图影像匹配:基于特征匹配的视觉定位2,python

根据之前视频防抖的代码,重新写了一套。能够输出缩放、旋转的信息。

  • 代码

    import cv2
    import numpy as np
    import argparse
    import os
    import re
    import math
    import matplotlib.pyplot as plt
    import time

    def show_image(image):
    plt.figure(figsize=(15, 10))
    plt.imshow(image)
    plt.title('Feature Matching Results')
    plt.show()

    def process_transform(refer_kp, drone_kp, matches, drone_frame):
    # 提取匹配点的坐标
    refer_pts = np.float32([refer_kp[m.queryIdx].pt for m in matches]).reshape(-1, 1, 2)
    drone_pts = np.float32([drone_kp[m.trainIdx].pt for m in matches]).reshape(-1, 1, 2)

    复制代码
      # 计算单应性矩阵
      H, mask = cv2.findHomography(drone_pts, refer_pts, cv2.RANSAC, 5.0)
          
      if H is None:
          print(f"无法计算 {frame_files[i]} 的变换矩阵,使用上一帧的变换")
          # 如果无法计算,使用恒等变换
          H = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]])
          
      # 从单应性矩阵中提取变换信息
      scale        = np.sqrt(H[0,0]**2 + H[1,0]** 2)
      rotation_rad = math.atan2(H[1,0], H[0,0])
      rotation_deg = math.degrees(rotation_rad)
      x_offset     = H[0,2]
      y_offset     = H[1,2]
      print('transform: scale=%.2f, rotation_rad=%.2f, rotation_deg=%.2f, x_offset=%.2f, y_offset=%.2f' % (scale, rotation_rad, rotation_deg, x_offset, y_offset))
          
      # 应用变换矩阵进行修正
      # height, width  = drone_frame.shape[:2]
      # adjusted_frame = cv2.warpPerspective(drone_frame, H, (width, height))
      # cv2.imwrite(adjusted_frame_path, adjusted_frame)

    def process_frame(frame):
    # 读取第一帧作为初始基准帧
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    复制代码
      # 检测基准帧的特征点和描述符
      kp, des = orb.detectAndCompute(gray, None)
      return frame, gray, kp, des

    def map_match(reference, drone):

    复制代码
      current_time = time.time()
      refer_frame, refer_gray, refer_kp, refer_des = process_frame(reference)
      drone_frame, drone_gray, drone_kp, drone_des = process_frame(drone)
          
      # 匹配特征点(当前帧与上一调整后的帧)
      matches = matcher.match(refer_des, drone_des)
      # 按匹配距离排序,取前100个最佳匹配
      matches = sorted(matches, key=lambda x: x.distance)[:10]
          
      process_transform(refer_kp, drone_kp, matches, drone_frame)
    
      print('cost time: %.2f ms' % ((time.time()-current_time)*1000))
      
      match_img = cv2.drawMatches(refer_frame, refer_kp,
                             drone_frame, drone_kp,
                             matches, None,
                             flags=cv2.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS)
    
      show_image(match_img)

    初始化ORB特征检测器和匹配器

    orb = cv2.ORB_create(1000)
    matcher = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)

    if name == "main":
    for index in range(1, 10):
    image1 = ('images/map-%02d.jpg' % ((index-1)*3))
    image1 = cv2.imread(image1)
    image2 = ('images/map-%02d.jpg' % ( index *3))
    image2 = cv2.imread(image2)
    map_match(image1, image2)

  • 效果

准确的计算出旋转角度,90。

复制代码
transform: scale=0.72, rotation_rad=-1.57, rotation_deg=-89.81, x_offset=184.79, y_offset=737.42
cost time: 45.87 ms
相关推荐
yunhuibin2 小时前
LeNet
人工智能·python
郝学胜-神的一滴3 小时前
深入理解网络IP协议与TTL机制:从原理到实践
linux·服务器·开发语言·网络·网络协议·tcp/ip·程序人生
程序猿_极客5 小时前
【2025 年最新版】Java JDK 安装与环境配置教程(附图文超详细,Windows+macOS 通用)
java·开发语言·windows·macos·jdk
二哈喇子!9 小时前
BOM模型
开发语言·前端·javascript·bom
二哈喇子!9 小时前
空指针异常
开发语言
咚为9 小时前
Rust Print 终极指南:从底层原理到全场景实战
开发语言·后端·rust
jaray9 小时前
PyCharm 2024.3.2 Professional 如何更换 PyPI 镜像源
ide·python·pycharm·pypi 镜像源
%xiao Q9 小时前
GESP C++五级-202406
android·开发语言·c++
Psycho_MrZhang9 小时前
Neo4j Python SDK手册
开发语言·python·neo4j