导航

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

    mvea 发布的帖子

    • RE: 尝试同时实现,无法巡线,下面前一段是单独巡线的,是正常的,后一段巡线加模板识别,不行

      前一段是单独巡线,后一段是模板识别加巡线,只能识别寻不了线,求求大佬帮忙看一下

      发布在 OpenMV Cam
      M
      mvea
    • 尝试同时实现,无法巡线,下面前一段是单独巡线的,是正常的,后一段巡线加模板识别,不行
      # Untitled - By: 26306 - Fri May 23 2025
      
      import sensor
      import time
      import image
      from pyb import UART
      
      
      
      uart = UART(3,115200)
      
      sensor.reset()
      sensor.set_pixformat(sensor.RGB565)
      sensor.set_framesize(sensor.QQQVGA)#图像缩小,线性回归算法要求,降低时间
      sensor.skip_frames(time=500)
      
      clock = time.clock()
      
      THRESHOLD =(0,20,-10,10,-10,10)#黑色线的阈值
      last_error_bottom = 0#增加给底部坐标和倾斜角度积分和微分的全局变量
      integral_bottom = 0
      last_error_theta = 0#增加给底部坐标和倾斜角度积分和微分的全局变量
      integral_theta = 0
      def pid_control(error,last_error,integral,Kp,Ki,Kd):
          proportional = Kp * error
          integral += error#积分,刷新率高,加法就是积分
          integral = integral * Ki
      
          derivative = Kd * (error - last_error)
      
          output = proportional + integral + derivative
          last_error = error
          return output, last_error,integral
      def get_endpoint(line):
          (x1,y1,x2,y2) = line.line()#直线的上下两个端点,底部y值大
          if y1>y2:
               return (x1,y1)
          else :
               return (x2,y2)#那么下一步查找直线倾斜角度
      def theta_change(theta):
          if theta > 90:
              theta = theta -180
              return theta
          else :
              return theta
      
      while True:
          clock.tick()
          img = sensor.snapshot()
          img.binary([THRESHOLD])#二值化
          img.open(1)#消除噪点
          img.gaussian(1)#边缘光滑,下面就可以计算了
          line = img.get_regression([(100,100)],robust = True) #下面判断是否真的找到直线
          if line and line.magnitude() >8:#直线的置信度,
              img.draw_line(line.line(),color = (255,0,0), thickness = 2)
              bottom_x,bottom_y = get_endpoint(line)
              error_x =  bottom_x-img.width()//2 #变量为直线的底部端点和画布中心的误差
              theta = theta_change(line.theta())#  error_x和 theta>0都是小车要往右走
      
              output_bottom,last_error_bottom,integral_bottom = pid_control(error_x,last_error_bottom,integral_bottom,0.7,0,0.17)
              output_theta,last_error_theta,integral_theta = pid_control(theta,last_error_theta,integral_theta,0.8,0,0.2)
      
              output = output_bottom + output_theta
              if(output >100):
                output = 100
              elif(output<-100):
                output=-100
              output = int(output)#强制类型转化
      
      
              send_value = 128 + output
              print("Send Value:", send_value)  # 输出十进制值
              result = "@%03d#" % send_value  # 用 %03d 格式化,保证三位数
              uart.write(result)
          else :
             result = "@%03d#" %0
             uart.write(result)
             print("Send Value:",  result)  # 输出十进制值
          #print(clock.fps())
      #########以上是单独巡线的代码,是正常的,下面是巡线和模板结合的代码,无法巡线了
      
      
      
      
      
      # OpenMV 多功能视觉处理 - 模板匹配 + PID巡线
      # By: 26306
      # Date: 2025-05-23
      
      import sensor, image, time, math
      from image import SEARCH_EX, SEARCH_DS
      from pyb import LED, UART
      
      # 初始化UART
      uart = UART(3, 115200)
      
      # 初始化摄像头
      sensor.reset()
      sensor.set_contrast(1)
      sensor.set_gainceiling(16)
      sensor.set_framesize(sensor.QQVGA)  # 80x60分辨率
      sensor.set_pixformat(sensor.GRAYSCALE)  # 灰度图模式
      sensor.skip_frames(time=500)  # 等待设置生效
      
      # 加载模板图像
      template2 = image.Image("4.pgm")
      
      # PID控制参数
      THRESHOLD = (0, 20, -10, 10, -10, 10)  # 黑色线的阈值
      last_error_bottom = 0
      integral_bottom = 0
      last_error_theta = 0
      integral_theta = 0
      
      clock = time.clock()
      
      def get_endpoint(line):
          """获取直线的底部端点"""
          (x1, y1, x2, y2) = line.line()
          return (x1, y1) if y1 > y2 else (x2, y2)
      
      def theta_change(theta):
          """角度归一化到[-90,90]"""
          return theta - 180 if theta > 90 else theta
      
      def pid_control(error, last_error, integral, Kp, Ki, Kd):
          """PID控制器"""
          proportional = Kp * error
          integral += error
          integral *= Ki
          derivative = Kd * (error - last_error)
          output = proportional + integral + derivative
          return output, error, integral
      
      while True:
          clock.tick()
          img = sensor.snapshot()  # 获取原始图像
      
          # ========== 1. 模板匹配部分 ==========
          r = img.find_template(template2, 0.70, step=4, search=SEARCH_EX)
          if r:
              print("A")
              img.draw_rectangle(r)
      
          
          
          # ========== 2. 巡线部分 ==========
          img2 = img.copy()  # 创建独立副本用于巡线处理
          img2.binary([THRESHOLD])  # 二值化
          img2.open(1)  # 开运算去噪
          img2.gaussian(1)  # 高斯滤波
      
          line = img2.get_regression([(100, 100)], robust=True)
      
          if line and line.magnitude() > 8:
              # 绘制检测到的线
              img.draw_line(line.line(), color=(255, 0, 0), thickness=2)
      
              # 计算控制参数
              bottom_x, bottom_y = get_endpoint(line)
              error_x = bottom_x - img.width() // 2
              theta = theta_change(line.theta())
      
              # PID计算
              output_bottom, last_error_bottom, integral_bottom = pid_control(
                  error_x, last_error_bottom, integral_bottom, 0.7, 0, 0.17)
      
              output_theta, last_error_theta, integral_theta = pid_control(
                  theta, last_error_theta, integral_theta, 0.8, 0, 0.2)
      
              # 综合输出
              output = output_bottom + output_theta
              output = max(-100, min(100, output))  # 限制在[-100,100]范围
              output = int(output)
      
              # 串口发送控制指令
              send_value = 128 + output  # 转换为128±100的范围
              print("Send Value:", send_value)
              result = "@%03d#" % send_value  # 格式化输出
              uart.write(result)
          else:
              # 未检测到线时发送中性值
              result = "@128#"
              uart.write(result)
              print("No line detected")
      
          # 显示帧率(调试用)
          # print(clock.fps())
      
      
      
      
      发布在 OpenMV Cam
      M
      mvea