[PYTHON] Rendre la rotation de détection d'objets OpenCV invariante

La quantité de fonctionnalités de haarcascade n'est pas invariante!

J'utilise Haarcascade_frontalface d'OpenCV pour reconnaître le visage, mais contrairement à SIFT et SURF, cela ne semble pas être une fonction invariante en rotation, et même si j'incline un peu le visage, le visage n'est pas reconnu.

Lors de la détection en temps réel avec une image de caméra, si vous mettez la caméra bien droite, elle sera reconnue raisonnablement parce que les gens ordinaires pointent la tête droite. Si vous détectez une photo qui est inclinée de cette manière par elle-même, elle ne sera pas reconnue correctement.

Show FACES Image_screenshot_18.09.2015.jpg Sur cette photo, seule Reni Takashiro, qui fait face droit devant elle, a détecté son visage.

Solution

L'idée est que si seulement un certain angle est reconnu, l'image elle-même doit être inclinée, et si toutes les images dont l'inclinaison est modifiée par petits pas sont jugées, toutes les faces inclinées seront détectées. droite.

Les étapes sont les suivantes

  1. Chargez l'image
  2. Préparez des images de ciel avec deux fois la hauteur et la largeur
  3. Inclinez l'image chargée de seulement 5 degrés
  4. Collez l'image inclinée au centre de l'image vide
  5. Jugez le visage
  6. Répétez les étapes 2 à 5

Cela ressemble à ceci sur la figure 回転不変.001.jpg

Code source

Ceci est le code source pour découper et enregistrer la photo du visage.

import cv2
import numpy as np
import os
from math import ceil

temp_face_img_path = 'work/temp/face/'

#Spécifiez le fichier xml utilisé pour le jugement de visage.
cascade_path =  os.path.dirname(os.path.abspath(__file__)) + "/haarcascade_frontalface_alt2.xml"

class classifyPhoto:
    def __init__(self):
        print("init")

    #Couper le visage de l'image, enregistrer, retourner le chemin
    def crop_face(self, img_path):
        #Analyse des noms de fichiers
        base_name = os.path.basename(img_path)
        name,ext = os.path.splitext(base_name)
        if (ext != '.jpg') and (ext != '.jpeg') :
            print('not a jpg image')
            return

        img_src = cv2.imread(img_path, 1)
        #Convertir en échelle de gris
        img_gray = cv2.cvtColor(img_src, cv2.COLOR_BGR2GRAY)
        cascade = cv2.CascadeClassifier(cascade_path)

        org_width = img_src.shape[1]
        org_height = img_src.shape[0]
        i = 0

        for j in range(0,71):
            #Créer une image agrandie
            big_img = np.zeros((org_height * 2, org_width * 2 ,3), np.uint8)
            big_img[ceil(org_height/2.0):ceil(org_height/2.0*3.0), ceil(org_width/2.0):ceil(org_width/2.0*3.0)] = img_src

            #Position centrale de l'image
            center = tuple(np.array([big_img.shape[1] * 0.5, big_img.shape[0] * 0.5]))

            #Obtenir la taille de l'image(côté,Verticale)
            size = tuple(np.array([big_img.shape[1], big_img.shape[0]]))

            #L'angle que vous souhaitez faire pivoter
            angle = 5.0 * float(j)
            #Taux d'expansion
            scale = 1.0

            #Calcul de la matrice de conversion de rotation
            rotation_matrix = cv2.getRotationMatrix2D(center, angle, scale)

            #Conversion d'affine
            img_rot = cv2.warpAffine(big_img, rotation_matrix, size, flags=cv2.INTER_CUBIC)
            rot_gray = cv2.cvtColor(img_rot, cv2.COLOR_BGR2GRAY)

            #Jugement de visage
            faces  =  cascade.detectMultiScale(img_rot, scaleFactor=1.2, minNeighbors=2, minSize=(50, 50))
            #S'il y a un visage
            if len(faces) > 0:
                for (x,y,w,h) in faces:
                    face = img_rot[y:y+h, x:x+w]
                    file_name =  name + "_face_" + str(i) + ext
                    cv2.imwrite(temp_face_img_path + file_name, face )
                    i += 1

            else :
                print('does not have any faces')

        return 

if __name__ == '__main__':
    classifier = classifyPhoto()
    classifier.crop_faceo('image.jpg')

résultat

回転不変.002.jpg

Considération

Il serait peut-être préférable de le régler, mais cela ne fonctionnera probablement pas.

Recommended Posts

Rendre la rotation de détection d'objets OpenCV invariante
Détection de visage avec Python + OpenCV (rotation invariante)
J'ai essayé la détection d'objets en utilisant Python et OpenCV
Outil de création de données d'entraînement pour la détection d'objets OpenCV
Essayez la détection des bords avec OpenCV
Détection de caractéristiques à l'aide d'opencv (détection de coin)
Détection des bords en temps réel avec OpenCV
Rendre Opencv disponible en Python
Détection de visage avec Python + OpenCV
Détection de visage d'anime avec OpenCV