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



    • # Find Rects Example
      #
      # 这个例子展示了如何使用april标签代码中的四元检测代码在图像中找到矩形。 四元检测算法以非常稳健的方式检测矩形,并且比基于Hough变换的方法好得多。 例如,即使镜头失真导致这些矩形看起来弯曲,它仍然可以检测到矩形。 圆角矩形是没有问题的!
      # (但是,这个代码也会检测小半径的圆)...
      
      import sensor, image, time
      from pyb import UART
      from machine import LED
      
      
      dark_exp=15000
      
      
      sensor.reset()
      sensor.set_pixformat(sensor.RGB565) # 灰度更快(160x120 max on OpenMV-M7)
      #sensor.set_pixformat(sensor.GRAYSCALE)
      sensor.set_framesize(sensor.QQVGA)
      sensor.skip_frames(time = 2000)
      sensor.set_auto_gain(False)  # 关闭自动自动增益
      sensor.set_auto_whitebal(False,(0,0,0))  # 关闭白平衡 第二个参数代表颜色
      sensor.set_brightness(1500) # 设置图像亮度 越大越亮
      sensor.set_auto_exposure(False,10000)#设置曝光时间
      
      
      #定义计算两点距离的函数
      def euler_distance(x1,y1,x2,y2):
          return ((x1-x2)**2+(y1-y2)**2)**(1/2)
      
      
      clock = time.clock()
      uart = UART(3,115200)#串口通信,波特率为115200
      
      thresholds_gray = [(70, 255)] # grayscale thresholds
      thresholds_rgb = [(20, 100, 20, 127, -128, 127), # generic_red_thresholds//3
                    (5, 91, -128, -45, -7, 127), # generic_green_thresholds//4
                    (0, 100, -96, 127, -128, -24)] # generic_blue_thresholds//6
      threshold_black=[(0,25,-10,10,-10,10)] #暂时没用
      
      threshold_test=(100, 42, -58, 127, -21, 40)
      
      #边缘检测卷积核还是锐化卷积核。。强调水平和垂直边缘。。的锐化
      kernel_size = 1 # kernel width = (size*2)+1, kernel height = (size*2)+1
      kernel = [-1, -1, -1,\
                -1, +8, -1,\
                -1, -1, -1]
      thresholds_gray = [(70, 255)] # grayscale thresholds
      
      
      recognize_rect_flag=0
      recognize_red_pen_flag=0
      #sensor.set_brightness(100) # 设置图像亮度 越大越亮
      #sensor.set_auto_exposure(False,14000)
      recognize_green_pen_flag=0  #暂时没用
      
      rect_point1_list=[] #识别多次,内部是坐标列表
      rect_point2_list=[]
      rect_point3_list=[]
      rect_point4_list=[]
      avg_rect_point1=[0,0]
      avg_rect_point2=[0,0]
      avg_rect_point3=[0,0]
      avg_rect_point4=[0,0]
      recognize_rect_count=0  #识别计数
      
      recognize_timeout_orign=10
      recognize_timeout=10  #几帧没识别到转换阈值
      
      while(True):
          clock.tick()
          img = sensor.snapshot()#.lens_corr(1.8)
      
          if (uart.any()):
              recv_data =(uart.read())
              print(recv_data)
              if (recv_data==b'r'):
                  recognize_rect_flag = 1
                  recognize_red_pen_flag=0
              if(recv_data==b'q'):
                  recognize_red_pen_flag=1
                  recognize_rect_flag=0
                  #sensor.set_brightness(100) # 设置图像亮度 越大越亮
                  #sensor.set_auto_exposure(False,1000)
              if(recv_data==b'p'):#恢复初始状态
                  sensor.set_auto_exposure(False,10000)
                  recognize_rect_flag=0
                  recognize_red_pen_flag=0
                  recognize_green_pen_flag=0  #暂时没用
                  rect_point1_list=[] #识别多次,内部是坐标列表
                  rect_point2_list=[]
                  rect_point3_list=[]
                  rect_point4_list=[]
                  avg_rect_point1=[0,0]
                  avg_rect_point2=[0,0]
                  avg_rect_point3=[0,0]
                  avg_rect_point4=[0,0]
                  recognize_rect_count=0  #识别计数
      
          if recognize_rect_flag:
              #print("test")
              for r in img.find_rects(threshold = 5000):
                  corners=r.corners()
                  length1=euler_distance(corners[0][0],corners[0][1],corners[1][0],corners[1][1])  #左下 右下 底边
                  length2=euler_distance(corners[1][0],corners[1][1],corners[2][0],corners[2][1])  #右下 右上 右侧边
                  length3=euler_distance(corners[2][0],corners[2][1],corners[3][0],corners[3][1])  #右上 左上 顶边
                  length4=euler_distance(corners[3][0],corners[3][1],corners[0][0],corners[0][1])  #左上 左下 左侧边
      
                  long_edge=1
                  short_edge=1
                  #判断长短边
                  if length1>length2:
                      long_edge=length1
                      short_edge=length2
                  else:
                      long_edge=length2
                      short_edge=length1
      
                  strange_flag=0 #判断是不是奇形怪状
                  if(length1==0 or length2==0 or length3==0 or length4==0):#某一边为0
                      strange_flag=1
                  elif((length1/length3)>0.85 and (length1/length3)<1.15 and (length2/length4)>0.85 and (length2/length4)<1.15):
                      strange_flag=0  #对边长度误差在0.15比例范围以内
                  else:
                      strange_flag=1
                  # 最终滤波
                  if strange_flag==0 and long_edge>25 and short_edge>25 and long_edge/short_edge<1.6: #and x>20 and x<140 and y>15 and y<105 and w_h>0.4 and w_h<1.6 and height>20 and width>20
                      img.draw_rectangle(r.rect(),color=(255,0,0))
                      for p in r.corners():
                          img.draw_circle(p[0], p[1], 5, color = (0, 255, 0))
                          #img.draw_cross(p[0], p[1])
      
                      #img.save("./img{}.jpg".format(len(rect_point1_list)),quality=80)
                      #开始存入列表
                      recognize_rect_count+=1  #计数 并将每次所得坐标加入列表
                      rect_point1_list.append(corners[0])
                      rect_point2_list.append(corners[1])
                      rect_point3_list.append(corners[2])
                      rect_point4_list.append(corners[3])
      
                      print (corners)
      
                      if(recognize_rect_count>=5):#停止识别  五次
                          for i in range(recognize_rect_count):   #求各个坐标的平均值
                              avg_rect_point1[0]+=rect_point1_list[i][0]
                              avg_rect_point1[1]+=rect_point1_list[i][1]
                              avg_rect_point2[0]+=rect_point2_list[i][0]
                              avg_rect_point2[1]+=rect_point2_list[i][1]
                              avg_rect_point3[0]+=rect_point3_list[i][0]
                              avg_rect_point3[1]+=rect_point3_list[i][1]
                              avg_rect_point4[0]+=rect_point4_list[i][0]
                              avg_rect_point4[1]+=rect_point4_list[i][1]
      
                          avg_rect_point1[0]=(avg_rect_point1[0]/recognize_rect_count)
                          avg_rect_point1[1]=(avg_rect_point1[1]/recognize_rect_count)
                          avg_rect_point2[0]=(avg_rect_point2[0]/recognize_rect_count)
                          avg_rect_point2[1]=(avg_rect_point2[1]/recognize_rect_count)
                          avg_rect_point3[0]=(avg_rect_point3[0]/recognize_rect_count)
                          avg_rect_point3[1]=(avg_rect_point3[1]/recognize_rect_count)
                          avg_rect_point4[0]=(avg_rect_point4[0]/recognize_rect_count)
                          avg_rect_point4[1]=(avg_rect_point4[1]/recognize_rect_count)
      
      
                          #矩形旋转一定角度会改变四个角点坐标的返回顺序,有顺时针和逆时针两种//找最大2个判断法 //左上是1号//顺时针排列
      
                          ############
                          newdata=[[0,0],[0,0],[0,0],[0,0]]
                          data_dict={1:(avg_rect_point1[0],avg_rect_point1[1]),2:(avg_rect_point2[0],avg_rect_point2[1]),3:(avg_rect_point3[0],avg_rect_point3[1]),4:(avg_rect_point4[0],avg_rect_point4[1])}
      
                          one_sort=sorted(data_dict.items(),key = lambda x: x[1][0])   #按x坐标大小排序,返回列表
                          #data_dict.items():以列表的形式返回可遍历的元组数组;lambda x:定义x的值为x[1][0]
      
                          #偏左的两个点
                          first2=[]
                          first2.append(one_sort[0])
                          first2.append(one_sort[1])
      
                          #偏右的两个点
                          second2=[]#=[]  #?!?
                          second2.append(one_sort[2])
                          second2.append(one_sort[3])
      
                          # 分别提取first2和second2中角点的索引和坐标,准备进行y坐标的排序
                          list_a = [first2[0][0]]+[first2[1][0]]
                          list_b = [first2[0][1]]+[first2[1][1]]
                          first2_dict = dict(zip(list_a, list_b)) # 将坐标打包成元组,再返回元组的列表,再将列表转成字典
      
                          list_a = [second2[0][0]]+[second2[1][0]]
                          list_b = [second2[0][1]]+[second2[1][1]]
                          second2_dict = dict(zip(list_a, list_b))
      
                          first2_sort=sorted(first2_dict.items(),key = lambda x: x[1][1],reverse=True) #y坐标 逆序排序  
                          second2_sort=sorted(second2_dict.items(),key = lambda x: x[1][1]) #顺序排序  
      
                          all_sort=first2_sort+second2_sort  #无论任何角度摆放矩形都顺时针发送角点坐标
      
                          newdata[0][0]=all_sort[0][1][0]
                          newdata[0][1]=all_sort[0][1][1]
                          newdata[1][0]=all_sort[1][1][0]
                          newdata[1][1]=all_sort[1][1][1]
                          newdata[2][0]=all_sort[2][1][0]
                          newdata[2][1]=all_sort[2][1][1]
                          newdata[3][0]=all_sort[3][1][0]
                          newdata[3][1]=all_sort[3][1][1]
                          ########
                          avg_rect_point1[0]=newdata[0][0]
                          avg_rect_point1[1]=newdata[0][1]
                          avg_rect_point2[0]=newdata[1][0]
                          avg_rect_point2[1]=newdata[1][1]
                          avg_rect_point3[0]=newdata[2][0]
                          avg_rect_point3[1]=newdata[2][1]
                          avg_rect_point4[0]=newdata[3][0]
                          avg_rect_point4[1]=newdata[3][1]
                          print("均值后点1:",avg_rect_point1[0],",",avg_rect_point1[1],"点2:",avg_rect_point2[0],",",avg_rect_point2[1],"点3:",avg_rect_point3[0],",",avg_rect_point3[1],"点4:",avg_rect_point4[0],",",avg_rect_point4[1])
      
                          #看看能不能用   #?
                          if(avg_rect_point1[1]>=89):
                              avg_rect_point1[1]-=1.5
                          if(avg_rect_point2[1]>=89):
                              avg_rect_point2[1]-=1.5
                          if(avg_rect_point3[1]>=89):
                              avg_rect_point3[1]-=1.5
                          if(avg_rect_point4[1]>=89):
                              avg_rect_point4[1]-=1.5
      
                          use_dev=1
                          if(use_dev):
      
                              #由于都是外框,所以设置往里偏像素
                              dev_k=0.03 #偏移系数,总的像素差乘它
                              is_reverse_xy=0 #xy偏移计算方向相反
                              is_use_single=0  #只是正常加一个固定数
      
                              #分别计算对角点x、y坐标之差
                              delta1_x=avg_rect_point3[0]-avg_rect_point1[0]
                              delta1_y=avg_rect_point3[1]-avg_rect_point1[1]
      
                              delta2_x=avg_rect_point4[0]-avg_rect_point2[0]
                              delta2_y=avg_rect_point4[1]-avg_rect_point2[1]
      
                              ############################################################
                              #以下代码不起作用(bug、?
                              if is_reverse_xy:#真  x 和 y 的偏移方向相反
                                  delta1_x=(round)(delta1_x*abs(delta1_y)/abs(delta1_x))
                                  delta1_y=(round)(delta1_y*abs(delta1_x)/abs(delta1_y))
                                  delta2_x=(round)(delta2_x*abs(delta2_y)/abs(delta2_x))
                                  delta2_y=(round)(delta2_y*abs(delta2_x)/abs(delta2_y))
      
                              if is_use_single:
                                  dev_k=1#?
                                  if delta1_x>0 :
                                      delta1_x=2
                                  else:
                                      delta1_x=-2
                                  if delta1_y>0 :
                                      delta1_y=2
                                  else:
                                      delta1_y=-2
                                  if delta2_x>0 :
                                      delta2_x=2
                                  else:
                                      delta2_x=-2
                                  if delta2_y>0 :
                                      delta2_y=2
                                  else:
                                      delta2_y=-2
      
                              #############################################################
                              avg_rect_point1[0]+=dev_k*delta1_x
                              avg_rect_point1[1]+=dev_k*delta1_y
                              avg_rect_point3[0]-=dev_k*delta1_x 
                              avg_rect_point3[1]-=dev_k*delta1_y 
      
                              avg_rect_point2[0]+=dev_k*delta2_x #-
                              avg_rect_point2[1]+=dev_k*delta2_y
                              avg_rect_point4[0]-=dev_k*delta2_x #+仅某一情况
                              avg_rect_point4[1]-=dev_k*delta2_y
      
                              #############################################################3
                      
                          avg_rect_point1[0]=(round)(avg_rect_point1[0])
                          avg_rect_point1[1]=(round)(avg_rect_point1[1])
                          avg_rect_point2[0]=(round)(avg_rect_point2[0])
                          avg_rect_point2[1]=(round)(avg_rect_point2[1])
                          avg_rect_point3[0]=(round)(avg_rect_point3[0])
                          avg_rect_point3[1]=(round)(avg_rect_point3[1])
                          avg_rect_point4[0]=(round)(avg_rect_point4[0])
                          avg_rect_point4[1]=(round)(avg_rect_point4[1])
      
      
      
      
      
                          print("加偏移后点1:",avg_rect_point1[0],",",avg_rect_point1[1],"点2:",avg_rect_point2[0],",",avg_rect_point2[1],"点3:",avg_rect_point3[0],",",avg_rect_point3[1],"点4:",avg_rect_point4[0],",",avg_rect_point4[1])
                          img.draw_cross(avg_rect_point1[0], avg_rect_point1[1])
                          img.draw_cross(avg_rect_point2[0], avg_rect_point2[1])
                          img.draw_cross(avg_rect_point3[0], avg_rect_point3[1])
                          img.draw_cross(avg_rect_point4[0], avg_rect_point4[1])
      
                          img.save("./img{}.jpg".format(len(rect_point1_list)),quality=80)#保存图像
      
                          uart.write(bytearray([0xA5]))
                          uart.write(bytearray([avg_rect_point1[0]]))
                          uart.write(bytearray([avg_rect_point1[1]]))
                          uart.write(bytearray([avg_rect_point2[0]]))
                          uart.write(bytearray([avg_rect_point2[1]]))
                          uart.write(bytearray([avg_rect_point3[0]]))
                          uart.write(bytearray([avg_rect_point3[1]]))
                          uart.write(bytearray([avg_rect_point4[0]]))
                          uart.write(bytearray([avg_rect_point4[1]]))
      
                          led.on()
                          time.sleep_ms(500)
                          led.off()
      
                          ##直接转换成暗色
                          #sensor.set_brightness(1000) # 设置图像亮度 越大越亮
                          sensor.set_auto_exposure(False,dark_exp)
      
                          #置回标志位
                          recognize_rect_flag=0
      
                          rect_point1_list=[]
                          rect_point2_list=[]
                          rect_point3_list=[]
                          rect_point4_list=[]
                          avg_rect_point1=[0,0]
                          avg_rect_point2=[0,0]
                          avg_rect_point3=[0,0]
                          avg_rect_point4=[0,0]
                          recognize_rect_count=0
                          break
      
          if recognize_red_pen_flag:
              max_area=0
              max_index=0
              get_blob=0
      
              blobs = img.find_blobs([thresholds_rgb[0]],pixels_threshold=1, area_threshold=1, merge=True)  #
              for i in range(len(blobs)):
                  get_blob=1
                  ####
                  #recognize_timeout=recognize_timeout_orign
                  ###
      
                  if blobs[i].area()>max_area:
                      max_area=blobs[i].area()
                      max_index=i
              if get_blob:
                  r=blobs[max_index]
                  img.draw_rectangle(r.rect())
                  img.draw_cross(r.cx(), r.cy())
                  #img.draw_keypoints([(r.cx(), r.cy(), int(math.degrees(r.rotation())))], size=20)
                  #print(r.cx(), r.cy())
                  uart.write(bytearray([0xAA]))
                  uart.write(bytearray([r.cx()]))
                  uart.write(bytearray([r.cy()]))
      
              ##########超时识别绿色
              #if(recognize_timeout==0):
                  #print("timeout")
                  #max_area=0
                  #max_index=0
                  #get_blob=0
                  #blobs = img.find_blobs([thresholds_rgb[0],thresholds_rgb[1]],pixels_threshold=1, area_threshold=1, merge=True)  #
                  #for i in range(len(blobs)):
                      #get_blob=1
      
                      #if blobs[i].area()>max_area:
                          #max_area=blobs[i].area()
                          #max_index=i
                  #if get_blob:
                      #r=blobs[max_index]
                      #img.draw_rectangle(r.rect())
                      #img.draw_cross(r.cx(), r.cy())
                      ##img.draw_keypoints([(r.cx(), r.cy(), int(math.degrees(r.rotation())))], size=20)
                      ##print(r.cx(), r.cy())
                      #uart.write(bytearray([0xAA]))
                      #uart.write(bytearray([r.cx()]))
                      #uart.write(bytearray([r.cy()]))
      
      
              #if(get_blob==0 and recognize_timeout>0):
                  #recognize_timeout-=1
              #print(clock.fps())
      

      0_1715263720343_6d2d1ea6-090b-4416-a66c-085cbbc50381-image.png
      找了很多地方设置曝光时间都是这么写的,为什么报错了