Distinguindo diferentes rostos
Tutorial em vídeo 19 - Distinguindo diferentes rostos:https://singtown.com/learn/50033/
Esta seção mostra como usar características LBP para distinguir diferentes rostos.
Primeiro precisamos construir nossa própria biblioteca de imagens. Primeiro criamos uma nova pasta no disco USB da OpenMV (observe que você deve inserir o cartão SD) e a nomeamos singtown, e depois criamos n subpastas chamadas s1, s2, s3...sn dentro da pasta singtown, onde n é o número de pessoas em toda a biblioteca de imagens. Como mostrado abaixo:

Em seguida, podemos executar o código a seguir para coletar diferentes amostras de rostos. Note que, ao coletar, tente manter o fundo uniforme e deixar o rosto preencher a tela inteira o máximo possível. O rosto pode estar sorrindo, sem sorrir, reto, inclinado, usando óculos, sem óculos, etc. Você pode escolher de 10 a 20 fotos por pessoa.
# Snapshot Example
#
# Note: You will need an SD card to run this example.
#
# You can use your OpenMV Cam to save image files.
import csi, image, machine
csi0 = csi.CSI()
#import pyb
RED_LED_PIN = 1
BLUE_LED_PIN = 3
csi0.reset() # Initialize the camera sensor.
csi0.pixformat(csi.GRAYSCALE) # or csi.GRAYSCALE
csi0.framesize(csi.QQVGA) # or csi.QQVGA (or others)
csi0.window((92,112))
csi0.snapshot(frames=10) # Let new settings take affect.
csi0.snapshot(time = 2000)
num = 1 # define o número da pessoa fotografada; as fotos da primeira pessoa são salvas na pasta s1, as da segunda na pasta s2, e assim por diante. Altere o valor de num a cada troca de pessoa fotografada.
n = 20 # define a quantidade de fotos tiradas de cada pessoa.
# tira n fotos seguidas, uma a cada 3s.
while(n):
# acende a luz vermelha
machine.LED("LED_RED").on()
#pyb.LED(RED_LED_PIN).on()
csi0.snapshot(time = 3000) # Give the user time to get ready. espera 3s, para se preparar com a expressão.
# apaga a luz vermelha, acende a luz azul
machine.LED("LED_RED").off()
machine.LED("LED_BLUE").on()
#pyb.LED(RED_LED_PIN).off()
#pyb.LED(BLUE_LED_PIN).on()
# salva a imagem capturada no cartão SD
print(n)
csi0.snapshot().save("singtown/s%s/%s.pgm" % (num, n) ) # or "example.bmp" (or others)
n -= 1
#pyb.LED(BLUE_LED_PIN).off()
machine.LED("LED_BLUE").off()
print("Done! Reset the camera to see the saved image.")
Depois de fotografar, a imagem no disco USB da OpenMV fica assim (note que toda vez que o disco USB da OpenMV grava uma nova imagem/arquivo, é necessário reiniciar a OpenMV para poder vê-la):


Por fim, executamos o código a seguir para identificar o rosto no campo de visão atual da câmera e retornar a pessoa que melhor corresponde ao objeto atual.
# 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 csi, time, image
csi0 = csi.CSI()
csi0.reset() # Initialize the camera sensor.
csi0.pixformat(csi.GRAYSCALE) # or csi.GRAYSCALE
csi0.framesize(csi.QQVGA) # or csi.QQVGA (or others)
csi0.window((92,112))
csi0.snapshot(frames=10) # Let new settings take affect.
csi0.snapshot(time = 5000) # espera 5s
#SUB = "s1"
NUM_SUBJECTS = 6 # número de pessoas diferentes na biblioteca de imagens, 6 pessoas no total
NUM_SUBJECTS_IMGS = 20 # cada pessoa tem 20 imagens de amostra
# captura o rosto atual.
img = csi0.snapshot()
#img = image.Image("singtown/%s/1.pgm"%(SUB))
d0 = img.find_lbp((0, 0, img.width(), img.height()))
# d0 é a característica lbp do rosto atual
img = None
pmin = 999999
num=0
def min(pmin, a, s):
global num
if a<pmin:
pmin=a
num=s
return pmin
for s in range(1, NUM_SUBJECTS+1):
dist = 0
for i in range(2, NUM_SUBJECTS_IMGS+1):
img = image.Image("singtown/s%d/%d.pgm"%(s, i))
d1 = img.find_lbp((0, 0, img.width(), img.height()))
# d1 é a característica lbp da imagem i da pasta s
dist += image.match_descriptor(d0, d1) # calcula o grau de diferença entre as características de d0 e d1, ou seja, entre a imagem de amostra e o rosto detectado.
print("Average dist for subject %d: %d"%(s, dist/NUM_SUBJECTS_IMGS))
pmin = min(pmin, dist/NUM_SUBJECTS_IMGS, s) # quanto menor o grau de diferença de características, mais o rosto detectado se assemelha e corresponde a essa amostra.
print(pmin)
print(num) # num é o número da pessoa que melhor corresponde atualmente.
O resultado da execução é mostrado na figura:
