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



    • 0_1587183317335_2ca4b564-35d3-42d9-9f38-49942ab44c92-image.png

      '''
      >> author: SXF
      >> email: [email]songxf1024@163.com[/email]
      >> description:
        用LBP特征进行人脸识别,可进行人脸注册、人脸检测与人脸识别
        Pin7高电平一次,触发人脸注册;默认低电平
        UART1(Pin1)输出调试信息
        UART3(Pin4)输出识别结果,当识别成功后,返回“Find It”(可自定义修改),可连接IoT平台
        注:需配备SD卡,最大3支持2G,将main.py等文件放至SD卡根目录后上电
      '''
      
      import sensor, time, image #调用传感器,时钟,图片的库
      import os, time            #调用Os库用于文件操作
      import pyb
      from pyb import Pin
      
      red   = pyb.LED(1)    #传递参数“1”给 pyb.LED 控制红色的RGB LED灯段, “2”控制绿色的RGB LED灯段,“3”控制蓝色的RGB LED灯段,“4”控制两个红外灯。
      green = pyb.LED(2)
      blue  = pyb.LED(3)
      infrared = pyb.LED(4)
      usart1 = pyb.UART(1, 115200)  #设置串口总线1和3的的输出管脚和波特率
      usart3 = pyb.UART(3, 115200)
      REGISTER_MODE = 0
      
      sensor.reset()
      sensor.set_contrast(1)     #设置相机图像对比度。-3至+3
      sensor.set_gainceiling(16)  #相机图像增益上限(2, 4, 8, 16, 32, 64, 128)
      sensor.set_framesize(sensor.HQVGA)   #设置相机模块的帧大小
      sensor.set_pixformat(sensor.GRAYSCALE)   #灰度,每个像素8bit。
      sensor.skip_frames(10)           #跳过10张照片,在更改设置后,跳过一些帧,等待感光元件变稳定
      
      Path_Backup = {'path':'', 'id':0}  #设置字符数组
      rootpath = "/orl_faces"            #定义根路径
      DIST_THRESHOLD = 15000  # 差异度阈值
      
      def debug(strings):               #返回调试结果
          print(strings)
          usart1.write(str(strings)+"\r\n")
      
      def find(face_cascade, img):
          objects = img.find_features(face_cascade, threshold=0.75, scale_factor=1.25)  # 人脸检测,搜索与Haar Cascade匹配的所有区域的图像,并返回一个关于这些特征的边界框矩形元组(x,y,w,h)的列表
          if objects:
              green.on()
              time.sleep(500)
              green.off()
              width_old = 0
              height_old = 0
              index = 0
              for r in objects:  # 寻找最大的face
                  if r[2] > width_old and r[3] > height_old:
                      width_old = r[2]
                      height_old = r[3]
                      index += 1
              index -= 1
              #print("index:", index)
              img.draw_rectangle(objects[index])
              d0 = img.find_lbp((0, 0, img.width(), img.height()))
              res = match(d0)
              if res != 0:
                  debug(res)
                  return 1
      
      
      def match(d0):  # 人脸识别
          dir_lists = os.listdir(rootpath)  # 路径下文件夹
          dir_num = len(dir_lists)          # 文件夹数量
          debug("*" * 60)
          debug("Total %d Folders -> %s"%(dir_num, str(dir_lists)))
      
          for i in range(0, dir_num):
              item_lists = os.listdir(rootpath+'/'+dir_lists[i])  # 路径下文件
              item_num = len(item_lists)                          # 文件数量
              debug("The %d Folder[%s], Total %d Files -> %s" %(i+1, dir_lists[i], item_num, str(item_lists)))
      
              Path_Backup['path'] = rootpath+'/'+dir_lists[i]  # 马上记录当前路径
              Path_Backup['id'] = item_num                     # 马上记录当前文件数量
      
              for j in range(0, item_num):  # 文件依次对比
                  debug(">> Current File: " + item_lists[j])
                  try:
                      img = image.Image("/orl_faces/%s/%s" % (dir_lists[i], item_lists[j]), copy_to_fb=True)
                  except Exception as e:
                      debug(e)
                      break
                  d1 = img.find_lbp((0, 0, img.width(), img.height()))  # 提取特征值
                  dist = image.match_descriptor(d0, d1)                 # 计算差异度
                  debug(">> Difference Degree: " + str(dist))
                  if dist < DIST_THRESHOLD:            #小于阈值
                      debug(">> ** Find It! **")
                      green.on()
                      time.sleep(1000)
                      green.off()
                      return item_lists[j]  #找到之后返回文件夹编号
          debug(">> ** No Match! **")
          return 0
      
      
      def register(face_cascade, img):                   #拍摄人脸,mode为0时表示在非拍摄状态
          global REGISTER_MODE
          if find(face_cascade, img) == 1:   #find it
              debug(">> Existing without registration!")
              REGISTER_MODE = 0
              return 0
                                            #not find it
          dir_lists = os.listdir(rootpath)  # 路径下文件夹
          dir_num = len(dir_lists)          # 文件夹数量
          new_dir = ("%s/%d") % (rootpath, int(dir_num)+1)
          os.mkdir(new_dir)                 # 创建文件夹
          cnt = 15  #拍摄10次图片
          while cnt:    #cnt>0
              img = sensor.snapshot()  #拍图片
              objects = img.find_features(face_cascade, threshold=0.75, scale_factor=1.25)  # 人脸检测
              if objects:
                  width_old = 0
                  height_old = 0
                  index = 0
                  for r in objects:  # 寻找最大的face
                      if r[2] > width_old and r[3] > height_old:
                          width_old = r[2]
                          height_old = r[3]
                          index += 1
                  index -= 1
                  #print("index:", index)
      
                  item_lists = os.listdir(new_dir)  # 新路径下文件
                  item_num = len(item_lists)        # 文件数量
                  img.save("%s/%d.pgm" % (new_dir, item_num))  # 写入文件
                  debug(">> [%d]Regist OK!" % cnt)
                  img.draw_rectangle(objects[index])
                  green.on()
                  time.sleep(50)
                  green.off()
                  cnt -= 1
                  if cnt==0:
                      green.on()
                      time.sleep(1000)
                      green.off()
              REGISTER_MODE = 0
      
      def takephoto(res):
         if res==1:
             dg_dir = ("%s/%s") % (rootpath, dangerous)
             os.mkdir(dg_dir)                 # 创建文件夹
             num=len(dg_dir)
             for i in range(0,8):
                 red.on()  #红灯亮表示一次的开始
                 print("About to start detecting faces...")
                 sensor.skip_frames(time = 2000) # Give the user time to get ready.设置生效
                 red.off()  #红灯灭,开始拍摄
                 print("Now detecting faces!")
                 blue.on()    #蓝灯亮
                 diff = 10 # We'll say we detected a face after 10 frames.
      
                 while(diff):
                     img = sensor.snapshot()
                                  # Threshold是介于0.0-1.0的阈值,较低值会同时提高检出率和假阳性
                                  # 率。相反,较高值会同时降低检出率和假阳性率。
                                  # scale是一个必须大于1.0的浮点数。较高的比例因子运行更快,
                                  # 但其图像匹配相应较差。理想值介于1.35-1.5之间。
                     faces = img.find_features(face_cascade, threshold=0.5, scale_factor=1.5)
                     if faces:
                         diff -= 1
                         for r in faces:
                          img.draw_rectangle(r)
                 blue.off()
                 print("Face detected! Saving image%s"%(dg_dir))
                 sensor.snapshot().save("%s/%d.pgm" % (dg_dir,num))# Save Pic.
                 num+=1
             dir_num = len(dg_dir)
             if dir_num>80:
               os.remove(dg_dir)
      
      
      
      
      
      
      def main():
          global REGISTER_MODE
          try:
              os.mkdir(rootpath)
          except:
              pass
          pin7 = Pin('P7', Pin.IN, Pin.PULL_DOWN)  # 1为注册模式,即拍照存入,即高电平时进行拍摄
          face_cascade = image.HaarCascade("frontalface", stages=25)      #利用haar算子将forntalface模型导入,将一个内置的正脸Haar Cascade载入内存
          #try:
              #face_cascade = image.HaarCascade("/haarcascade_frontalcatface.cascade", stages=25)  # "frontalface"
          #except:
              #face_cascade = image.HaarCascade("frontalface", stages=25)
          print(face_cascade)
          clock = time.clock()
          img = None
      
          while (True):
              clock.tick()
              img = sensor.snapshot()
              if pin7.value() == 1:   #高电平时设置mode为1进行录入拍摄模式,为低电平时执行else进行查找操作,并串口发出find it
                  REGISTER_MODE = 1
      
              if REGISTER_MODE == 1:
                  debug("REGISTER_MODE\r\n")
                  register(face_cascade, img)
              else:
                  res = find(face_cascade, img)
                  if res==1:
                      takephoto(res)
                      usart3.write("Find It\r\n")
      
      
      
      # 程序开始
      #debug(os.listdir())
      main()