导航

    • 登录
    • 搜索
    • 版块
    • 产品
    • 教程
    • 论坛
    • 淘宝
    1. 主页
    2. an2l
    A
    • 举报资料
    • 资料
    • 关注
    • 粉丝
    • 屏蔽
    • 帖子
    • 楼层
    • 最佳
    • 群组

    an2l

    @an2l

    0
    声望
    14
    楼层
    77
    资料浏览
    0
    粉丝
    0
    关注
    注册时间 最后登录

    an2l 关注

    an2l 发布的帖子

    • RE: 利用AprilTag标记追踪功能通过标签实际尺寸与像素宽度比例测量移动距离,为什么误差时小时大,如何减小

      @uzbd 在特定于OPENMV Cam库中未找到返回的​​Homography矩阵​​相关信息,​​Homography矩阵包含什么参数,如需构建​​Homography矩阵该怎么构建?0_1753755397527_6a474d54-7122-4fcb-a6db-04b9d1cc0a4a-image.png

      发布在 OpenMV Cam
      A
      an2l
    • RE: 利用AprilTag标记追踪功能通过标签实际尺寸与像素宽度比例测量移动距离,为什么误差时小时大,如何减小

      @uzbd 使用标签的像素高度使用是否也会有随角度偏移出现梯形导致像素高度失真的现象呢?

      发布在 OpenMV Cam
      A
      an2l
    • RE: 利用AprilTag标记追踪功能通过标签实际尺寸与像素宽度比例测量移动距离,为什么误差时小时大,如何减小

      1.透视畸变用畸变镜头或畸变矫正算法改善作用大吗?程序中已使用畸变矫正
      2.标签尺寸与像素宽度之间是怎么样的关系?
      3.以尝试将标签边沿黑色加深,可以减小像素宽度的误差

      发布在 OpenMV Cam
      A
      an2l
    • 利用AprilTag3D标记追踪功能测量标签移动距离时如何减小计算量?

      可以通过截取两帧或多帧图像,识别不同帧标的签位置计算而不是实时识别标签位置,H7 Plus可以实现吗?如何实现?

      发布在 OpenMV Cam
      A
      an2l
    • 利用AprilTag标记追踪功能通过标签实际尺寸与像素宽度比例测量移动距离,为什么误差时小时大,如何减小

      import sensor, image, time, math

      初始化摄像头

      sensor.reset() # 复位摄像头硬件
      sensor.set_pixformat(sensor.RGB565) # 设置像素格式为RGB565
      sensor.set_framesize(sensor.VGA) # 设置分辨率640x480
      sensor.skip_frames(time=500) # 等待摄像头稳定(0.5秒)
      sensor.set_auto_gain(False) # 关闭自动增益(防止图像过曝)
      sensor.set_auto_whitebal(False) # 关闭自动白平衡

      相机内参设置(需根据实际镜头校准)

      f_x = (2.8 / 3.6736) * 640 # X轴焦距:(焦距mm / 传感器宽度mm)*像素宽度
      f_y = (2.8 / 2.7384) * 480 # Y轴焦距:(焦距mm / 传感器高度mm)*像素高度
      c_x = 640 * 0.5 # 图像中心X坐标
      c_y = 480 * 0.5 # 图像中心Y坐标

      系统状态变量

      SETTING_BASE = 0
      MEASURING = 1
      system_state = SETTING_BASE # 初始状态为设置基准位置

      位置信息

      base_x = None # 基准位置平移量(x)
      base_y = None # 基准位置平移量(y)
      base_w = None # 基准位置标签宽度

      filtered_w = None # 滤波后的标签宽度
      filtered_position = None # 滤波后的当前位置
      stroke_mm = 0 # 计算出的行程值(毫米)
      base_samples = [] # 基准位置采样列表
      current_samples = [] # 当前位置采样列表
      INITIAL_SAMPLES = 10 # 基准位置采样次数
      CURRENT_SAMPLES = 10 # 当前位置采样次数

      AprilTag参数

      TAG_SIZE_MM = 29.5 # AprilTag实际物理尺寸(毫米)

      计算实际距离的函数

      def calculate_real_distance(pixel_distance, k_value):
      """
      根据像素距离和标签宽度计算实际距离
      pixel_distance: 像素距离
      w: 标签宽度(像素)
      返回: 实际距离(毫米)
      """
      # 计算比例系数 K = 标签实际尺寸 / 标签像素尺寸
      return pixel_distance * k_value

      计算二维空间欧氏距离

      def euclidean_distance(pos1, pos2):
      """计算两个像素点之间的欧氏距离"""
      if pos1 is None or pos2 is None:
      return 0.0
      dx = pos1[0] - pos2[0]
      dy = pos1[1] - pos2[1]

      return math.sqrt((dx*dx + dy*dy))
      

      卡尔曼滤波器类

      class KalmanFilter:
      def init(self, initial_value, process_variance=0.5, measurement_variance=0.5):
      """
      一维卡尔曼滤波器
      :param initial_value: 初始估计值
      :param process_variance: 过程噪声方差 (Q)
      :param measurement_variance: 测量噪声方差 (R)
      """
      self.state_estimate = initial_value
      self.estimate_variance = 5 # 初始估计方差 (P)
      self.process_variance = process_variance
      self.measurement_variance = measurement_variance

      def update(self, measurement):
          """
          更新卡尔曼滤波器
          :param measurement: 当前测量值
          :return: 滤波后的估计值
          """
          # 预测步骤
          prior_estimate = self.state_estimate
          prior_variance = self.estimate_variance + self.process_variance
      
          # 更新步骤
          kalman_gain = prior_variance / (prior_variance + self.measurement_variance)
          self.state_estimate = prior_estimate + kalman_gain * (measurement - prior_estimate)
          self.estimate_variance = (1 - kalman_gain) * prior_variance
      
          return self.state_estimate
      

      创建w值卡尔曼滤波器实例

      w_kalman = KalmanFilter(initial_value=10000.0) # 初始值设为50像素

      计算K值函数

      def calculate_k_value(w):
      """根据标签宽度计算比例系数K"""
      return TAG_SIZE_MM / w if w > 0 else 1.0

      加权平均位置计算

      def weighted_average_position(positions):
      """使用加权平均计算位置(近期样本权重更高)"""
      if not positions:
      return None

      n = len(positions)
      total_weight = 0
      weighted_x = 0
      weighted_y = 0
      
      # 使用线性权重:最近样本权重最高
      for i, pos in enumerate(positions):
          # 权重 = (样本索引 + 1)  最近样本权重最高
          weight = i + 1
          total_weight += weight
          weighted_x += pos[0] * weight
          weighted_y += pos[1] * weight
      
      return (
          weighted_x / total_weight,
          weighted_y / total_weight,
      )
      

      clock = time.clock()

      主循环

      while(True):
      clock.tick()
      img = sensor.snapshot().lens_corr(1.6) # 捕获一帧图像
      #img.draw_rectangle([70,160,50,50], color=(255, 0, 0))
      # 检测AprilTag标签
      tags = img.find_apriltags(fx=f_x, fy=f_y, cx=c_x, cy=c_y,
      families=image.TAG36H11, tag_size=TAG_SIZE_MM)

      if tags:  # 如果检测到标签
          tag = tags[0]  # 假设只检测一个标签
      
          # 在图像上绘制标签轮廓
          img.draw_rectangle(tag.rect, color=(255, 0, 0))
          # 在图像上绘制标签中心十字
          img.draw_cross(tag.cx, tag.cy, color=(0, 255, 0))
          img.draw_string(0, 400, "ID:%d" % tag.id, color=(255, 0, 0))
      
          # 获取标签坐标位置
          x, y, w, h= tag.rect
      
          # 使用卡尔曼滤波处理w值
          filtered_w = w_kalman.update(w)
      
          # 计算当前比例系数K
          k_value = calculate_k_value(filtered_w)
      
          # 记录当前二维空间位置
          current_position = (x, y)
      
          if system_state == SETTING_BASE:
              # 设置基准位置阶段
              base_samples.append((x,y))  # 存储平移量
              #w_samples.append(w)          # 存储宽度
      
              # 显示设置进度
              progress = len(base_samples) / INITIAL_SAMPLES * 100
              img.draw_string(0, 10, "Setting base:%d%%" % progress, color=(255, 255, 0))
      
              if len(base_samples) >= INITIAL_SAMPLES:
                  # 计算加权平均平移量
                  avg_x = sum(sample[0] for sample in base_samples) / len(base_samples)
                  avg_y = sum(sample[1] for sample in base_samples) / len(base_samples)
      
                  # 存储基准位置和宽度
                  base_x, base_y = avg_x, avg_y
      
                  # 计算基准位置
                  base_position = (avg_x, avg_y)
      
                  print("Base position set: (%.1f, %.1f)mm" % base_position)
                  print("Base translation: (%.2f, %.2f)" % (base_x, base_y))
                  print("Base width: %.1f pixels" % filtered_w)
      
                  # 切换到测量状态
                  system_state = MEASURING
                  base_samples = []  # 清空样本
                  current_samples = []  # 初始化当前位置采样列表
      
          elif system_state == MEASURING:
              # 测量阶段
              # 将当前位置添加到采样列表
              current_samples.append((x, y))
      
              # 保持采样列表长度不超过设定值
              if len(current_samples) > CURRENT_SAMPLES:
                  current_samples.pop(0)  # 移除最旧的样本
      
              # 计算加权平均平移量
              if len(current_samples) >= 0:  # 至少有0个样本
                  avg_x = sum(sample[0] for sample in current_samples) / len(current_samples)
                  avg_y = sum(sample[1] for sample in current_samples) / len(current_samples)
      
                  # 计算滤波后的位置
                  filtered_position = (avg_x, avg_y)
      
                  # 计算基准位置(使用当前比例系数)
                  base_position = (base_x, base_y)
      
                  # 计算像素距离
                  pixel_distance = euclidean_distance((avg_x, avg_y), (base_x, base_y))
      
                  # 计算实际距离
                  stroke_mm = calculate_real_distance(pixel_distance, k_value)
      
      
              # 显示行程信息
              if filtered_position:
                  text = "Distance:%.1fmm" % stroke_mm
                  img.draw_string(0, 430, text, color=(0, 255, 0))
      
                  # 显示当前位置
                  pos_text = "Pos:(%.1f,%.1f)mm" % filtered_position
                  img.draw_string(0, 450, pos_text, color=(255, 255, 0))
      
                  # 显示标签宽度信息
                  w_text = "Width:%.1f (K=%.4f)" % (filtered_w, k_value)
                  img.draw_string(0, 470, w_text, color=(255, 255, 0))
      
                  # 显示采样信息
                  sample_text = "Samples:%d/%d" % (len(current_samples), CURRENT_SAMPLES)
                  img.draw_string(0, 420, sample_text, color=(255, 255, 0))
      
                  # 显示卡尔曼增益信息
                  kalman_gain = w_kalman.estimate_variance / (w_kalman.estimate_variance
                                                          + w_kalman.measurement_variance)
                  gain_text = "Kalman Gain: %.2f" % kalman_gain
                  img.draw_string(0, 230, gain_text, color=(150, 150, 255))
      
                  print("%s | W:%.1fpx | K:%.4f | Gain:%.2f" % (
                                      text, filtered_w, k_value, kalman_gain))
                  # 打印调试信息
                  print("%s | Filtered Pos: (%.1f,%.1f)mm" % (
                      text, filtered_position[0], filtered_position[1]))
      
      else:
          # 未检测到标签时的处理
          if system_state == SETTING_BASE:
              img.draw_string(0, 10, "Place piston at base position", color=(255, 0, 0))
          elif system_state == MEASURING:
              if filtered_position:
                  img.draw_string(0, 430, "Distance:%.1fmm" % stroke_mm, color=(0, 255, 0))
              img.draw_string(0, 420, "Tag lost!", color=(255, 0, 0))
      
      # 显示系统状态
      states = ["SETTING_BASE", "MEASURING"]
      img.draw_string(0, 440, "State:%s" % states[system_state], color=(255, 255, 255))
      
      # 显示实时帧率
      img.draw_string(0, 410, "FPS:%.1f" % clock.fps(), color=(255, 255, 255))
      print(clock.fps())
      
      # 显示基准位置
      if system_state == MEASURING:
          base_text = "Base:(%.1f,%.1f)mm" % base_position
          img.draw_string(0, 460, base_text, color=(255, 255, 0))
      发布在 OpenMV Cam
      A
      an2l
    • 使用AprilTag 3D定位功能实现测距功能时,K值有办法根据不同距离自动计算吗?

      0_1751968035425_8c766b27-13fe-42a2-8bb7-62dc097f4c36-image.png

      发布在 OpenMV Cam
      A
      an2l
    • RE: 如何识别不规则的物体形状,颜色不固定,可以使用那些方法识别?纯新手小白求解答

      感谢大佬,也是考虑TAG码的方案,激光测距仪方案受温度影响才考虑传统的视觉方案

      发布在 OpenMV Cam
      A
      an2l
    • RE: mv4 h7plus在刷写引导加载程序时显示Cannot open DFU device 0483,该怎么解决

      用STM32刷成功了,已解决,感谢大佬

      发布在 OpenMV Cam
      A
      an2l
    • RE: 如何识别不规则的物体形状,颜色不固定,可以使用那些方法识别?纯新手小白求解答

      运动是银色部分会伸出一定长度的柱子,需要通过模块实时测量伸出柱子的长度0_1751598258461_274dd1dd-3938-4d8d-be51-e55216cd7510-image.png

      发布在 OpenMV Cam
      A
      an2l