- Detección de objetos mediante SIFT
- Detección de objetos mediante ORB
- Histograma de gradientes orientados (HOG)
- Histograma de gradientes orientados (HOG), paso a paso:
- Clasificadores en cascada HAAR
- Detección de rostro y ojos
- Detección de rostros y ojos en vivo
- Ajuste de clasificadores en cascada
- Detección de automóviles y peatones en videos
Comenzamos con la instalación de Python OpenCV en Windows y hasta ahora hicimos un procesamiento básico de imágenes, segmentación de imágenes y detección de objetos usando Python, que se tratan en los siguientes tutoriales:
- Introducción a Python OpenCV: instalación y procesamiento básico de imágenes
- Manipulaciones de imágenes en Python OpenCV (Parte 1)
- Manipulaciones de imágenes en OpenCV (Parte 2)
- Segmentación de imágenes mediante OpenCV: extracción de áreas específicas de una imagen
También aprendimos sobre varios métodos y algoritmos para la detección de objetos donde se identificaron algunos puntos clave para cada objeto utilizando diferentes algoritmos. En este tutorial vamos a usar esos algoritmos para detectar objetos de la vida real, aquí estaríamos usando SIFT y ORB para la detección.
Detección de objetos mediante SIFT
Aquí, la detección de objetos se realizará mediante la transmisión en vivo de la cámara web, por lo que si reconoce el objeto, mencionará el objeto encontrado. En el código, el papel principal lo desempeña la función que se llama detector SIFT, esta función realiza la mayor parte del procesamiento.
Y en la otra mitad del código, comenzamos abriendo el flujo de la cámara web, luego cargamos la plantilla de imagen, es decir, la imagen de referencia, es decir, el programa está mirando a través del flujo de la cámara web.
A continuación, se están capturando continuamente las imágenes de la corriente de cámaras con la ayuda de infinito mientras bucle, y luego la captura de la altura correspondiente y anchura del marco webcam, y después de entonces definir los parámetros de la región de interés caja (ROI) en el cual nuestro objeto puede encajar tomando la altura y el ancho correspondientes del marco de la cámara web. Y luego dibujamos el rectángulo a partir de los parámetros de ROI que habíamos definido anteriormente. Luego, finalmente, recorte el rectángulo e introdúzcalo en la parte del código del detector SWIFT.
Ahora el detector SIFT básicamente tiene dos entradas, una es la imagen recortada y la otra es la plantilla de imagen que definimos previamente y luego nos da algunas coincidencias, por lo que las coincidencias son básicamente la cantidad de objetos o puntos clave que son similares en la imagen recortada. y la imagen de destino. Luego definimos un valor de umbral para las coincidencias, si el valor de las coincidencias es mayor que el umbral, colocamos la imagen encontrada en nuestra pantalla con el color verde del rectángulo de ROI.
Ahora volvamos a la parte principal del código, la función que se llama como detector SIFT, toma la entrada como dos imágenes, una es la imagen donde está buscando el objeto y otra es el objeto que estamos tratando de hacer coincidir a (plantilla de imagen). Luego, aplique escala de grises a la primera imagen y defina la plantilla de imagen como segunda imagen. Luego creamos un objeto detector SIFT y ejecutamos la función de detección y cálculo de SIFT de OpenCV, para detectar los puntos clave y calcular los descriptores, los descriptores son básicamente los vectores que almacenan la información sobre los puntos clave, y es realmente importante ya que hacemos la comparación entre los descriptores de las imágenes.
Y luego defina el comparador basado en FLANN, no vamos a entrar en la teoría matemática del emparejamiento detrás de él, pero puede buscarlo fácilmente en Google. Primero definimos el índice kdtree a cero y luego configuramos el índice y los parámetros de búsqueda en el formato de diccionario, solo definimos el algoritmo que vamos a usar que es KDTREE, y la cantidad de árboles que vamos a usar, más árbol usamos cuanto más complicado se vuelve y más lento. Y en el parámetro de búsqueda defina el número de comprobaciones, que es básicamente el número de coincidencias que va a completar.
Y luego cree nuestro objeto comparador basado en FLANN cargando el parámetro que definimos previamente, que son parámetros de índice y parámetros de búsqueda, y en base a esto cree nuestro comparador basado en FLANN, que es un comparador KNN donde KNN es K-vecinos más cercanos, básicamente es una forma en que buscamos emparejadores y descriptores más cercanos y hacemos el emparejamiento con la constante de inicialización k. Ahora, este comparador basado en FLANN devuelve el número de coincidencias que obtenemos.
La coincidencia basada en FLANN es solo una aproximación, para aumentar la precisión del comparador basado en FLANN, realizamos una prueba de relación de Lowe's y lo que hace es buscar las coincidencias del comparador basado en knn flann y definir algunos parámetros matriciales que es la distancia aquí, para la cual la distancia es una función numerosa, y una vez que cumple con los criterios, agrega las coincidencias a las buenas coincidencias y devuelve las buenas coincidencias encontradas, por lo que la transmisión de video en vivo indica la cantidad de coincidencias encontradas en la esquina de la pantalla.
Ahora veamos el código de la descripción anterior:
import cv2 import numpy as np def sift_detector (new_image, image_template): # Función que compara la imagen de entrada con la plantilla # Luego devuelve el número de coincidencias de SIFT entre ellas image1 = cv2.cvtColor (new_image, cv2.COLOR_BGR2GRAY) image2 = image_template # Crear Objeto detector SIFT #sift = cv2.SIFT () sift = cv2.xfeatures2d.SIFT_create () # Obtenga los puntos clave y descriptores usando SIFT keypoints_1, descriptors_1 = sift.detectAndCompute (image1, None) keypoints_2, descriptors_2 = sift.detectAndCompute (image2, Ninguno) # Definir parámetros para nuestro Flann Matcher FLANN_INDEX_KDTREE = 0 index_params = dict (algoritmo = FLANN_INDEX_KDTREE, árboles = 3) search_params = dict (checks = 100) # Crear el objeto Flann Matcher flann = cv2.FlannBasedMatcher (index_params, search_params) # Obtener coincidencias usando el método K- Nerther Neighbor # el resultado 'matchs' es el número de coincidencias similares encontradas en ambas coincidencias de imágenes = flann.knnMatch (descriptors_1, descriptors_2, k = 2) # tienda partidos buenos usando la prueba de relación de Lowe good_matches = para m, n en los partidos: si m.distance <0,7 * n.distance: good_matches.append (m) de retorno len (good_matches) cap = cv2.VideoCapture (0) # Cargue nuestra plantilla de imagen, esta es nuestra imagen de referencia image_template = cv2.imread ('phone.jpg', 0) while True: # Obtenga imágenes de la cámara web ret, frame = cap.read () # Obtiene la altura y el ancho de la altura del marco de la cámara web , width = frame.shape # Definir las dimensiones del cuadro de ROI top_left_x = int (width / 3) top_left_y = int ((height / 2) + (height / 4)) bottom_right_x = int ((width / 3) * 2) bottom_right_y = int ((height / 2) - (height / 4)) # Dibujar una ventana rectangular para nuestra región de interés cv2.rectangle (frame, (top_left_x, top_left_y), (bottom_right_x, bottom_right_y), 255, 3) # Recortar ventana de observación que definimos arriba recortada = marco # Voltear la orientación del marco horizontalmente frame = cv2.flip (frame, 1) # Obtener el número de coincidencias SIFT coincide = sift_detector (recortado, image_template) # Muestra la cadena de estado que muestra el número actual. de coincidencias cv2.putText (frame, str (coincidencias), (450,450), cv2.FONT_HERSHEY_COMPLEX, 2, (0,255,0), 1) # Nuestro umbral para indicar la detección de objetos # Usamos 10 ya que el detector SIFT devuelve pequeños falsos positivos umbral = 10 # Si las coincidencias superan nuestro umbral, entonces se ha detectado el objeto si coincidencias> umbral: 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 objetos usando SIFT', marco) if cv2.waitKey (1) == 13: # 13 es la clave de entrada de salto cap.release () cv2.destroyAllWindows ()
Detección de objetos mediante ORB
La detección de objetos usando SIFT es bastante interesante y precisa, ya que genera un número muy preciso de coincidencias basadas en puntos clave, sin embargo, está patentado y eso dificulta su uso para aplicaciones comerciales, la otra salida es el algoritmo ORB para la detección de objetos.
Similar al método de detección de objetos por SIFT en el que dividimos el programa en dos partes, aquí se seguirá el mismo.
En primer lugar, definimos la función ORB_detector que toma dos entradas, una es la imagen de transmisión en vivo proveniente de la cámara web y la otra es la plantilla de imagen sobre la base de la cual vamos a hacer coincidir nuestra imagen. Luego, escalamos la imagen de nuestra cámara web en escala de grises y luego inicializamos nuestro detector ORB, y lo configuramos aquí en 1000 puntos clave y parámetros de escala de 1.2. puede jugar fácilmente con estos parámetros, luego detectar los puntos clave (kp) y los descriptores (des) para las imágenes y el segundo parámetro que estamos definiendo en la función detectANDCompute es NINGUNO, está solicitando el uso de máscara de imagen o no y lo estamos negando aquí.
Luego muévete al detector que anteriormente hemos estado usando el comparador basado en FLANN, pero aquí usaremos BFMatcher y dentro de BFMatcher definimos dos parámetros, uno es NORM_HAMMING y el otro es el crossCheck cuyo valor es TRUE.
Luego, calcule las coincidencias entre esas dos imágenes utilizando los descriptores definidos anteriormente, que en general devuelve el número de coincidencias, ya que estas coincidencias no son aproximadas y, por lo tanto, no es necesario realizar la prueba de relación de Lowe's, sino que ordenamos las coincidencias en función de la distancia., al menos la distancia más coincidencia es mejor (aquí la distancia significa la distancia entre los puntos), y al final devolvemos el número de coincidencias usando la función de longitud.
Y en la función principal establecemos el umbral en un valor mucho más alto, ya que el detector de orbes genera mucho ruido.
Ahora veamos el código para la detección basada en ORB
import cv2 import numpy as np def ORB_detector (new_image, image_template): # Función que compara la imagen de entrada con la plantilla # Luego devuelve el número de coincidencias de ORB entre ellas image1 = cv2.cvtColor (new_image, cv2.COLOR_BGR2GRAY) # Crear detector de ORB con 1000 puntos clave con un factor de escala de pirámide de 1.2 orb = cv2.ORB_create (1000, 1.2) # Detectar puntos clave de la imagen original (kp1, des1) = orb.detectAndCompute (imagen1, Ninguno) # Detectar puntos clave de la imagen rotada (kp2, des2) = orb.detectAndCompute (image_template, None) # Create matcher # Tenga en cuenta que ya no usamos la coincidencia basada en Flann bf = cv2.BFMatcher (cv2.NORM_HAMMING, crossCheck = True) # Hacer coincidencias = bf.match (des1, des2) # Ordenar las coincidencias según la distancia. Distancia mínima # es mejor coincidencias = ordenado (coincidencias, clave = lambda val: val.distance) return len (coincidencias) cap = cv2.VideoCapture (0) # Cargue nuestra plantilla de imagen, esta es nuestra imagen de referencia image_template = cv2.imread ('phone.jpg', 0) # image_template = cv2.imread ('images / kitkat.jpg', 0) while True: # Obtener imágenes de la cámara web ret, frame = cap.read () # Obtener la altura y el ancho de la altura del marco de la cámara web , width = frame.shape # Definir las dimensiones del cuadro de ROI (tenga en cuenta que algunas de estas cosas deben estar fuera del bucle) top_left_x = int (width / 3) top_left_y = int ((altura / 2) + (altura / 4)) bottom_right_x = int ((ancho / 3) * 2) bottom_right_y = int ((altura / 2) - (altura / 4)) # Dibujar ventana rectangular para nuestro región de interés cv2.rectangle (frame, (top_left_x, top_left_y), (bottom_right_x, bottom_right_y), 255, 3) # Recortar la ventana de observación que definimos arriba cropped = frame # Voltear la orientación del marco horizontalmente frame = cv2.flip (frame, 1) # Obtener el número de coincidencias de ORB = ORB_detector (recortado, image_template) # Mostrar cadena de estado que muestra el número actual. de coincidencias output_string = "Matches =" + str (coincidencias) cv2.putText (frame, output_string, (50,450), cv2.FONT_HERSHEY_COMPLEX, 2, (250,0,150), 2) # Nuestro umbral para indicar la detección de objetos # Para imágenes nuevas o condiciones de iluminación, es posible que deba experimentar un poco # Nota: El detector de ORB para obtener las 1000 coincidencias principales, 350 es esencialmente un umbral mínimo de coincidencia del 35% = 250 # Si las coincidencias superan nuestro umbral, entonces el objeto ha sido detectado si coincide> umbral: 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 ('Detector de objetos usando ORB', marco) if cv2.waitKey (1) == 13: # 13 es el límite de interrupción de la tecla Enter .release () cv2.destroyAllWindows ()
Histograma de gradientes orientados (HOG)
Ahora hablemos de un descriptor diferente que es Histograma de gradientes orientados (HOG).
Los HOG son descriptores bastante interesantes y útiles y se utilizan ampliamente y con éxito para la detección de objetos, como se vio anteriormente, los descriptores de imágenes como SIFT y ORB, donde tenemos que calcular puntos clave y luego tenemos que calcular descriptores a partir de esos puntos clave, los HOG hacen ese proceso. diferentemente. Se representa objetos como un único vector de características en comparación con un conjunto de vectores de características, donde cada uno representa un segmento de la imagen. Significa que tenemos una función de vector único para toda la imagen.
Se calcula mediante un detector de ventana deslizante sobre una imagen, donde se calcula un descriptor HOG para cada posición. Y luego cada posición se combina para un único vector de características.
Al igual que SIFT, la escala de la imagen se ajusta piramidalmente.
Anteriormente, hemos usado comparadores como FLANN y BFMatcher, pero los HOG lo hacen de manera diferente con la ayuda de clasificadores SVM (máquina de vectores de soporte), donde cada descriptor HOG que se calcula se alimenta a un clasificador SVM para determinar si el objeto fue encontrado o no.
Aquí está el enlace a un gran artículo de Dalal & Triggs sobre el uso de HOG para la detección humana:
Histograma de gradientes orientados (HOG), paso a paso:
Comprender los HOG puede ser bastante complejo, pero aquí solo vamos a tratar la teoría de los HOG sin profundizar en las matemáticas relacionadas con ella.
Así que tomemos esta imagen que está un poco pixelada, y en la esquina superior hay un cuadro de 8x8 píxeles aquí, por lo que en este cuadro calculamos el vector de degradado o las orientaciones de los bordes en cada píxel. Entonces significa que en este cuadro calculamos el vector de degradado de imagen de píxeles dentro del cuadro (son una especie de dirección o flujo de la intensidad de la imagen en sí), y esto genera 64 (8 x 8) vectores de degradado que luego se representan como un histograma. Así que imagine un histograma que represente cada vector de gradiente. Entonces, si todos los puntos o intensidades se encuentran en una dirección, el histograma para esa dirección, digamos 45 grados, el histograma tendría un pico a 45 grados.
Entonces, lo que hacemos ahora es dividir cada celda en contenedores angulares, donde cada contenedor corresponde a una dirección de gradiente (por ejemplo, x, y). En el artículo de Dalal y Triggs, utilizaron 9 contenedores 0-180 ° (20 ° cada contenedor). Esto reduce efectivamente 64 vectores a solo 9 valores. Entonces, lo que hemos hecho es reducir el tamaño pero conservar toda la información clave que se necesita.
El siguiente paso en el cálculo del cerdo es la normalización, normalizamos los gradientes para garantizar la invariancia a los cambios de iluminación, es decir, brillo y contraste.
En esta imagen, los valores de intensidad se muestran en el cuadrado de acuerdo con la dirección respectiva y todos tienen una diferencia de 50 entre sí.
∆ H = 50, ∆ v = 50; │∆│ = √50 2 +50 = 70,72, 70,72 / 100 = 0,707
Dividimos los vectores por las magnitudes de gradiente y obtenemos 0.707 para todos, esto es normalización.
Del mismo modo, si cambiamos la intensidad o cambiamos el contraste obtenemos los siguientes valores.
∆ 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
La normalización no tiene lugar a nivel de celda, sino que tiene lugar a nivel de bloque, por lo que aquí los bloques son básicamente un grupo de 4 celdas, esto tiene en cuenta los bloques vecinos, así que normalícelos teniendo en cuenta segmentos más grandes de la imagen.
Ahora veamos el código
import numpy as np import cv2 import matplotlib.pyplot as plt # Cargar imagen y luego en escala de grises image = cv2.imread ('elephant.jpg') gray = cv2.cvtColor (image, cv2.COLOR_BGR2GRAY) # Mostrar imagen original cv2.imshow (' Input Image ', image) cv2.waitKey (0) # definiendo los parámetros, tamaño de celda y tamaño de bloque # hxw en píxeles cell_size = (8, 8) # hxw en celdas block_size = (2, 2) # número de contenedores de orientación nbins = 9 # Usando el descriptor HOG de OpenCV # winSize es el tamaño de la imagen recortada a un múltiplo del tamaño de la celda 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) # Creamos una forma de matriz numpy para crear hog_features n_cells = (gray.shape // cell_size, gray.shape // cell_size) # Primero indexamos bloques por filas. # hog_feats ahora contiene las amplitudes de gradiente para cada dirección, # para cada celda de su grupo para cada grupo. La indexación es por filas y luego por columnas. hog_feats = hog.compute (gris).reshape (n_cells - block_size + 1, n_cells - block_size + 1, block_size, block_size, nbins).transpose ((1, 0, 2, 3, 4)) # Cree nuestra matriz de gradientes con dimensiones nbin para almacenar orientaciones de gradientes gradients = np.zeros ((n_cells, n_cells, nbins)) # Cree una matriz de dimensiones cell_count = np.full ((n_cells, n_cells, 1), 0, dtype = int) # Normalización de bloque para off_y en rango (block_size): para off_x en rango (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 promedio gradients / = cell_count # Trazar HOGs usando Matplotlib # el ángulo es 360 / nbins * dirección color_bins = 5 plt.pcolor (gradientes) plt.gca (). invert_yaxis () plt.gca (). set_aspect ('igual', ajustable = 'caja') plt.colorbar () plt.show () cv2.destroyAllWindows ()
La imagen muestra cómo se representa la imagen de entrada como representación HOG.
Clasificadores en cascada HAAR
Como se discutió anteriormente, podemos extraer características de una imagen y usar esas características para clasificar o detectar objetos.
¿Qué son los clasificadores en cascada HAAR?
Un método de detección de objetos que introduce características de Haar en una serie de clasificadores (cascada) para identificar objetos en una imagen. Están entrenados para identificar un tipo de objeto, sin embargo, podemos usar varios de ellos en paralelo, por ejemplo, detectando ojos y rostros juntos.
Clasificadores HAAR explicados:
Los clasificadores HAAR se entrenan usando muchas imágenes positivas (es decir, imágenes con el objeto presente) e
imágenes negativas (es decir, imágenes sin el objeto presente).
Una vez que tenemos esas imágenes, extraemos características usando ventanas deslizantes de bloques rectangulares. Estas características (características HAAR) tienen un solo valor y se calculan restando la suma de las intensidades de píxeles debajo de los rectángulos blancos de los rectángulos negros.
Sin embargo, esta es una cantidad ridícula de cálculos, incluso para una ventana base de 24 x 24 píxeles (180.000 características generadas).
Entonces, los investigadores idearon un método llamado Imágenes integrales que computaron esto con cuatro referencias de matriz. Sin embargo, todavía tenían 180.000 funciones y la mayoría de ellas no agregaban valor real.
Luego, se utilizó el impulso para determinar las características más informativas, con AdaBoost de Freund & Schapire y se encontró la mayoría de las características informativas en la imagen. El impulso es el proceso mediante el cual usamos clasificadores débiles para construir clasificadores fuertes, simplemente asignando penalizaciones ponderadas más severas a clasificaciones incorrectas. Reducir las 180.000 funciones a 6000, que todavía son bastantes funciones.
En esas 6000 funciones, algunas serán más informativas que otras. Entonces, si usamos las características más informativas para verificar primero si la región puede tener una cara (los falsos positivos no serán un gran problema). Hacerlo elimina la necesidad de calcular todas las 6000 características a la vez. Este concepto se llama Cascade of Classifiers: para la detección de rostros, el método Viola Jones utilizó 38 etapas.
Detección de rostro y ojos
Entonces, después de obtener algunos conocimientos teóricos sobre las cascadas HAAR, finalmente lo implementaremos, para dejar las cosas bastante claras, dividiremos las lecciones en partes, primero detectaríamos la cara frontal, luego nos moveremos para detectar la cara frontal con ojos y finalmente haríamos detección en vivo de rostro y ojos a través de la webcam.
Entonces, para esto, usaremos clasificadores previamente entrenados que han sido proporcionados por OpenCV como archivos.xml, xml significa lenguaje de marcado extensible, este lenguaje se usa para almacenar una gran cantidad de datos, incluso podría construir una base de datos en él.
Puede acceder a estos clasificadores en este enlace .
Detección de rostro
Probemos para la detección de rostros frontales, puede tener el acceso para la cascada del detector de rostros frontales aquí. Simplemente extraiga el archivo zip para obtener el archivo xml.
import numpy as np import cv2 # Apuntamos la función CascadeClassifier de OpenCV a donde está almacenado nuestro # clasificador (formato de archivo XML), recuerde mantener el código y el clasificador en la misma carpeta face_cascade = cv2.CascadeClassifier ('haarcascade_frontalface_default.xml') # Cargar nuestra imagen luego convertirla a escala de grises image = cv2.imread ('Trump.jpg') gray = cv2.cvtColor (image, cv2.COLOR_BGR2GRAY) # Nuestro clasificador devuelve el ROI de la cara detectada como una tupla # Almacena la parte superior izquierda coordenada y las coordenadas de abajo a la derecha # devuelve la lista de listas, que son la ubicación de las diferentes caras detectadas. caras = face_cascade.detectMultiScale (gris, 1.3, 5) # Cuando no se detectan caras, face_classifier regresa y una tupla vacía si las caras son (): print ("No se encontraron caras") # Repetimos nuestra matriz de caras y dibujamos un rectángulo # sobre cada cara en las caras para (x, y, w, h) en caras: cv2.rectangle (imagen, (x, y), (x + w, y + h), (127,0,255), 2) cv2.imshow ('Detección facial', imagen) cv2.waitKey (0) cv2.destroyAllWindows ()
Ahora combinemos la detección de rostro y ojos juntos, puede tener el acceso para la cascada del detector de ojos en el mismo archivo zip.
import numpy as np import cv2 face_classifier = cv2.CascadeClassifier ('haarcascade_frontalface_default.xml') eye_classifier = cv2.CascadeClassifier ('haarcascade_eye.xml') img = cv2.imread ('Trump.jpg') gris = cv2.cv2. cv2.COLOR_BGR2GRAY) faces = face_classifier.detectMultiScale (gray, 1.3, 5) # Cuando no se detectan caras, face_classifier regresa y una tupla vacía si las caras son (): print ("No Face Found") para (x, y, w, h) en caras: cv2.rectangle (img, (x, y), (x + w, y + h), (127,0,255), 2) cv2.imshow ('img', img) roi_gray = gris roi_color = img eyes = eye_classifier.detectMultiScale (roi_gray) cv2.waitKey (0) para (ex, ey, ew, eh) en ojos: 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)
Así que este código es el mismo que el código para la detección de rostros, pero aquí hemos agregado cascadas de ojos y un método para detectarlos, como puede ver, hemos elegido la versión en escala de grises de la cara como parámetro para el detectMultiScale para los ojos, lo que nos lleva a la reducción en el cálculo ya que solo vamos a detectar ojos solo en esa área.
Detección de rostros y ojos en vivo
Así que hasta ahora hemos hecho detección de rostros y ojos, ahora implementemos lo mismo con la transmisión de video en vivo desde la cámara web. En esto haremos la misma detección de rostro y ojos pero esta vez lo haremos para la transmisión en vivo desde la webcam. En la mayor parte de la aplicación, encontrará su rostro resaltado con un cuadro alrededor, pero aquí hemos hecho algo diferente que encontrará su rostro recortado y los ojos se identificarán solo en eso.
Así que aquí estamos importando tanto el clasificador de rostro como el de ojos, y definimos una función para hacer todo el procesamiento de la detección de rostro y ojo. Y después de eso, comenzó la transmisión de la cámara web y llamó a la función de detector de rostros para detectar la cara y los ojos. El parámetro que estamos definiendo dentro de la función del detector facial son las imágenes continuas de la transmisión de la cámara web en 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, tamaño = 0.5): # Convertir imagen a escala de grises cv2.c (img, cv2.COLOR_BGR2GRAY) faces = face_classifier.detectMultiScale (gray, 1.3, 5) si las caras son (): devuelve img para (x, y, w, h) en caras: 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 = gris roi_color = img ojos = eye_classifier.detectMultiScale (roi_gray) para (ex, ey, ew, eh) en ojos: 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) while True: ret, frame = cap.read () cv2.imshow ('Our Face Extractor', face_detector (frame)) if cv2.waitKey (1) == 13: # 13 es la clave Enter break cap.release () cv2.destroyAllWindows ()
Ajuste de clasificadores en cascada
Los parámetros definidos dentro de detectMultiScale distintos de la imagen de entrada tienen el siguiente significado
ourClassifier. detectMultiScale (imagen de entrada, factor de escala, vecinos mínimos)
- Factor de escala Especifica cuánto reducimos el tamaño de la imagen cada vez que escalamos. Por ejemplo, en la detección de rostros normalmente usamos 1.3. Esto significa que reducimos la imagen en un 30% cada vez que se escala. Los valores más pequeños, como 1.05, tardarán más en calcularse, pero aumentarán la tasa de detección.
- Vecinos mínimos Especifica el número de vecinos que debe tener cada ventana potencial para considerarla una detección positiva. Normalmente se establece entre 3-6. Actúa como ajuste de sensibilidad, los valores bajos a veces detectan múltiples caras sobre una sola cara. Los valores altos asegurarán menos falsos positivos, pero es posible que se pierdan algunas caras.
Detección de automóviles y peatones en videos
Ahora detectaremos peatones y automóviles en videos usando las cascadas HAAR, pero en el caso de que no se cargue ningún video y el código se compile sin un error, debe seguir los siguientes pasos:
Si no se carga ningún video después de ejecutar el código, es posible que deba copiar nuestro opencv_ffmpeg.dl de : opencv \ sources \ 3rdparty \ ffmpeg para pegarlo donde está instalado su python, por ejemplo, C: \ Anaconda2
Una vez que se haya copiado, deberá cambiar el nombre del archivo de acuerdo con la versión de OpenCV que esté usando.eg si está usando OpenCV 2.4.13, luego cambie el nombre del archivo a: opencv_ffmpeg2413_64.dll o opencv_ffmpeg2413.dll (si está usando una máquina X86) opencv_ffmpeg310_64.dll o opencv_ffmpeg310.dll (si está usando una máquina X86)
Para saber dónde está instalado python.exe, simplemente ejecute estas dos líneas de código, imprimirá la ubicación donde está instalado Python.
importar impresión del sistema (sys.executable)
Ahora, si ha realizado estos pasos con éxito, pasemos al código para la detección de peatones, Puede tener la cascada para la detección de peatones y desde el archivo zip adjunto aquí.
import cv2 import numpy as np # Crea nuestro clasificador corporal body_classifier = cv2.CascadeClassifier ('haarcascade_fullbody.xml') # Inicia la captura de video para el archivo de video, aquí estamos usando el archivo de video en el que se detectarían peatones cap = cv2.VideoCapture ('walking.avi') # Repetir una vez que el video se cargue correctamente mientras cap.isOpened (): # Leyendo cada fotograma del video ret, frame = cap.read () # aquí estamos cambiando el tamaño del fotograma, a la mitad de su tamaño, lo estamos haciendo para acelerar la clasificación # ya que las imágenes más grandes tienen muchas más ventanas para deslizar, por lo que en general reducimos la resolución # de video por la mitad eso es lo que indica 0.5, y también estamos usando un método de interpolación más rápido que es #interlinear frame = cv2.resize (frame, None, fx = 0.5, fy = 0.5, interpolation = cv2.INTER_LINEAR) gray = cv2. cvtColor (frame, cv2.COLOR_BGR2GRAY) # Pasar el frame a nuestro clasificador de cuerpos bodies = body_classifier.detectMultiScale (gray, 1.2, 3) # Extraer cuadros delimitadores para cualquier cuerpo identificado para (x, y, w, h) en cuerpos: cv2. rectangle (frame, (x, y), (x + w, y + h), (0, 255, 255), 2) cv2.imshow ('Peatones', frame) if cv2.waitKey (1) == 13: # 13 es el salto de tecla Enter cap.release () cv2.destroyAllWindows ()
Después de detectar con éxito un peatón en video, pasemos al código para la detección de automóviles. Puede tener la cascada para la detección de peatones desde aquí.
import cv2 import time import numpy as np # Crea nuestro clasificador de cuerpo car_classifier = cv2.CascadeClassifier ('haarcascade_car.xml') # Inicia la captura de video para el archivo de video cap = cv2.VideoCapture ('cars.avi') # Repite una vez que el video es exitoso cargado mientras cap.isOpened (): time.sleep (.05) # Leer el primer cuadro ret, frame = cap.read () gray = cv2.cvtColor (frame, cv2.COLOR_BGR2GRAY) # Pasar el cuadro a nuestro clasificador de coches cars = car_classifier.detectMultiScale (gray, 1.4, 2) # Extrae los cuadros delimitadores para cualquier cuerpo identificado para (x, y, w, h) en automóviles: cv2.rectangle (frame, (x, y), (x + w, y + h), (0, 255, 255), 2) cv2.imshow ('Cars', frame) si cv2.waitKey (1) == 13: # 13 es la tecla Enter break cap.release () cv2.destroyAllWindows ()
Ha notado que hemos agregado time.sleep (.05) , es solo un retraso en la velocidad de fotogramas para que pueda confirmar que todos los autos están identificados correctamente, o puede eliminarlo fácilmente simplemente agregando una etiqueta de comentario.
Este artículo es una referencia del curso Master Computer Vision ™ OpenCV4 en Python con Deep Learning en Udemy, creado por Rajeev Ratan, suscríbase para obtener más información sobre Computer Vision y Python.