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



    • # 圆形检测例程
      
      #
      
      # 这个例子展示了如何用Hough变换在图像中找到圆。
      
      # https://en.wikipedia.org/wiki/Circle_Hough_Transform
      
      #
      
      # 请注意,find_circles()方法将只能找到完全在图像内部的圆。圈子之外的
      
      # 图像/ roi被忽略...
      
      
      
      import sensor, image, time
      
      from pid import PID
      
      from pyb import Servo
      
      pan_servo=Servo(1)
      
      title_servo=Servo(2)
      
      red_threshold = (13,39,18,61,6,47)
      
      pan_pid = PID(p=0.17,i=0,imax=90)
      
      title_pid = PID(p=0.15,i=0,imax=90)
      
      def find_max(blobs):
      
          max_size=0
      
          for blob in blobs:
      
              if blob[2]*blob[3] > max_size:
      
                  max_blob = blob
      
                  max_size = blob[2]*blob[3]
      
              return max_blob
      
      sensor.reset()
      
      sensor.set_contrast(1)
      
      sensor.set_gainceiling(16)
      
      sensor.set_pixformat(sensor.GRAYSCALE) # 灰度更快
      
      sensor.set_framesize(sensor.QQVGA)
      
      sensor.skip_frames(time = 2000)
      
      sensor.set_auto_whitebal(False)
      
      clock = time.clock()
      
      while(True):
      
          clock.tick()
      
          #lens_corr(1.8)畸变矫正
      
          img = sensor.snapshot().lens_corr(1.8)
      
          # x_margin 控制所检测的圆的合并。 圆像素为 x_margin 、 y_margin 和
          # r_margin的部分合并。
          # y_margin 控制所检测的圆的合并。 圆像素为 x_margin 、 y_margin 和
          # r_margin 的部分合并。
          # r_margin 控制所检测的圆的合并。 圆像素为 x_margin 、 y_margin 和
          # r_margin 的部分合并。
          # r_min,r_max和r_step控制测试圆的半径。
          # 缩小测试圆半径的数量可以大大提升性能。
          # threshold = 3500比较合适。如果视野中检测到的圆过多,请增大阈值;
          # 相反,如果视野中检测到的圆过少,请减少阈值。
      
          # 判断形状,result=1为圆,2为正方形,3为正三角形
      
          #blobs=img.find_circles(threshold = 3500, x_margin = 10,y_margin = 10, r_margin = 10,r_min = 2, r_max = 100, r_step = 2)
      
          #if blobs:
      
              #max_blob = find_max(blobs)
      
              #pan_error = max_blob[0]-img.width()/2
      
              #title_error = max_blob[1]-img.height()/2
      
              #print("pan_error:", pan_error)
      
              #img.draw_circle(max_blob.x(),max_blob.y(),max_blob.r(),color = (255,0,0))
      
              #img.draw_cross(int(max_blob[0],int(max_blob[1]))
      
              #pan_output=pan_pid.get_pid(pan_error,1)/2
      
              #tilt_output=tilt_pid.get_pid(tilt_error,1)
      
              #print("pan_output",pan_output)
      
              #pan_servo.angle(pan_servo.angle()+pan_output)
      
              #tilt_servo.angle(tilt_servo.angle()-tilt_output)
      
          for c in img.find_circles(threshold = 3500, x_margin = 10, y_margin = 10, r_margin = 10,r_min = 2, r_max = 100, r_step = 2):
      
              d = 2*c.r()
      
              print (d)
      
              if (d!=0):
      
                  #result = 1
      
                  print ('yuan')
      
          #blobs = img.find_rects(threshold = 10000)
      
          #if blobs:
      
           #   max_blob = find_max(blobs)
      
            #  pan_error = max_blob.cx()-img.width()/2
      
             # tilt_error = max_blob.cy()-img.height()/2
      
              #print("pan_error: ", pan_error)
      
      #        img.draw_rectangle(max_blob.rect()) # rect
      
       #       img.draw_cross(max_blob.cx(), max_blob.cy()) # cx, cy
      
        #      pan_output=pan_pid.get_pid(pan_error,1)/2
      
         #     tilt_output=tilt_pid.get_pid(tilt_error,1)
      
          #    print("pan_output",pan_output)
      
           #   pan_servo.angle(pan_servo.angle()+pan_output)
      
            #  tilt_servo.angle(tilt_servo.angle()-tilt_output)
      
          for r in img.find_rects(threshold = 10000):
      
              if (r!=0):
      
                  for l in img.find_line_segments(merge_distance = 0, max_theta_diff = 5):
      
                      s = 0
      
                      s = s + l.length()
      
                      a = s / 4
      
                  print ("square",a)
      
                  #result = 2
      
          for l in img.find_line_segments(merge_distance = 10, max_theta_diff = 10):
      
              img.draw_line(l.line(), color = (255,0,0))
      
              s1 = 0
      
              s1 += l.theta()
      
          s1 = s1 - 180
      
          if s1<110 and s1>1:
      
              z = 0
      
              z = z + line.length()
      
              b = z / 3
      
          blobs = img.find_rects(threshold = 10000)
      
          if blobs:
      
              max_blob = find_max(blobs)
      
              pan_error = max_blob[0]-img.width()/2
      
              tilt_error = max_blob[1]-img.height()/2
      
              print("pan_error: ", pan_error)
      
              img.draw_rectangle(max_blob.rect()) # rect
      
              img.draw_cross(max_blob.x(), max_blob.y()) # cx, cy
      
              pan_output=pan_pid.get_pid(pan_error,1)/2
      
              tilt_output=tilt_pid.get_pid(tilt_error,1)
      
              print("pan_output",pan_output)
      
              pan_servo.angle(pan_servo.angle()+pan_output)
      
              tilt_servo.angle(tilt_servo.angle()-tilt_output)
      
          result = 3
      
      #测量距离
      
      #计算边长
      
      # 圆形检测例程
      
      #
      
      # 这个例子展示了如何用Hough变换在图像中找到圆。
      
      # https://en.wikipedia.org/wiki/Circle_Hough_Transform
      
      #
      
      # 请注意,find_circles()方法将只能找到完全在图像内部的圆。圈子之外的
      
      # 图像/ roi被忽略...
      
      
      
      import sensor, image, time
      
      
      
      sensor.reset()
      
      sensor.set_pixformat(sensor.RGB565) # 灰度更快
      
      sensor.set_framesize(sensor.QQVGA)
      
      sensor.skip_frames(time = 2000)
      
      clock = time.clock()
      
      
      
      while(True):
      
          clock.tick()
      
      
      
          #lens_corr(1.8)畸变矫正
      
          img = sensor.snapshot().lens_corr(1.8)
      
      
      
          # Circle对象有四个值: x, y, r (半径), 和 magnitude。
      
          # magnitude是检测圆的强度。越高越好
      
      
      
          # roi 是一个用以复制的矩形的感兴趣区域(x, y, w, h)。如果未指定,
      
          # ROI 即图像矩形。操作范围仅限于roi区域内的像素。
      
      
      
          # x_stride 是霍夫变换时需要跳过的x像素的数量。若已知圆较大,可增加
      
          # x_stride 。
      
      
      
          # y_stride 是霍夫变换时需要跳过的y像素的数量。若已知直线较大,可增加
      
          # y_stride 。
      
      
      
          # threshold 控制从霍夫变换中监测到的圆。只返回大于或等于阈值的圆。
      
          # 应用程序的阈值正确值取决于图像。注意:一条圆的大小是组成圆所有
      
          # 索贝尔滤波像素大小的总和。
      
      
      
          # x_margin 控制所检测的圆的合并。 圆像素为 x_margin 、 y_margin 和
      
          # r_margin的部分合并。
      
      
      
          # y_margin 控制所检测的圆的合并。 圆像素为 x_margin 、 y_margin 和
      
          # r_margin 的部分合并。
      
      
      
          # r_margin 控制所检测的圆的合并。 圆像素为 x_margin 、 y_margin 和
      
          # r_margin 的部分合并。
      
      
      
          # r_min,r_max和r_step控制测试圆的半径。
      
          # 缩小测试圆半径的数量可以大大提升性能。
      
          # threshold = 3500比较合适。如果视野中检测到的圆过多,请增大阈值;
      
          # 相反,如果视野中检测到的圆过少,请减少阈值。
      
          # 判断形状,result=1为圆,2为正方形,3为正三角形
      
          for c in img.find_circles(threshold = 3500, x_margin = 10, y_margin = 10, r_margin = 10,r_min = 2, r_max = 100, r_step = 2):
      
              img.draw_circle(c.x(), c.y(), c.r(), color = (255, 0, 0))
      
              print(c)
      
              d = 2*c.r()
      
          if (d!=0):
      
              result = 1
      
          #画出特征点
          def draw_keypoints(img, kpts):
      
              if kpts:
      
                  print(kpts)
      
                  img.draw_keypoints(kpts)
      
                  img = sensor.snapshot()
      
                  time.sleep(1000)
      
          #kpts1 = None
          #kpts1保存目标物体的特征,可以从文件导入特征,但是不建议这么做。
          kpts1 = image.load_descriptor("/desc1.orb")
      
          kpts2 = image.load_descriptor("/desc2.orb")
      
          kpts3 = image.load_descriptor("/desc3.orb")
          #img = sensor.snapshot()
          #draw_keypoints(img, kpts1)
      
          clock = time.clock()
      
          while (True):
      
              clock.tick()
      
              img = sensor.snapshot()
      
              if (kpts1 == None):
      
                  kpts1 = img.find_keypoints(max_keypoints=150, threshold=10, scale_factor=1.2)
      
                  draw_keypoints(img, kpts1)
      
              else:
                #当与最开始的目标特征进行匹配时,默认设置normalized=True,只匹配目标特征的一种大小。
                # NOTE: When extracting keypoints to match the first descriptor, we use normalized=True to extract
                # keypoints from the first scale only, which will match one of the scales in the first descriptor.
                kpts0 = img.find_keypoints(max_keypoints=150, threshold=10, normalized=True)
                #如果检测到特征物体
                if (kpts0):
                    #匹配当前找到的特征和最初的目标特征的相似度
                    match = image.match_descriptor(kpts1, kpts0, threshold=85)
                    #image.match_descriptor(descritor0, descriptor1, threshold=70, filter_outliers=False)。本函数返回kptmatch对象。
                    #threshold阈值设置匹配的准确度,用来过滤掉有歧义的匹配。这个值越小,准确度越高。阈值范围0~100,默认70
                    #filter_outliers默认关闭。
      
                    #match.count()是kpt1和kpt2的匹配的近似特征点数目。
                    #如果大于10,证明两个特征相似,匹配成功。
                    if (match.count()>10):
                        # If we have at least n "good matches"
                        # Draw bounding rectangle and cross.
                        #在匹配到的目标特征中心画十字和矩形框。
                        img.draw_rectangle(match.rect())
      
                        img.draw_cross(match.cx(), match.cy(), size=10)
      
                    #match.theta()是匹配到的特征物体相对目标物体的旋转角度。
                    print(kpts0, "matched:%d dt:%d"%(match.count(), match.theta()))
                     #不建议draw_keypoints画出特征角点。
                     # NOTE: uncomment if you want to draw the keypoints
                     #img.draw_keypoints(kpts2, size=KEYPOINTS_SIZE, matched=True)
      
              if (kpts2 == None):
      
                  kpts2 = img.find_keypoints(max_keypoints=150, threshold=10, scale_factor=1.2)
      
                  draw_keypoints(img, kpts2)
      
              else:
      
                  kpts0 = img.find_keypoints(max_keypoints=150, threshold=10, normalized=True)
      
              if(kpts0):
      
                  match = image.match_descriptor(kpts2, kpts0, threshold=85)
      
                  if (match.count()>10):
      
                      img.draw_rectangle(match.rect())
      
                      img.draw_cross(match.cx(), match.cy(), size=10)
      
                  print(kpts0, "matched:%d dt:%d"%(match.count(), match.theta()))
      
              if (kpts3 == None):
      
                  kpts3 = img.find_keypoints(max_keypoints=150, threshold=10, scale_factor=1.2)
      
                  draw_keypoints(img, kpts3)
      
              else:
      
                  kpts0 = img.find_keypoints(max_keypoints=150, threshold=10, normalized=True)
      
              if(kpts0):
      
                  match = image.match_descriptor(kpts3, kpts0, threshold=85)
      
                  if (match.count()>10):
      
                      img.draw_rectangle(match.rect())
      
                      img.draw_cross(match.cx(), match.cy(), size=10)
      
                  print(kpts0, "matched:%d dt:%d"%(match.count(), match.theta()))
      
          for r in img.find_rects(threshold = 10000):
      
              img.draw_rectangle(r.rect(), color = (255, 0, 0))
      
              print(r)
      
              if (r!=0):
      
                  for l in img.find_line_segments(merge_distance = 0, max_theta_diff = 5):
      
                      s = s + line.length()
      
                      a = s / 4
      
                  result = 2
      
          for l in img.find_line_segments(merge_distance = 10, max_theta_diff = 10):
      
              img.draw_line(l.line(), color = (255,0,0))
      
              sum += l.theta()
      
          sum-=180
      
          if (sum<110 and sum>1):
      
              z = z + line.length()
      
          b = z / 3
      
          result = 3
      
      #测量距离
      
      #计算边长
      
      
      

      第200行 显示tilt_pid没定义
      第172行 显示S1没定义
      是什么问题呢



    • 1,第31行是title_pid。和tilt_pid名字不一样。

      2,如果164行没有找到线段,s1就不会设置为0,s1就未定义。