- Detecção de objetos usando SIFT
- Detecção de objetos usando ORB
- Histograma de gradientes orientados (HOG's)
- Histograma de gradientes orientados (HOG's), passo a passo:
- Classificadores em cascata HAAR
- Detecção de rosto e olhos
- Detecção de rosto e olhos ao vivo
- Ajustando Classificadores Cascade
- Detecção de carros e pedestres em vídeos
Começamos instalando o Python OpenCV no Windows e até agora fizemos processamento básico de imagens, segmentação de imagens e detecção de objetos usando Python, que são abordados nos tutoriais abaixo:
- Introdução ao Python OpenCV: instalação e processamento básico de imagens
- Manipulações de imagem em Python OpenCV (parte 1)
- Manipulações de imagem em OpenCV (Parte 2)
- Segmentação de imagens usando OpenCV - Extração de áreas específicas de uma imagem
Também aprendemos sobre vários métodos e algoritmos para detecção de objetos, onde alguns pontos-chave foram identificados para cada objeto usando diferentes algoritmos. Neste tutorial vamos usar esses algoritmos para detectar objetos da vida real, aqui estaríamos usando SIFT e ORB para a detecção.
Detecção de objetos usando SIFT
Aqui a detecção do objeto será feita através do stream da webcam ao vivo, portanto, se reconhecer o objeto, mencionará o objeto encontrado. No código, a parte principal é desempenhada pela função que é chamada de detector SIFT, a maior parte do processamento é feito por esta função.
E na outra metade do código, estamos começando com a abertura do stream da webcam e, em seguida, carregamos o modelo de imagem, ou seja, a imagem de referência, ou seja, o programa está realmente olhando através do stream da webcam.
Em seguida, estamos continuamente capturando as imagens do stream da webcam com a ajuda de loop while infinito e , em seguida, capturando a altura e largura correspondentes da moldura da webcam, e depois definir os parâmetros da caixa da região de interesse (ROI) em que nosso objeto pode caber tomando a altura e largura correspondentes da moldura da webcam. E então desenhamos o retângulo a partir dos parâmetros de ROI que definimos acima. Então, finalmente recorte o retângulo e alimente-o na parte do detector SWIFT do código.
Agora, o detector SIFT tem basicamente duas entradas, uma é a imagem recortada e a outra é o modelo de imagem que definimos anteriormente e, em seguida, ele nos dá algumas correspondências, então correspondências são basicamente o número de objetos ou pontos-chave que são semelhantes na imagem recortada e a imagem alvo. Então definimos um valor limite para as correspondências, se o valor das correspondências for maior que o limite, colocamos a imagem encontrada em nossa tela com a cor verde do retângulo ROI.
Agora vamos voltar para a parte principal do código, a função que é chamada de detector SIFT, ela pega a entrada como duas imagens, uma é a imagem onde está procurando o objeto e a outra é o objeto que estamos tentando combinar para (modelo de imagem). Em seguida, dimensione a primeira imagem em escala de cinza e defina o modelo da imagem como a segunda imagem. Em seguida, criamos um objeto detector SIFT e executamos a função OpenCV SIFT detectar e calcular, de modo a detectar os pontos-chave e calcular os descritores, os descritores são basicamente os vetores que armazenam as informações sobre os pontos-chave, e é muito importante enquanto fazemos a correspondência entre os descritores das imagens.
E então definir o matcher baseado em FLANN, não vamos entrar na teoria matemática de correspondência por trás dele, mas você pode facilmente pesquisar no Google sobre isso. Em primeiro lugar, defina o índice kdtree para zero e depois definimos o índice e os parâmetros de pesquisa no formato de dicionário, apenas definimos o algoritmo que vamos usar que é KDTREE, e o número de árvores que vamos usar, mais árvores nós usamos quanto mais complicado e lento. E no parâmetro de pesquisa defina o número de verificações, que é basicamente o número de correspondências que vai completar.
E, em seguida, crie nosso objeto matcher baseado em FLANN carregando o parâmetro que definimos anteriormente, que são parâmetros de índice e parâmetros de pesquisa e com base nisso, crie nosso matcher baseado em FLANN, que é um matcher KNN onde KNN são os vizinhos K-mais próximos, basicamente é uma maneira onde procuramos os matchers e descritores mais próximos e fazemos a correspondência com a constante de inicialização k. Agora, este matcher baseado em FLANN retorna o número de correspondências que obtemos.
A correspondência baseada em FLANN é apenas uma aproximação, de modo a aumentar a precisão do combinador baseado em FLANN, realizamos um teste de proporção de Lowe e o que ele faz é procurar as correspondências do combinador baseado em knn flann e definir alguns parâmetros matriciais que são a distância aqui, para a qual a distância é uma função numpy e, uma vez que atenda aos critérios, acrescente as correspondências às boas correspondências e retorne as boas correspondências encontradas, e assim o fluxo de vídeo ao vivo informa o número de correspondências encontradas no canto da tela.
Agora, vamos examinar o código da descrição acima:
import cv2 import numpy as np def sift_detector (new_image, image_template): # Função que compara a imagem de entrada com o modelo # Em seguida, retorna o número de correspondências SIFT entre eles image1 = cv2.cvtColor (new_image, cv2.COLOR_BGR2GRAY) image2 = image_template # Criar Objeto detector SIFT #sift = cv2.SIFT () sift = cv2.xfeatures2d.SIFT_create () # Obtenha os pontos-chave e os descritores usando SIFT keypoints_1, descriptors_1 = sift.detectAndCompute (image1, None) keypoints_2, descriptors_2 = sift.detectAndCompute (image2, Nenhum) # Defina parâmetros para nosso Flann Matcher FLANN_INDEX_KDTREE = 0 index_params = dict (algoritmo = FLANN_INDEX_KDTREE, trees = 3) search_params = dict (checks = 100) # Crie o objeto Flann Matcher flann = cv2.FlannBasedMatcher (index_params, search_params) # Obtenha correspondências usando o método do vizinho mais próximo K # o resultado 'correspondências' é o número de correspondências semelhantes encontradas nas correspondências de ambas as imagens = flann.knnMatch (descriptors_1, descriptors_2, k = 2) # Armazene boas correspondências usando o teste de razão de Lowe good_matches = para m, n em correspondências: se m.distance <0,7 * n.distance: good_matches.append (m) return len (good_matches) cap = cv2.VideoCapture (0) # Carregue nosso modelo de imagem, esta é nossa imagem de referência image_template = cv2.imread ('phone.jpg', 0) while True: # Obter imagens da webcam ret, frame = cap.read () # Obtenha a altura e a largura da altura do quadro da webcam , width = frame.shape # Defina as dimensões da caixa ROI top_left_x = int (largura / 3) top_left_y = int ((altura / 2) + (altura / 4)) bottom_right_x = int ((largura / 3) * 2) bottom_right_y = int ((altura / 2) - (altura / 4)) # Desenhe uma janela retangular para nossa região de interesse cv2.rectangle (frame, (top_left_x, top_left_y), (bottom_right_x, bottom_right_y), 255, 3) # Janela de corte de observação que definimos acima cropped = frame # Inverter orientação do frame horizontalmente frame = cv2.flip (frame, 1) # Obter o número de correspondências SIFT = sift_detector (cropped, image_template) # Exibir string de status mostrando o nº atual. de correspondências cv2.putText (frame, str (correspondências), (450,450), cv2.FONT_HERSHEY_COMPLEX, 2, (0,255,0), 1) # Nosso limite para indicar detecção de objeto # Usamos 10, pois o detector SIFT retorna poucos falsos positivos threshold = 10 # Se as correspondências excederem nosso limite, então o objeto foi detectado se correspondências> threshold: cv2.rectangle (frame, (top_left_x, top_left_y), (bottom_right_x, bottom_right_y), (0,255,0), 3) cv2.putText (frame, 'Object Found', (50,50), cv2.FONT_HERSHEY_COMPLEX, 2, (0,255,0), 2) cv2.imshow ('Object Detector using SIFT', frame) if cv2.waitKey (1) == 13: # 13 é a quebra da chave Enter cap.release () cv2.destroyAllWindows ()
Detecção de objetos usando ORB
A detecção de objetos usando SIFT é muito legal e precisa, pois gera um número muito preciso de correspondências com base em keypoints, porém é patenteado e isso dificulta o uso para aplicações comerciais, a outra saída para isso é o algoritmo ORB para detecção de objetos.
Semelhante ao método de detecção de objetos por SIFT em que dividimos o programa em duas partes, o mesmo será seguido aqui.
Em primeiro lugar, definimos a função ORB_detector que recebe duas entradas, uma é a imagem de transmissão ao vivo proveniente da webcam e a outra é o modelo de imagem com base no qual vamos combinar nossa imagem. Em seguida, colocamos a imagem da webcam em tons de cinza e inicializamos nosso detector ORB, e estamos configurando aqui em 1000 pontos-chave e parâmetros de escala de 1,2. você pode brincar facilmente com esses parâmetros, em seguida, detectar os pontos-chave (kp) e os descritores (des) para as imagens e o segundo parâmetro que estamos definindo na função detectANDCompute é NONE, está solicitando o uso de máscara de imagem ou não e estamos negando isso aqui.
Em seguida, mova para o detector que estávamos usando o matcher baseado em FLANN, mas aqui estaremos usando BFMatcher e dentro do BFMatcher definimos dois parâmetros, um é NORM_HAMMING e outro é o crossCheck cujo valor é TRUE.
Em seguida, calcule as correspondências - as correspondências entre essas duas imagens usando os descritores definidos acima, que em todos retorna o número de correspondências, uma vez que essas correspondências não são aproximações e, portanto, não há necessidade de fazer o teste de razão de Lowe, em vez disso, classificamos as correspondências com base na distância, quanto menos a distância mais a correspondência é melhor (aqui a distância significa distância entre os pontos), e no final retornamos o número de correspondências usando a função de comprimento.
E na função principal definimos o limite para um valor muito mais alto, uma vez que o detector orbe gera muito ruído.
Agora vamos examinar o código para detecção baseada em ORB
import cv2 import numpy as np def ORB_detector (new_image, image_template): # Função que compara a imagem de entrada com o modelo # Em seguida, retorna o número de correspondências ORB entre eles image1 = cv2.cvtColor (new_image, cv2.COLOR_BGR2GRAY) # Criar detector ORB com 1000 pontos-chave com um fator de pirâmide de escala de 1,2 orb = cv2.ORB_create (1000, 1,2) # Detecta pontos-chave da imagem original (kp1, des1) = orb.detectAndCompute (image1, Nenhum) # Detecta pontos-chave da imagem girada (kp2, des2) = orb.detectAndCompute (image_template, None) # Create matcher # Observe que não estamos mais usando a correspondência baseada em Flann bf = cv2.BFMatcher (cv2.NORM_HAMMING, crossCheck = True) # Faça correspondências = bf.match (des1, des2) # Classifique as correspondências com base na distância. A menor distância # é melhor corresponde a = classificado (coincide, chave = lambda val: val.distance) return len (coincide) cap = cv2.VideoCapture (0) # Carrega nosso modelo de imagem, esta é nossa imagem de referência image_template = cv2.imread ('phone.jpg', 0) # image_template = cv2.imread ('images / kitkat.jpg', 0) enquanto Verdadeiro: # Obter imagens da webcam ret, frame = cap.read () # Obter altura e largura da altura da moldura da webcam , width = frame.shape # Define ROI Box Dimensions (observe que algumas dessas coisas devem estar fora do loop) top_left_x = int (largura / 3) top_left_y = int ((height / 2) + (height / 4)) bottom_right_x = int ((largura / 3) * 2) bottom_right_y = int ((height / 2) - (height / 4)) # Desenhe janela retangular para nosso região de interesse cv2.rectangle (frame, (top_left_x, top_left_y), (bottom_right_x, bottom_right_y), 255, 3) # Janela de corte de observação que definimos acima cropped = frame # Inverter orientação de frame horizontalmente frame = cv2.flip (frame, 1) # Obtém o número de correspondências de ORB = ORB_detector (cropped, image_template) # Mostra a string de status mostrando o nº atual. de correspondências output_string = "Matches =" + str (correspondências) cv2.putText (frame, output_string, (50.450), cv2.FONT_HERSHEY_COMPLEX, 2, (250,0,150), 2) # Nosso limite para indicar detecção de objeto # Para novas imagens ou condições de iluminação, você pode precisar experimentar um pouco # Nota: O detector ORB para obter as 1000 melhores correspondências, 350 é essencialmente um limite mínimo de correspondência de 35% = 250 # Se as correspondências excederem nosso threshold então o objeto foi detectado se for compatível com > threshold: cv2.rectangle (frame, (top_left_x, top_left_y), (bottom_right_x, bottom_right_y), (0,255,0), 3) cv2.putText (frame, 'Objeto encontrado', (50, 50), cv2.FONT_HERSHEY_COMPLEX, 2, (0,255,0), 2) cv2.imshow ('Detector de objeto usando ORB', frame) se cv2.waitKey (1) == 13: # 13 é o limite de quebra da chave Enter .release () cv2.destroyAllWindows ()
Histograma de gradientes orientados (HOG's)
Agora vamos falar sobre um descritor diferente que é Histogram of Oriented Gradients (HOG's).
HOGs são descritores muito legais e úteis e são amplamente e com sucesso usados para detecção de objetos, como visto anteriormente, os descritores de imagem como SIFT e ORB, onde temos que calcular os pontos-chave e depois calcular os descritores a partir desses pontos-chave, os HOGs fazem esse processo de forma diferente. Ele representa objetos como um único vetor de recursos, em oposição a um conjunto de vetores de recursos, onde cada um representa um segmento da imagem. Isso significa que temos recurso de vetor único para a imagem inteira.
É calculado por um detector de janela deslizante sobre uma imagem, onde um descritor HOG é calculado para cada posição. E então cada posição é combinada para um único vetor de recurso.
Como SIFT, a escala da imagem é ajustada piramidando.
Anteriormente, usamos matchers como FLANN e BFMatcher, mas HOGs fazem isso de forma diferente com a ajuda de classificadores SVM (máquina de vetor de suporte), onde cada descritor HOG que é calculado é alimentado para um classificador SVM para determinar se o objeto foi encontrado ou não.
Aqui está o link para um ótimo artigo de Dalal & Triggs sobre o uso de HOGs para detecção humana:
Histograma de gradientes orientados (HOG's), passo a passo:
Entender os HOGs pode ser bastante complexo, mas aqui vamos apenas lidar com a teoria dos HOGs, sem nos aprofundarmos na matemática relacionada a ela.
Então vamos tirar esta foto um pouco pixelada, e no canto superior está a caixa de 8x8 pixels aqui, então nesta caixa nós calculamos o vetor gradiente ou as orientações das bordas em cada pixel. Isso significa que nesta caixa calculamos o vetor gradiente da imagem de pixels dentro da caixa (eles são uma espécie de direção ou fluxo da própria intensidade da imagem), e isso gera 64 (8 x 8) vetores gradientes que são então representados como um histograma. Então imagine um histograma que representa cada vetor gradiente. Portanto, se todos os pontos ou intensidades estivessem em uma direção, o histograma para essa direção, digamos 45 graus, o histograma teria pico em 45 graus.
Então o que fazemos agora é dividir cada célula em caixas angulares, onde cada caixa corresponde a uma direção de gradiente (por exemplo, x, y). No artigo Dalal e Triggs, eles usaram 9 escaninhos 0-180 ° (20 ° cada escaninho). Isso efetivamente reduz 64 vetores para apenas 9 valores. Portanto, o que fizemos foi reduzir o tamanho, mas manter todas as informações essenciais necessárias.
O próximo passo no cálculo do porco é a normalização, normalizamos os gradientes para garantir a invariância às mudanças de iluminação, ou seja, brilho e contraste.
Nesta imagem, os valores de intensidade são mostrados no quadrado de acordo com a respectiva direção e todos têm diferença de 50 entre si
∆ H = 50, ∆ v = 50; │∆│ = √50 2 +50 = 70,72, 70,72 / 100 = 0,707
Dividimos os vetores pelas magnitudes do gradiente e obtemos 0,707 para todos, isso é normalização.
Da mesma forma, se alterarmos a intensidade ou o contraste, obteremos os valores abaixo.
∆ H = 50, ∆ v = 50; │∆│ = √50 2 +50 = 70,72, 70,72 / 100 = 0,707; ∆ H = 100, ∆ v = 100; │∆│ = √100 2 +100 = 141,42, 141,42 / 100 = 1,41
A normalização não ocorre em um nível de célula, mas sim em um nível de bloco, então aqui os blocos são basicamente um grupo de 4 células, isso leva em consideração os blocos vizinhos, então normalize enquanto leva em consideração segmentos maiores da imagem.
Agora vamos dar uma olhada no código
import numpy as np import cv2 import matplotlib.pyplot as plt # Carregar imagem e depois em tons de cinza image = cv2.imread ('elephant.jpg') gray = cv2.cvtColor (image, cv2.COLOR_BGR2GRAY) # Mostrar imagem original cv2.imshow (' Input Image ', image) cv2.waitKey (0) #definindo os parâmetros, tamanho da célula e tamanho do bloco # hxw em pixels cell_size = (8, 8) # hxw em células block_size = (2, 2) # número de bins de orientação nbins = 9 # Usando o descritor HOG do OpenCV # winSize é o tamanho da imagem cortada em um múltiplo do tamanho da célula hog = cv2.HOGDescriptor (_winSize = (gray.shape // cell_size * cell_size, gray.shape // cell_size * cell_size), _blockSize = (block_size * cell_size, block_size * cell_size), _blockStride = (cell_size, cell_size), _cellSize = (cell_size, cell_size), _nbins = nbins) # Crie uma forma de array numpy que usamos para criar hog_features n_cells = (gray.shape // cell_size, gray.shape // cell_size) # Indexamos blocos por linhas primeiro. # hog_feats agora contém as amplitudes de gradiente para cada direção, # para cada célula de seu grupo para cada grupo. A indexação é feita por linhas e depois por colunas. hog_feats = hog.compute (cinza).reshape (n_cells - block_size + 1, n_cells - block_size + 1 , block_size, block_size, nbins).transpose ((1, 0, 2, 3, 4)) # Crie nossa matriz de gradientes com dimensões nbin para armazenar orientações de gradientes gradientes = np.zeros ((n_cells, n_cells, nbins)) # Crie matriz de dimensões cell_count = np.full ((n_cells, n_cells, 1), 0, dtype = int) # Normalização de bloco para off_y no intervalo (block_size): para off_x no intervalo (block_size): gradientes - block_size + off_y + 1, off_x: n_cells - block_size + off_x + 1] + = \ hog_feats cell_count - block_size + off_y + 1, off_x: n_cells - block_size + off_x + 1] + = 1 # gradientes médios de gradientes / = cell_count # Plot HOGs usando Matplotlib # ângulo é 360 / nbins * direção color_bins = 5 plt.pcolor (gradientes) plt.gca (). invert_yaxis () plt.gca (). set_aspect ('equal', ajustável = 'box') plt.colorbar () plt.show () cv2.destroyAllWindows ()
A imagem mostra como a imagem de entrada é representada como representação HOG.
Classificadores em cascata HAAR
Conforme discutido anteriormente, podemos extrair recursos de uma imagem e usar esses recursos para classificar ou detectar objetos.
O que são classificadores em cascata HAAR?
Um método de detecção de objeto que insere recursos Haar em uma série de classificadores (cascata) para identificar objetos em uma imagem. Eles são treinados para identificar um tipo de objeto, no entanto, podemos usar vários deles em paralelo, por exemplo, detectar olhos e rostos juntos.
Classificadores HAAR explicados:
Classificadores HAAR são treinados usando muitas imagens positivas (ou seja, imagens com o objeto presente) e
imagens negativas (ou seja, imagens sem o objeto presente).
Assim que tivermos essas imagens, extraímos os recursos usando janelas deslizantes de blocos retangulares. Esses recursos (recursos HAAR) têm um valor único e são calculados subtraindo a soma das intensidades de pixel sob os retângulos brancos dos retângulos pretos.
No entanto, este é um número ridículo de cálculos, mesmo para uma janela base de 24 x 24 pixels (180.000 recursos gerados).
Então, os pesquisadores desenvolveram um método chamado Imagens Integrais que calculou isso com quatro referências de array. No entanto, eles ainda tinham 180.000 recursos e a maioria deles não agregava valor real.
O Boosting foi então usado para determinar os recursos mais informativos, com o AdaBoost de Freund & Schapire e encontrou os recursos mais informativos na imagem. Boosting é o processo pelo qual usamos classificadores fracos para construir classificadores fortes, simplesmente atribuindo penalidades mais pesadas em classificações incorretas. Reduzindo os 180.000 recursos para 6.000, o que ainda é um pouco de recursos.
Nesses 6000 recursos, alguns serão mais informativos do que outros. Portanto, se usarmos os recursos mais informativos para primeiro verificar se a região pode ter potencialmente um rosto (falsos positivos não serão grande coisa). Isso elimina a necessidade de calcular todos os 6000 recursos de uma vez. Esse conceito é chamado de Cascata de Classificadores - para detecção de rosto, o método de Viola Jones usou 38 estágios.
Detecção de rosto e olhos
Então, depois de adquirir algum conhecimento teórico sobre as cascatas HAAR, vamos finalmente implementá-lo, para deixar as coisas bem claras, quebraremos as lições em partes, primeiro detectaríamos a face frontal, depois disso, passaremos para detectar a face frontal com olhos e finalmente faríamos a detecção ao vivo de rosto e olhos através da webcam.
Então, para isso, vamos usar classificadores pré-treinados que foram fornecidos pelo OpenCV como arquivos.xml, xml significa linguagem de marcação extensível, essa linguagem é usada para armazenar uma grande quantidade de dados, você pode até construir um banco de dados sobre ela.
Você pode ter acesso a esses classificadores neste link .
Detecção de rosto
Vamos tentar a detecção facial frontal, você pode ter o acesso para a cascata do detector facial frontal aqui. Basta extrair o arquivo zip para obter o arquivo xml.
import numpy as np import cv2 # Apontamos a função CascadeClassifier do OpenCV para onde nosso # classificador (formato de arquivo XML) está armazenado, lembre-se de manter o código e o classificador na mesma pasta face_cascade = cv2.CascadeClassifier ('haarcascade_frontalface_default.xml') # Carregar nossa imagem, em seguida, converta-a para tons de cinza image = cv2.imread ('Trump.jpg') grey = cv2.cvtColor (image, cv2.COLOR_BGR2GRAY) # Nosso classificador retorna o ROI do rosto detectado como uma tupla # Ele armazena o canto superior esquerdo coordenada e as coordenadas inferiores à direita # retorna a lista de listas, que são a localização de diferentes rostos detectados. faces = face_cascade.detectMultiScale (cinza, 1.3, 5) # Quando nenhum rosto é detectado, face_classifier retorna e esvazia a tupla se faces for (): print ("No faces found") # Nós iteramos através de nossa matriz faces e desenhamos um retângulo # sobre cada face em faces para (x, y, w, h) em faces: cv2.rectangle (image, (x, y), (x + w, y + h), (127,0,255), 2) cv2.imshow ('Face Detection', image) cv2.waitKey (0) cv2.destroyAllWindows ()
Agora vamos combinar a detecção de rosto e olhos, você pode ter acesso para a cascata do detector de olhos no mesmo arquivo zip.
import numpy como np import cv2 face_classifier = cv2.CascadeClassifier ('haarcascade_frontalface_default.xml') eye_classifier = cv2.CascadeClassifier ('haarcascade_eye.xml') img = cv2.imread ('TrumpColor.jpg') grey = cv2.imread ('Trump.jpg (img). cv2.COLOR_BGR2GRAY) faces = face_classifier.detectMultiScale (grey, 1.3, 5) # Quando nenhum rosto detectado, face_classifier retorna e tupla vazia se faces for (): print ("Nenhum rosto encontrado") para (x, y, w, h) nas faces: cv2.rectangle (img, (x, y), (x + w, y + h), (127,0,255), 2) cv2.imshow ('img', img) roi_gray = grey roi_color = img eyes = eye_classifier.detectMultiScale (roi_gray) cv2.waitKey (0) para (ex, ey, ew, eh) nos olhos: cv2.rectangle (roi_color, (ex, ey), (ex + ew, ey + eh), (255,255,0), 2) cv2.imshow ('img', img) cv2.waitKey (0) cv2.destroyAllWindows () cv2.waitKey (0)
Portanto, este código é igual ao código para detecção de rosto, mas aqui adicionamos cascatas de olhos e método para detectá-los, como você pode ver, escolhemos a versão em escala de cinza do rosto como parâmetro para detectMultiScale para os olhos, o que nos leva à redução da computação, já que vamos detectar olhos apenas naquela área.
Detecção de rosto e olhos ao vivo
Até agora, fizemos a detecção de rosto e olhos, agora vamos implementar o mesmo com a transmissão de vídeo ao vivo da webcam. Neste faremos a mesma detecção de rosto e olhos, mas desta vez faremos para a transmissão ao vivo da webcam. Na maior parte do aplicativo, você encontraria seu rosto destacado com uma caixa ao redor, mas aqui fizemos algo diferente que você encontraria seu rosto cortado e os olhos se identificariam apenas nisso.
Então, aqui estamos importando o classificador de rosto e olho, e definimos uma função para fazer todo o processamento de detecção de rosto e olhos. E depois disso começou o stream da webcam e chamou a função de detector de rosto para detectar o rosto e os olhos. O parâmetro que estamos definindo dentro da função do detector de rosto são as imagens contínuas do fluxo da webcam ao vivo
import cv2 import numpy as np face_classifier = cv2.CascadeClassifier ('haarcascade_frontalface_default.xml') eye_classifier = cv2.CascadeClassifier ('haarcascade_eye.xml') def face_detector (img, tamanho = v2.v2.v2.t): # Converter imagem em tons de cinza em cinza. (img, cv2.COLOR_BGR2GRAY) faces = face_classifier.detectMultiScale (cinza, 1.3, 5) se faces for (): retornar img para (x, y, w, h) em faces: x = x - 50 w = w + 50 y = y - 50 h = h + 50 cv2.rectangle (img, (x, y), (x + w, y + h), (255,0,0), 2) roi_gray = cinza roi_color = img eyes = eye_classifier.detectMultiScale (roi_gray) para (ex, ey, ew, eh) nos olhos: cv2.rectangle (roi_color, (ex, ey), (ex + ew, ey + eh), (0,0,255), 2) roi_color = cv2.flip (roi_color, 1) return roi_color cap = cv2.VideoCapture (0) enquanto True: ret, frame = cap.read () cv2.imshow ('Our Face Extractor', face_detector (frame)) if cv2.waitKey (1) == 13: # 13 é a quebra da chave Enter cap.release () cv2.destroyAllWindows ()
Ajustando Classificadores Cascade
Os parâmetros definidos dentro de detectMultiScale além da imagem de entrada têm o seguinte significado
ourClassifier. detectMultiScale (imagem de entrada, fator de escala, vizinhos mínimos)
- Fator de escala Especifica o quanto reduzimos o tamanho da imagem cada vez que dimensionamos. Por exemplo, na detecção de rosto, normalmente usamos 1.3. Isso significa que reduzimos a imagem em 30% cada vez que ela é dimensionada. Valores menores, como 1,05, levarão mais tempo para serem computados, mas aumentarão a taxa de detecção.
- Min Neighbours Especifica o número de vizinhos que cada janela potencial deve ter para considerá-la uma detecção positiva. Normalmente definido entre 3-6. Ele atua como configuração de sensibilidade, valores baixos às vezes detectam faces múltiplas em uma única face. Valores altos garantirão menos falsos positivos, mas você pode perder algumas faces.
Detecção de carros e pedestres em vídeos
Agora detectaremos pedestres e carros em vídeos usando as cascatas HAAR, mas caso nenhum vídeo seja carregado e o código seja compilado sem erro, você precisa seguir os seguintes passos:
Se nenhum vídeo carregar depois de executar o código, você pode precisar copiar nosso opencv_ffmpeg.dl de : opencv \ sources \ 3rdparty \ ffmpeg para colá-lo onde seu python está instalado, por exemplo, C: \ Anaconda2
Depois de copiado, você precisará renomear o arquivo de acordo com a versão do OpenCV que está usando.eg se estiver usando o OpenCV 2.4.13, renomeie o arquivo como: opencv_ffmpeg2413_64.dll ou opencv_ffmpeg2413.dll (se estiver usando uma máquina X86) opencv_ffmpeg310_64.dll ou opencv_ffmpeg310.dll (se você estiver usando uma máquina X86)
Para descobrir onde o python.exe está instalado, basta executar essas duas linhas de código, ele imprimirá o local onde o python está instalado.
import sys print (sys.executable)
Agora, se você realizou essas etapas com sucesso, vamos passar para o código de detecção de pedestres, Você pode ter a cascata para detecção de pedestres e do arquivo zip anexado aqui.
import cv2 import numpy as np # Crie nosso classificador de corpo body_classifier = cv2.CascadeClassifier ('haarcascade_fullbody.xml') # Iniciar a captura de vídeo para o arquivo de vídeo, aqui estamos usando o arquivo de vídeo no qual os pedestres seriam detectados cap = cv2.VideoCapture ('walking.avi') # Loop depois que o vídeo é carregado com sucesso enquanto cap.isOpened (): # Lendo cada quadro do ret de vídeo , frame = cap.read () # aqui estamos redimensionando o quadro, para metade do seu tamanho, estamos fazendo para acelerar a classificação # já que imagens maiores têm muito mais janelas para deslizar, portanto, no geral, reduzimos a resolução #de vídeo pela metade é o que 0,5 indica, e também estamos usando um método de interpolação mais rápido que é # frame interlinear = cv2.resize (frame, None, fx = 0,5, fy = 0,5, interpolation = cv2.INTER_LINEAR) gray = cv2. cvtColor (frame, cv2.COLOR_BGR2GRAY) # Passar frame para nosso classificador de corpo corpos = body_classifier.detectMultiScale (cinza, 1.2, 3) # Extrair caixas delimitadoras para quaisquer corpos identificados por (x, y, w, h) em corpos: cv2. retângulo (quadro, (x, y), (x + w, y + h), (0, 255, 255), 2) cv2.imshow ('Pedestres', quadro) se cv2.waitKey (1) == 13: # 13 é a quebra da chave Enter cap.release () cv2.destroyAllWindows ()
Depois de detectar pedestres em vídeo com sucesso, vamos passar para o código de detecção de carro. Você pode ter a cascata para detecção de pedestres aqui.
import cv2 import time import numpy as np # Criar nosso classificador de corpo car_classifier = cv2.CascadeClassifier ('haarcascade_car.xml') # Iniciar a captura de vídeo para o arquivo de vídeo cap = cv2.VideoCapture ('cars.avi') # Loop quando o vídeo for bem-sucedido carregado enquanto cap.isOpened (): time.sleep (.05) # Leia o primeiro quadro ret, frame = cap.read () grey = cv2.cvtColor (frame, cv2.COLOR_BGR2GRAY) # Passe o quadro para o classificador de nosso carro cars = car_classifier.detectMultiScale (grey, 1.4, 2) # Extraia caixas delimitadoras para quaisquer corpos identificados por (x, y, w, h) em carros: cv2.rectangle (frame, (x, y), (x + w, y + h), (0, 255, 255), 2) cv2.imshow ('Cars', frame) if cv2.waitKey (1) == 13: # 13 é a quebra da chave Enter cap.release () cv2.destroyAllWindows ()
Você notou que adicionamos time.sleep (.05) , é apenas um atraso na taxa de quadros para que você possa confirmar que todos os carros estão identificados corretamente, ou você pode removê-lo facilmente apenas adicionando um rótulo de comentário a ele.
Este artigo é referido a partir do curso Master Computer Vision ™ OpenCV4 em Python com Deep Learning na Udemy, criado por Rajeev Ratan, inscreva-se para aprender mais sobre Visão Computacional e Python.