• 免费好用的星瞳AI云服务上线!简单标注,云端训练,支持OpenMV H7和OpenMV H7 Plus。可以替代edge impulse。 https://forum.singtown.com/topic/9519
  • 我们只解决官方正版的OpenMV的问题(STM32),其他的分支有很多兼容问题,我们无法解决。
  • 如果有产品硬件故障问题,比如无法开机,论坛很难解决。可以直接找售后维修
  • 发帖子之前,请确认看过所有的视频教程,https://singtown.com/learn/ 和所有的上手教程http://book.openmv.cc/
  • 每一个新的提问,单独发一个新帖子
  • 帖子需要目的,你要做什么?
  • 如果涉及代码,需要报错提示全部代码文本,请注意不要贴代码图片
  • 必看:玩转星瞳论坛了解一下图片上传,代码格式等问题。
  • 帧缓冲区上我打印的数据以后会不会对后续的图像识别有干扰?



    • import sensor, image, time, math
      from pyb import UART, LED, Pin, Timer
      import display
      
      # Initialize the camera sensor.
      sensor.reset()
      sensor.set_contrast(1)
      sensor.set_pixformat(sensor.GRAYSCALE)  # Set to grayscale mode
      sensor.set_framesize(sensor.QQVGA)
      sensor.skip_frames(30)
      sensor.set_auto_gain(False)
      sensor.set_auto_whitebal(False)
      clock = time.clock()
      sensor.set_vflip(True)
      sensor.set_hmirror(True)
      
      # Initialize LED and UART
      LED(1).on()  # Ensure LED1 is on
      LED(2).on()  # Ensure LED2 is on
      LED(3).on()  # Ensure LED3 is on
      
      uart = UART(3, 115200, timeout_char=1000)
      
      # Initialize flash light using PWM on Pin P6
      light = Timer(2, freq=50000).channel(1, Timer.PWM, pin=Pin("P6"))
      light.pulse_width_percent(5)  # Control brightness 0~100
      
      u_start = bytearray([0xb3, 0xb3])
      u_over = bytearray([0x0d, 0x0a])
      GRAYSCALE_THRESHOLD = [(5, 70)]  # Grayscale threshold for line following
      ROIS = [
          (0, 90, 160, 20, 0.7),  # Bottom region, weight 0.7
          (0, 50, 160, 20, 0.4),  # Middle region, weight 0.4
          (0, 0, 160, 20, 0.05)   # Top region, weight 0.05
      ]  # Three regions
      weight_sum = 0
      range_stop = [390, 190, 100]  # Minimum pixel value for stop line
      range_wait = [60, 40, 0]  # Minimum pixel value for wait stop line
      for r in ROIS:
          weight_sum += r[4]
      
      thresholds = [(-100, 72, -128, -16, -128, 127)]  # Threshold for distance measurement
      
      # Initialize the LCD screen.
      lcd = display.SPIDisplay()
      
      # Function to find two largest blobs
      def find_max(blobs):
          max_size = [0, 0]
          max_ID = [-1, -1]
          for i in range(len(blobs)):
              if blobs[i].pixels() > max_size[0]:
                  max_ID[1] = max_ID[0]
                  max_size[1] = max_size[0]
                  max_ID[0] = i
                  max_size[0] = blobs[i].pixels()
              elif blobs[i].pixels() > max_size[1]:
                  max_ID[1] = i
                  max_size[1] = blobs[i].pixels()
          return max_ID
      
      def car_run():
          centroid_sum = [0, 0]
          left_center = [-1, -1, -1]  # Store left blob center cx value for calculating left offset angle
          right_center = [-1, -1, -1]  # Store right blob center cx value for calculating right offset angle
          flag_cross = 0  # Flag for intersection
          flag_Stop = 0  # Stop flag
          flag_Wait = [0, 0]  # Wait stop flag
      
          for r in range(3):  # Search for blobs in three regions
              blobs = img.find_blobs(GRAYSCALE_THRESHOLD, roi=ROIS[r][0:4], merge=True, area_threshold=100, margin=3)
              if blobs:
                  max_ID = find_max(blobs)  # Find the largest blob
                  img.draw_rectangle(blobs[max_ID[0]].rect())  # Draw rectangle
                  img.draw_cross(blobs[max_ID[0]].cx(), blobs[max_ID[0]].cy())  # Draw center cross
      
                  if max_ID[1] != -1:  # If there are two blobs, indicating an intersection
                      img.draw_rectangle(blobs[max_ID[1]].rect())
                      flag_cross = 1  # Set intersection flag
                      img.draw_cross(blobs[max_ID[1]].cx(), blobs[max_ID[1]].cy())
      
                      if blobs[max_ID[0]].cx() < blobs[max_ID[1]].cx():
                          left_center[r] = blobs[max_ID[0]].cx()
                          right_center[r] = blobs[max_ID[1]].cx()
                      else:
                          left_center[r] = blobs[max_ID[1]].cx()
                          right_center[r] = blobs[max_ID[0]].cx()
                  else:  # Only one blob
                      if flag_cross == 0:  # No intersection, check for stop line
                          if blobs[max_ID[0]].pixels() > range_stop[r]:
                              flag_Stop = r + 1
                          if blobs[max_ID[0]].w() > range_wait[r]:
                              flag_Wait[0] += 1
                      left_center[r] = right_center[r] = blobs[max_ID[0]].cx()
      
                  centroid_sum[0] += left_center[r] * ROIS[r][4]  # Multiply by weight
                  centroid_sum[1] += right_center[r] * ROIS[r][4]
      
          center_pos = [0, 0]
          center_pos[0] = (centroid_sum[0] / weight_sum)  # Calculate left weighted center
          center_pos[1] = (centroid_sum[1] / weight_sum)  # Calculate right weighted center
      
          if flag_Wait[0] == 2:
              flag_Wait[1] = 1  # Set wait flag
      
          deflection_angle = [0, 0]
          deflection_angle[0] = -math.atan((center_pos[0] - 80) / 60)  # Calculate left offset angle
          deflection_angle[1] = -math.atan((center_pos[1] - 80) / 60)  # Calculate right offset angle
          deflection_angle[0] = math.degrees(deflection_angle[0])  # Convert to degrees
          deflection_angle[1] = math.degrees(deflection_angle[1])
      
          if center_pos[0] == center_pos[1] == 0:
              deflection_angle[1] = deflection_angle[0] = 0  # If no blob found, set angle to 0
      
          A = [float(deflection_angle[0]) + 90, float(deflection_angle[1]) + 90, float(flag_Stop), float(flag_Wait[1])]
          return A
      
      def degrees(radians):
          return (180 * radians) / math.pi
      
      while True:
          clock.tick()
          img = sensor.snapshot().lens_corr(strength=1.8, zoom=1.0)  # Continuously capture images with lens correction
          row_data = [0.0, 0.0, 0.0, 0.0]  # Remove row_data[2]
          row_data[0], row_data[1], row_data[2], row_data[3] = car_run()  # Rearrange indices
          uart_buf = bytearray([int(d) for d in row_data])
          
          # Print row_data to console
          print(row_data)
          
          # Calculate the position to display the text at the bottom, and move it slightly to the right
          text = "{}".format(row_data)
          x = 2  # Adjust the x position as needed to move to the right
          y = img.height() - 10  # Adjust the y position as needed
          
          # Draw the text on the image before rotation
          img.draw_string(x, y, text, color=(0, 0, 255), scale=1)
          
          # Rotate the image by 180 degrees
          img = img.rotation_corr(z_rotation=180)
      
          uart.write(u_start)
          uart.write(uart_buf)
          uart.write(u_over)
          
          lcd.write(img)  # Display the image on the LCD screen with row_data
      


    • 图片上写字,画线,会直接更改图片的像素值,会对后面的识别有干扰。