• OpenMV VSCode 扩展发布了,在插件市场直接搜索OpenMV就可以安装
  • 如果有产品硬件故障问题,比如无法开机,论坛很难解决。可以直接找售后维修
  • 发帖子之前,请确认看过所有的视频教程,https://singtown.com/learn/ 和所有的上手教程http://book.openmv.cc/
  • 每一个新的提问,单独发一个新帖子
  • 帖子需要目的,你要做什么?
  • 如果涉及代码,需要报错提示全部代码文本,请注意不要贴代码图片
  • 必看:玩转星瞳论坛了解一下图片上传,代码格式等问题。
  • 为什么IDE可以正常运行而脱机后不能正常运行而闪烁白灯,再连接到电脑上时候会有一个内存管理错误的日志



    • # Face recognition with LBP descriptors.
      # See Timo Ahonen's "Face Recognition with Local Binary Patterns".
      #
      # Before running the example:
      # 1) Download the AT&T faces database http://www.cl.cam.ac.uk/Research/DTG/attarchive/pub/data/att_faces.zip
      # 2) Exract and copy the orl_faces directory to the SD card root.
      
      
      import sensor, time, image ,display
      import random
      import pyb
      import os
      import ustruct
      from pyb import UART
      from pyb import Pin, Timer
      sensor.reset() # Initialize the camera sensor.
      sensor.set_pixformat(sensor.GRAYSCALE) # or sensor.GRAYSCALE
      sensor.set_framesize(sensor.QQVGA2) # or sensor.QQVGA (or others)
      sensor.set_windowing((128,160))
      sensor.skip_frames(10) # Let new settings take affect.
      sensor.skip_frames(time = 1000) #等待5s
      #sensor.set_framesize(sensor.QQVGA2) # 128x160大小的特定液晶屏。
      lcd = display.SPIDisplay()
      #key = Pin('P6', Pin.IN, Pin.PULL_UP)
      #key_pressed = False
      debounce_counter = 0
      
      #SUB = "s1"
      
      NUM_SUBJECTS = 2 #图像库中不同人数,一共6人
      NUM_SUBJECTS_IMGS = 20 #每人有20张样本图片
      RED_LED_PIN = 1
      BLUE_LED_PIN = 3
      # 拍摄当前人脸。
      img = sensor.snapshot()
      lcd.write(sensor.snapshot()) # 拍照并显示图像。
      #img = image.Image("singtown/%s/1.pgm"%(SUB))
      d0 = img.find_lbp((0, 0, img.width(), img.height()))
      face_cascade = image.HaarCascade("frontalface", stages=25)
      
      #d0为当前人脸的lbp特征
      img = None
      pmin = 999999
      num=0
      global dist
      ID_num = 3
      face_num=20
      state_flag=0
      with open("/sd/data.txt", "r") as f:
          lines = f.readlines()  # 读取所有行
          for line in lines:
              line = line.strip()  # 去除换行符
              if line:
                  NUM_SUBJECTS, ID_num = map(int, line.split(", "))  # 解析为整数
                  print("图像库中人数:%d ",NUM_SUBJECTS)
                  print(f"图像库中人数: {NUM_SUBJECTS}, ID: {ID_num}")
      def min(pmin, a, s):
          global num
          if a<pmin:
              pmin=a
              num=s
          return pmin
      key_state=0
      #def timer_callback(timer):
      #    global key_pressed, debounce_counter,key,key_state
      
      #        # 读取按键状态(按下=0,松开=1)
      #    key_state = key.value()
      
      #        # 消抖逻辑(检测到低电平时开始计数)
      #    if key_state == 0:  # 按键按下
      #        debounce_counter += 1
      #    if debounce_counter >= 10:  # 5ms*4=20ms消抖
      #       key_state = key.value()
      #       if key_state == 1:
      #          ID_num += 1
      #          key_pressed = True
      #          debounce_counter = 0
      rx_buff=[0,0,0,0]
      state = 0
      rx_flag = 0
      uart_num=0
      uart = UART(3, 115200, timeout_char=200)
      uart.init(115200, bits=8, parity=None, stop=1)
          #串口接收函数
      def Receive_Prepare(data):
          global state
          global rx_buff
          global rx_flag
          global uart_num
          global ID_num
          if (state==0 and data==13):
             state=1
          if state==1 :
              rx_buff[uart_num]=data
              uart_num+=1
              if data==93 and rx_buff[1]==1:
                  print("结束")
                  rx_flag=1
                  ID_num += 1
                  uart_num=0
                  state=0
              if data==93 and rx_buff[1]==2:
                   print("结束")
                   rx_flag=0
                   uart_num=0
                   state=0
      #tim = Timer(4, freq=200)  # 200Hz = 5ms
      #tim.callback(timer_callback)  # 绑定回调函数
      def sending_data(cx,cy,cw):
          global uart;
          #frame=[0x2C,18,cx%0xff,int(cx/0xff),cy%0xff,int(cy/0xff),0x5B];
          #data = bytearray(frame)
          data = ustruct.pack("<bbhhhb",      #格式为俩个字符俩个短整型(2字节)
                         0x2C,                      #帧头1
                         0x12,                      #帧头2
                         int(cx), # up sample by 4   #数据1
                         int(cy), # up sample by 4    #数据2
                         int(cw), # up sample by 4    #数据1
      #                   int(ch), # up sample by 4    #数据2
                         0x5B)
          uart.write(data);   #必须要传入一个字节数组
      
      while 1:
       if uart.any():  # 检测是否有数据
              data = uart.readchar()
              Receive_Prepare(data)
      #        print(rx_buff)
       lcd.write(sensor.snapshot())
      # rx_buff[1]=2
       if rx_buff[1]==1 and rx_flag == 1 :
      
           sending_data(1,0,0)
           pyb.LED(RED_LED_PIN).on()
           sensor.skip_frames(time = 500) # Give the user time to get ready.等待3s,准备一下表情。
           lcd.write(sensor.snapshot())
           #红灯灭,蓝灯亮
           #machine.LED("LED_RED").off()
           #machine.LED("LED_BLUE").on()
           pyb.LED(RED_LED_PIN).off()
           pyb.LED(BLUE_LED_PIN).on()
      
           #保存截取到的图片到SD卡
      #     print(face_num)
           sensor.snapshot().save("face/s%s/%s.bmp" % (ID_num, face_num) ) # or "example.bmp" (or others)
           os.sync()  # 确保数据写入硬件
           face_num -= 1
      
           pyb.LED(BLUE_LED_PIN).off()
           #machine.LED("LED_BLUE").off()
           if face_num==0:
             state_flag=0
             rx_flag=0
             rx_buff=[0,0,0,0]
             NUM_SUBJECTS+=1
             sending_data(0,ID_num,1)
             with open("/sd/data.txt", "w") as f:  # "a"表示追加模式
                 # 写入字符串格式的整数(可添加换行符分隔)
                 f.write(f"{NUM_SUBJECTS}, {ID_num}\n")  # 格式:计数,温度
      #       print(f"已写入数据:{NUM_SUBJECTS}, {{ID_num}}")
      #       print("Done! Reset the camera to see the saved image.")
      
      
      
       elif (rx_buff[1] == 2 and rx_flag == 0):
      #   print("About to start detecting faces...")
      # sensor.skip_frames(time=2000)  # 给用户一个时间来准备
         lcd.write(sensor.snapshot())
         if uart.any():  # 检测是否有数据
                data = uart.readchar()
      #          print(data)
                Receive_Prepare(data)
      #          print(rx_buff)
      #   print("Now detecting faces!")
      #   diff = 1  # We'll say we detected a face after 10 frames.
      
      #   while diff and rx_buff[1]==0 and uart.any() == 0:
      #      img = sensor.snapshot()
      #      lcd.write(sensor.snapshot())
      #      if uart.any():  # 检测是否有数据
      #             data = uart.readchar()
      #             print(data)
      #             Receive_Prepare(data)
      #             print(rx_buff)
      #        # Threshold是介于0.0-1.0的阈值,较低值会同时提高检出率和假阳性
      #        # 率。相反,较高值会同时降低检出率和假阳性率。
      #        # scale是一个必须大于1.0的浮点数。较高的比例因子运行更快,
      #        # 但其图像匹配相应较差。理想值介于1.35-1.5之间。
      #        # scale控制匹配比例,使您可以检测较小的脸部。
      #      faces = img.find_features(face_cascade, threshold=0.2, scale_factor=1.4)
      
      #      if faces:
      #           diff -= 1
      #           for r in faces:
      #               img.draw_rectangle(r)
         pyb.LED(RED_LED_PIN).on()
         lcd.write(sensor.snapshot())
         sensor.skip_frames(time = 3000)
         img = sensor.snapshot()
         d0 = img.find_lbp((0, 0, img.width(), img.height()))
         pyb.LED(RED_LED_PIN).off()
         pmin = 999999
         for s in range(1, NUM_SUBJECTS+1):
            global dist
            dist = 0
            lcd.write(sensor.snapshot()) # 拍照并显示图像。
            for i in range(2, NUM_SUBJECTS_IMGS+1):
                img = image.Image("face/s%d/%d.bmp"%(s, i))
                lcd.write(sensor.snapshot()) # 拍照并显示图像。
                d1 = img.find_lbp((0, 0, img.width(), img.height()))
                #d1为第s文件夹中的第i张图片的lbp特征
                dist += image.match_descriptor(d0, d1)#计算d0 d1即样本图像与被检测人脸的特征差异度。
            print("Average dist for subject %d: %d"%(s, dist/NUM_SUBJECTS_IMGS))
            pmin = min(pmin, dist/NUM_SUBJECTS_IMGS, s)#特征差异度越小,被检测人脸与此样本更相似更匹配。
      
            print(pmin)
         rx_buff=[0,0,0,0]
         sending_data(0,num,NUM_SUBJECTS)
         print(num) # num为当前最匹配的人的编号。