• 免费好用的星瞳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
      from pyb import LED,Timer,Pin
      #------------------------求矩形轮廓的上边直线
      def fit_line(x,y):#最小二乘法拟合
          NX=len(x)
          NY=len(y)
          if NX<2:return('N')
          sxy=sxx=0
          for i in range(NX):
              sxy+=x[i]*y[i]
              sxx+=x[i]*x[i]
          sx=sum(x)
          sy=sum(y)
          T=sx**2-NX*sxx#防备分母是0
          if abs(T)<1e-6:#斜率无穷大,x=sx/NX
              return('N')
          else:
              k=(sx*sy-NX*sxy)/T#斜率
              b=(sx*sxy-sy*sxx)/T#截距
              # for i in range(NX):
                  # if i==0 or i==NX-1:#头尾偏差允许大一些
                      # if x[i]*k+b-y[i]>2*GAP:
                          # err+=x[i]*k+b-y[i]
                          # break
                  # else:
                      # if x[i]*k+b-y[i]>GAP:
                          # err+=x[i]*k+b-y[i]
                          # break
              #return([k,b,err])
              return([k,b])
      #------------------------求矩形轮廓的上边直线
      
      def deviation(x,y,k,b):
          NX=len(x)
          NY=len(y)
          if NX<2:
              return('N')
          else:
              err = 0
              for i in range(NX):
                  if i==0 or i==NX-1:#头尾偏差允许大一些
                      if x[i]*k+b-y[i]>2*GAP and x[i]*k+b-y[i]<55:#剔除袋外扰动
                          #err+=x[i]*k+b-y[i]
                          err=x[i]*k+b-y[i]
                          break
                  else:
                      if x[i]*k+b-y[i]>GAP and x[i]*k+b-y[i]<55:
                          #err+=x[i]*k+b-y[i]
                          err=x[i]*k+b-y[i]
                          break
              return(err)
      
      W_W=(640)#定义显示窗口宽度
      W_H=(240)#定义显示窗口高度
      GAP=8#边缘与袋腔之间的间隙,在此间隙内不检测
      Col=32 #屏幕纵向平均分成Col个块,可以使得图像分割精细
      p_out = Pin('P7', Pin.OUT_PP)#设置p_out为输出引脚,点亮发光二极管
      p_out.high()#设置p_out引脚为高
      
      
      sensor.reset()
      sensor.set_pixformat(sensor.RGB565) # grayscale is faster
      sensor.set_framesize(sensor.VGA)#VGA: 640x480
      sensor.set_windowing((W_W,W_H)) # 设置屏幕有效大小W_W*W_H
      sensor.skip_frames(time = 3000) #在3秒内,适应光照环境(放大倍数,白平衡)
      sensor.set_auto_gain(False) # 关闭放大倍数自动调节功能
      sensor.set_auto_whitebal(False) # 关闭白平衡自动调节功能
      p_out.low()#设置p_out引脚为低,指示白平衡和放大倍数学习完成,可以开始工作。
      
      #brown_thresholds =[(10,70,15,100,20,100)]#大粗块棕色
      brown_thresholds =[(35, 70, -5, 45, 20, 60)]
      light_brown=[(10,50,15,50,20,80)]#淡棕色
          #棕色的初始值很重要,影响能否准确分割出大棕色块区域,此值是反复试验得到,不一定最优。
      def tick(timer):#时间中断函数,定时熄灭LED
          p_out.low()#设置p_out引脚为低
          #LED(3).off()
      tim = Timer(4, freq=2)   # create a timer object using timer 4 - trigger at 0.25Hz
      tim.callback(tick)          # set the callback to our tick function
      
      clock = time.clock()
      
      while(True):
          clock.tick()
          img = sensor.snapshot()#摄取一幅图像
          BY=[]#棕色块y坐标暂存
          BX=[]#棕色块x坐标暂存
          BH=[]#棕色块高度暂存
          BW=[]#棕色块宽度暂存
          ###################################新子集
          BYY=[]
          BXX=[]
          BHH=[]
          BWW=[]
          #########################################
          BY1=[]#棕色块y坐标暂存
          BX1=[]#棕色块x坐标暂存
          BH1=[]#棕色块高度暂存
          BW1=[]#棕色块宽度暂存
          Y_Thresholds=[]#自校正阈值暂存
          for i in range(Col):#处理屏幕各纵向块
              IMG=img.find_blobs(brown_thresholds,pixels_threshold=50,area_threshold=20,merge=True,\
                  roi=[i*W_W//Col,0,W_W//Col,W_H],margin=W_H,x_stride=1,y_stride=1)#找大块棕色
              if IMG and IMG[0].w()>640/2/Col:
                  BY.append(IMG[0].y())
                  BX.append(IMG[0].x())
                  BH.append(IMG[0].h())
                  BW.append(IMG[0].w())
                  img.draw_rectangle([BX[-1],BY[-1],BW[-1],BH[-1]],color=(255,0,0))#画大棕色块的红色矩形框39
          if len(BY)>=5 and min(BY)>GAP and max(BY)<W_H-2*GAP:#要至少检测到5个色块
              SROI=[BX[1],max(BY),BX[-1]-BX[1],W_H-max(BY)]
              stat=img.get_statistics(roi=SROI)#获得像素的统计量
              b_thresholds=[(stat.l_lq(),stat.l_max(),10,stat.a_max(),10,stat.b_max())]#自校正阈值
              print(b_thresholds)#自校正之后的阈值
              for i in range(Col):#处理屏幕各纵向块
                  IMG=img.find_blobs(b_thresholds,pixels_threshold=50,area_threshold=20,merge=True,\
                      roi=[i*W_W//Col,0,W_W//Col,W_H],margin=W_H,x_stride=1,y_stride=1)#找大块棕色
                  if IMG and IMG[0].w()>640/2/Col:
                      BY1.append(IMG[0].y())
                      BX1.append(IMG[0].x())
                      BH1.append(IMG[0].h())
                      BW1.append(IMG[0].w())
              MinV=min(BY1)#y的最小值
              MinI=BY1.index(MinV)#y的最小值的索引
      
              if MinI!=len(BX1)-1 and MinI!=0:#y的最小值在中间挑选长边侧
                  P1=fit_line(BX1[1:MinI+2],BY1[0:MinI+1])#寻找y的最小值左侧直线参数纵坐标不变,横坐标平移
                  P2=fit_line(BX1[MinI:],BY1[MinI:])#寻找y的最小值右侧直线参数
                  if abs(P1[0]*P2[0]+1)<0.7:#直角在中间判断垂直情况,0.7为可调参数
                      if MinI<len(BX)/2:
                          BX1=BX1[MinI:]
                          BY1=BY1[MinI:]
                          BW1=BW1[MinI:]
                          BH1=BH1[MinI:]
                      else:
                          BX1=BX1[:MinI+1]
                          BY1=BY1[:MinI+1]
                          BW1=BW1[:MinI+1]
                          BH1=BH1[:MinI+1]
              P=fit_line(BX1,BY1)#这时候拟合了所有点
              print(len(BX1))
              TX=BX1[-1]+BW1[-1]
              img.draw_line(BX1[0],round(BX1[0]*P[0]+P[1]),\
              TX,round(TX*P[0]+P[1]),color=[0,0,255])#拟合蓝线
              NXX=len(BX1)
              if NXX>2:
                for i in range(NXX):
                  if i==0 or i==NXX-1:#头尾偏差允许大一些
                      AbsDev = BX1[i]*P[0]+P[1]-BY1[i]
                      if abs(AbsDev)<round(0.5*GAP):##########此处参数可调小于此参数保留
                          BYY.append(BY1[i])
                          BXX.append(BX1[i])
                          BHH.append(BH1[i])
                          BWW.append(BW1[i])
                      #   break
                  else:
                      Absdev1 = BX1[i]*P[0]+P[1]-BY1[i]
                      if abs(Absdev1)<round(0.2*GAP):
                          BYY.append(BY1[i])
                          BXX.append(BX1[i])
                          BHH.append(BH1[i])
                          BWW.append(BW1[i])
                      #   break buzhida
              print(len(BXX))
              PR=fit_line(BXX,BYY)#重新拟合一条直线返回新的k,b
              print(PR)
              if len(PR)>1:
                  TXX=BXX[-1]+BWW[-1]
                  img.draw_line(BXX[0],round(BXX[0]*PR[0]+PR[1]),\
                  TXX,round(TXX*PR[0]+PR[1]),color=[0,255,0])#绿线拟合
                  dev=deviation(BX1,BY1,PR[0],PR[1])
                  print(dev)
                  if dev>GAP:
                      p_out.high()#设置p_out引脚为高
                      print(P)
                      continue
      #        if dev>GAP:
      #            p_out.high()#设置p_out引脚为高
      #            print(P)
      #            continue
      
              #stat=img.get_statistics(roi=[BX[1],max(BY)+GAP,BX[-2]-BX[1],max(W_H-max(BY)-GAP,1)])#获得像素的统计量3993
              #b_thresholds=[stat.l_lq(),stat.l_max(),10,stat.a_max(),10,stat.b_max()]#自校正阈值
      #        for i in range((BX[-1]+BW[-1]-BX[0])//8+1):#棕色块的宽度除以
                  #img.draw_line(BX[0]+8*i,round(max(P[0]*(BX[0]+4*i)+P[1]-60,0)),BX[0]+4*i,round(P[0]*(BX[0]+4*i)+P[1]),color=[0,255,0])
      #            ey=round(P[0]*(BX[0]+8*i)+P[1])
      #            eyy=max(ey-50,0)
      #            if round(ey-eyy-1.5*GAP)>0:
      #                #ROI=[BX[0]+8*i,eyy,8,round(ey-eyy-1.5*GAP)]
      #                ROI=[min(BX[0]+8*i,W_W-9),eyy,8,round(ey-eyy)]
      #                IMG1=img.find_blobs(light_brown,pixels_threshold=1,area_threshold=1,merge=True,\
      #                roi=ROI,margin=W_H,x_stride=1,y_stride=1)#找大块棕色
      #                if IMG1:
      #                    #img.draw_rectangle(ROI,color=(0,255,0),fill=True)#找到的精细黄色的矩形区域(绿色)
      #                    p_out.high()#设置p_out引脚为高
      #                    continue
      
          print(clock.fps())
      
      
      

      0_1621305404903_1.png



    • 硬件是什么版本的?