webentwicklung-frage-antwort-db.com.de

Erkennen Sie das Gesicht und lassen Sie Bilder automatisch abschneiden

Ich versuche, eine App zu finden, die Gesichter in meinen Bildern erkennen kann, das erkannte Gesicht zentrieren und 720 x 720 Pixel des Bildes beschneiden kann. Es ist ziemlich zeitaufwändig und akribisch, hunderte von Bildern zu bearbeiten, die ich vorhabe.

Ich habe versucht, dies mit python opencv zu tun , aber ich denke, es ist veraltet. Ich habe auch mit diesem versucht, aber es gibt mir auch einen Fehler in meinem System. Es wurde auch versucht, das Gesichtserkennungs-Plugin für GIMP zu verwenden, aber es wurde für GIMP 2.6 entwickelt, ich verwende jedoch regelmäßig 2.8. Ich habe auch versucht, das zu tun, was auf ultrahigh blog gepostet wurde, aber es ist sehr veraltet (da ich ein Precise-Derivat von Ubuntu verwende, während der Blogpost vor langer Zeit als Hardy erstellt wurde). Es wurde auch mit Phatch versucht, aber es gibt keine Gesichtserkennung, so dass einige abgeschnittene Bilder sofort abgeschnitten werden.

Ich habe all das oben Genannte ausprobiert und einen halben Tag damit verbracht, zu versuchen, das zu tun, was ich tun musste.

Haben Sie einen Vorschlag, ein Ziel von etwa 800 Bildern zu erreichen, die ich habe.

Mein Betriebssystem ist Linux Mint 13 MATE.

Hinweis: Ich wollte noch zwei weitere Links hinzufügen, aber Stackexchange hat mich daran gehindert, zwei weitere Links zu posten, da ich noch keinen guten Ruf habe.

50
AisIceEyes

Ich habe es geschafft, Code aus verschiedenen Quellen zu packen und diesen zusammenzusetzen. Es ist noch ein work in progress. Hast du auch Beispielbilder?

'''
Sources:
http://pythonpath.wordpress.com/2012/05/08/pil-to-opencv-image/
http://www.lucaamore.com/?p=638
'''

#Python 2.7.2
#Opencv 2.4.2
#PIL 1.1.7

import cv
import Image

def DetectFace(image, faceCascade):
    #modified from: http://www.lucaamore.com/?p=638

    min_size = (20,20)
    image_scale = 1
    haar_scale = 1.1
    min_neighbors = 3
    haar_flags = 0

    # Allocate the temporary images
    smallImage = cv.CreateImage(
            (
                cv.Round(image.width / image_scale),
                cv.Round(image.height / image_scale)
            ), 8 ,1)

    # Scale input image for faster processing
    cv.Resize(image, smallImage, cv.CV_INTER_LINEAR)

    # Equalize the histogram
    cv.EqualizeHist(smallImage, smallImage)

    # Detect the faces
    faces = cv.HaarDetectObjects(
            smallImage, faceCascade, cv.CreateMemStorage(0),
            haar_scale, min_neighbors, haar_flags, min_size
        )

    # If faces are found
    if faces:
        for ((x, y, w, h), n) in faces:
            # the input to cv.HaarDetectObjects was resized, so scale the
            # bounding box of each face and convert it to two CvPoints
            pt1 = (int(x * image_scale), int(y * image_scale))
            pt2 = (int((x + w) * image_scale), int((y + h) * image_scale))
            cv.Rectangle(image, pt1, pt2, cv.RGB(255, 0, 0), 5, 8, 0)

    return image

def pil2cvGrey(pil_im):
    #from: http://pythonpath.wordpress.com/2012/05/08/pil-to-opencv-image/
    pil_im = pil_im.convert('L')
    cv_im = cv.CreateImageHeader(pil_im.size, cv.IPL_DEPTH_8U, 1)
    cv.SetData(cv_im, pil_im.tostring(), pil_im.size[0]  )
    return cv_im

def cv2pil(cv_im):
    return Image.fromstring("L", cv.GetSize(cv_im), cv_im.tostring())


pil_im=Image.open('testPics/faces.jpg')
cv_im=pil2cv(pil_im)
#the haarcascade files tells opencv what to look for.
faceCascade = cv.Load('C:/Python27/Lib/site-packages/opencv/haarcascade_frontalface_default.xml')
face=DetectFace(cv_im,faceCascade)
img=cv2pil(face)
img.show()

Testen auf der ersten Seite von Google (googled "Gesichter"): enter image description here


Update

Dieser Code sollte genau das tun, was Sie möchten. Lass es mich wissen, wenn du fragen hast. Ich habe versucht, viele Kommentare in den Code aufzunehmen:

'''
Sources:
http://opencv.willowgarage.com/documentation/python/cookbook.html
http://www.lucaamore.com/?p=638
'''

#Python 2.7.2
#Opencv 2.4.2
#PIL 1.1.7

import cv #Opencv
import Image #Image from PIL
import glob
import os

def DetectFace(image, faceCascade, returnImage=False):
    # This function takes a grey scale cv image and finds
    # the patterns defined in the haarcascade function
    # modified from: http://www.lucaamore.com/?p=638

    #variables    
    min_size = (20,20)
    haar_scale = 1.1
    min_neighbors = 3
    haar_flags = 0

    # Equalize the histogram
    cv.EqualizeHist(image, image)

    # Detect the faces
    faces = cv.HaarDetectObjects(
            image, faceCascade, cv.CreateMemStorage(0),
            haar_scale, min_neighbors, haar_flags, min_size
        )

    # If faces are found
    if faces and returnImage:
        for ((x, y, w, h), n) in faces:
            # Convert bounding box to two CvPoints
            pt1 = (int(x), int(y))
            pt2 = (int(x + w), int(y + h))
            cv.Rectangle(image, pt1, pt2, cv.RGB(255, 0, 0), 5, 8, 0)

    if returnImage:
        return image
    else:
        return faces

def pil2cvGrey(pil_im):
    # Convert a PIL image to a greyscale cv image
    # from: http://pythonpath.wordpress.com/2012/05/08/pil-to-opencv-image/
    pil_im = pil_im.convert('L')
    cv_im = cv.CreateImageHeader(pil_im.size, cv.IPL_DEPTH_8U, 1)
    cv.SetData(cv_im, pil_im.tostring(), pil_im.size[0]  )
    return cv_im

def cv2pil(cv_im):
    # Convert the cv image to a PIL image
    return Image.fromstring("L", cv.GetSize(cv_im), cv_im.tostring())

def imgCrop(image, cropBox, boxScale=1):
    # Crop a PIL image with the provided box [x(left), y(upper), w(width), h(height)]

    # Calculate scale factors
    xDelta=max(cropBox[2]*(boxScale-1),0)
    yDelta=max(cropBox[3]*(boxScale-1),0)

    # Convert cv box to PIL box [left, upper, right, lower]
    PIL_box=[cropBox[0]-xDelta, cropBox[1]-yDelta, cropBox[0]+cropBox[2]+xDelta, cropBox[1]+cropBox[3]+yDelta]

    return image.crop(PIL_box)

def faceCrop(imagePattern,boxScale=1):
    # Select one of the haarcascade files:
    #   haarcascade_frontalface_alt.xml  <-- Best one?
    #   haarcascade_frontalface_alt2.xml
    #   haarcascade_frontalface_alt_tree.xml
    #   haarcascade_frontalface_default.xml
    #   haarcascade_profileface.xml
    faceCascade = cv.Load('haarcascade_frontalface_alt.xml')

    imgList=glob.glob(imagePattern)
    if len(imgList)<=0:
        print 'No Images Found'
        return

    for img in imgList:
        pil_im=Image.open(img)
        cv_im=pil2cvGrey(pil_im)
        faces=DetectFace(cv_im,faceCascade)
        if faces:
            n=1
            for face in faces:
                croppedImage=imgCrop(pil_im, face[0],boxScale=boxScale)
                fname,ext=os.path.splitext(img)
                croppedImage.save(fname+'_crop'+str(n)+ext)
                n+=1
        else:
            print 'No faces found:', img

def test(imageFilePath):
    pil_im=Image.open(imageFilePath)
    cv_im=pil2cvGrey(pil_im)
    # Select one of the haarcascade files:
    #   haarcascade_frontalface_alt.xml  <-- Best one?
    #   haarcascade_frontalface_alt2.xml
    #   haarcascade_frontalface_alt_tree.xml
    #   haarcascade_frontalface_default.xml
    #   haarcascade_profileface.xml
    faceCascade = cv.Load('haarcascade_frontalface_alt.xml')
    face_im=DetectFace(cv_im,faceCascade, returnImage=True)
    img=cv2pil(face_im)
    img.show()
    img.save('test.png')


# Test the algorithm on an image
#test('testPics/faces.jpg')

# Crop all jpegs in a folder. Note: the code uses glob which follows unix Shell rules.
# Use the boxScale to scale the cropping area. 1=opencv box, 2=2x the width and height
faceCrop('testPics/*.jpg',boxScale=1)

Bei Verwendung des obigen Bildes werden mit diesem Code 52 der 59 Gesichter extrahiert, und es werden beschnittene Dateien wie: .__ erzeugt.enter image description hereenter image description hereenter image description hereenter image description hereenter image description hereenter image description hereenter image description hereenter image description here

83
Onlyjus

Eine weitere verfügbare Option ist dlib , die auf maschinellen Lernansätzen basiert. 

import dlib
import Image
from skimage import io
import matplotlib.pyplot as plt


def detect_faces(image):

    # Create a face detector
    face_detector = dlib.get_frontal_face_detector()

    # Run detector and get bounding boxes of the faces on image.
    detected_faces = face_detector(image, 1)
    face_frames = [(x.left(), x.top(),
                    x.right(), x.bottom()) for x in detected_faces]

    return face_frames

# Load image
img_path = 'test.jpg'
image = io.imread(img_path)

# Detect faces
detected_faces = detect_faces(image)

# Crop faces and plot
for n, face_rect in enumerate(detected_faces):
    face = Image.fromarray(image).crop(face_rect)
    plt.subplot(1, len(detected_faces), n+1)
    plt.axis('off')
    plt.imshow(face)

 enter image description here  enter image description here

11

facedetect

https://github.com/wavexx/facedetect ist ein Nice Python OpenCV CLI-Wrapper, und ich habe soeben hinzugefügt dieses Beispiel mit ImageMagick zu ihrem README hinzugefügt:

for file in path/to/pictures/*.jpg; do
  name=$(basename "$file")
  i=0
  facedetect "$file" | while read x y w h; do
    convert "$file" -crop ${w}x${h}+${x}+${y} "path/to/faces/${name%.*}_${i}.${name##*.}"
    i=$(($i+1))
  done
done

Getestet auf Ubuntu 16.04 mit (unbeschrifteten) Facebook-Profilbildern, siehe:

Das klingt wie eine bessere Frage für einen der eher auf (Computer-) Technologie ausgerichteten Austausch. 

Haben Sie sich das so etwas Jquery-Gesichtserkennungsskript angesehen? Ich weiß nicht, wie klug Sie sind, aber es ist eine Option, die unabhängig vom Betriebssystem ist.

Diese Lösung sieht auch vielversprechend aus, würde aber Windows erfordern. 

5
ckoerner

die obigen Codes funktionieren, aber dies ist eine kürzlich implementierte Implementierung von OpenCV Ich konnte das obige nicht ausführen und habe etwas gefunden, das funktioniert (von verschiedenen Orten aus). 

import cv2
import os

def facecrop(image):
    facedata = "haarcascade_frontalface_alt.xml"
    cascade = cv2.CascadeClassifier(facedata)

    img = cv2.imread(image)

    minisize = (img.shape[1],img.shape[0])
    miniframe = cv2.resize(img, minisize)

    faces = cascade.detectMultiScale(miniframe)

   for f in faces:
        x, y, w, h = [ v for v in f ]
        cv2.rectangle(img, (x,y), (x+w,y+h), (255,255,255))

        sub_face = img[y:y+h, x:x+w]
        fname, ext = os.path.splitext(image)
        cv2.imwrite(fname+"_cropped_"+ext, sub_face)



    return



facecrop("1.jpg")
4
Israel Abebe

Ich habe eine Anwendung "Gesichtserkennung mit eigenem Datensatz" mit dem Paket python= 'face_recognition' und 'opencv-python' .

Der Quellcode und die Installationsanleitung befinden sich im GitHub - Gesichtserkennung mit eigenem Datensatz

Oder führen Sie die Quelle -

import face_recognition
import cv2
import numpy as np

import os
'''
    Get current working director and create a Data directory to store the faces
'''
currentDirectory = os.getcwd()
dirName = os.path.join(currentDirectory, 'Data')
print(dirName)
if not os.path.exists(dirName):
    try:
        os.makedirs(dirName)
    except:
        raise OSError("Can't create destination directory (%s)!" % (dirName))
'''
    For the given path, get the List of all files in the directory tree 
'''
def getListOfFiles(dirName):
    # create a list of file and sub directories
    # names in the given directory
    listOfFile = os.listdir(dirName)
    allFiles = list()
    # Iterate over all the entries
    for entry in listOfFile:
        # Create full path
        fullPath = os.path.join(dirName, entry)
        # If entry is a directory then get the list of files in this directory
        if os.path.isdir(fullPath):
            allFiles = allFiles + getListOfFiles(fullPath)
        else:
            allFiles.append(fullPath)

    return allFiles

def knownFaceEncoding(listOfFiles):
    known_face_encodings=list()
    known_face_names=list()
    for file_name in listOfFiles:
        # print(file_name)
        if(file_name.lower().endswith(('.png', '.jpg', '.jpeg'))):
            known_image = face_recognition.load_image_file(file_name)
            # known_face_locations = face_recognition.face_locations(known_image)
            # known_face_encoding = face_recognition.face_encodings(known_image,known_face_locations)
            face_encods = face_recognition.face_encodings(known_image)
            if face_encods:
                known_face_encoding = face_encods[0]
                known_face_encodings.append(known_face_encoding)
                known_face_names.append(os.path.basename(file_name[0:-4]))
    return known_face_encodings, known_face_names


# Get the list of all files in directory tree at given path
listOfFiles = getListOfFiles(dirName)
known_face_encodings, known_face_names = knownFaceEncoding(listOfFiles)

video_capture = cv2.VideoCapture(0)
cv2.namedWindow("Video", flags= cv2.WINDOW_NORMAL)
# cv2.namedWindow("Video")

cv2.resizeWindow('Video', 1024,640)
cv2.moveWindow('Video', 20,20)


# Initialize some variables
face_locations = []
face_encodings = []
face_names = []
process_this_frame = True


while True:
    # Grab a single frame of video
    ret, frame = video_capture.read()
    # print(ret)
    # Resize frame of video to 1/4 size for faster face recognition processing
    small_frame = cv2.resize(frame, (0, 0), fx=0.25, fy=0.25)
    # Convert the image from BGR color (which OpenCV uses) to RGB color (which face_recognition uses)
    rgb_small_frame = small_frame[:, :, ::-1]


    k = cv2.waitKey(1)
    # Hit 'c' on capture the image!
    # Hit 'q' on the keyboard to quit!
    if k == ord('q'):
        break
    Elif k== ord('c'):
        face_loc = face_recognition.face_locations(rgb_small_frame)
        if face_loc:
            print("Enter Name -")
            name = input()
            img_name = "{}/{}.png".format(dirName,name)
            (top, right, bottom, left)= face_loc[0]
            top *= 4
            right *= 4
            bottom *= 4
            left *= 4
            cv2.imwrite(img_name, frame[top - 5 :bottom + 5,left -5 :right + 5])
            listOfFiles = getListOfFiles(dirName)
            known_face_encodings, known_face_names = knownFaceEncoding(listOfFiles)

    # Only process every other frame of video to save time
    if process_this_frame:
        # Find all the faces and face encodings in the current frame of video
        face_locations = face_recognition.face_locations(rgb_small_frame)
        face_encodings = face_recognition.face_encodings(rgb_small_frame, face_locations)
        # print(face_locations)

        face_names = []

        for face_encoding,face_location in Zip(face_encodings,face_locations):
            # See if the face is a match for the known face(s)
            matches = face_recognition.compare_faces(known_face_encodings, face_encoding, tolerance= 0.55)
            name = "Unknown"
            distance = 0

            # use the known face with the smallest distance to the new face
            face_distances = face_recognition.face_distance(known_face_encodings, face_encoding)
            #print(face_distances)
            if len(face_distances) > 0:
                best_match_index = np.argmin(face_distances)
                if matches[best_match_index]:
                    name = known_face_names[best_match_index]
                    # distance = face_distances[best_match_index]
            #print(face_distances[best_match_index])
            # string_value = '{} {:.3f}'.format(name, distance)
            face_names.append(name)


    process_this_frame = not process_this_frame


    # Display the results
    for (top, right, bottom, left), name in Zip(face_locations, face_names):
        # Scale back up face locations since the frame we detected in was scaled to 1/4 size
        top *= 4
        right *= 4
        bottom *= 4
        left *= 4

        # Draw a box around the face
        cv2.rectangle(frame, (left, top), (right, bottom), (0, 0, 255), 2)

        # Draw a label with a name below the face
        cv2.rectangle(frame, (left, bottom + 46), (right, bottom+11), (0, 0, 155), cv2.FILLED)
        font = cv2.FONT_HERSHEY_DUPLEX
        cv2.putText(frame, name, (left + 6, bottom +40), font, 1.0, (255, 255, 255), 1)

    # Display the resulting image
    cv2.imshow('Video', frame)

# Release handle to the webcam
video_capture.release()
cv2.destroyAllWindows()

Es wird ein "Daten" -Verzeichnis am aktuellen Speicherort erstellt, auch wenn dieses Verzeichnis nicht vorhanden ist.

Wenn ein Gesicht mit einem Rechteck markiert ist, drücken Sie 'c' , um das Bild aufzunehmen. In der Eingabeaufforderung werden Sie nach dem Namen des Gesichts gefragt . Geben Sie den Namen des Bildes ein und geben Sie ein. Sie finden dieses Bild im Verzeichnis 'Data' .

2
Anupam Bera

Autocrop hat für mich ziemlich gut geklappt . Es ist so einfach wie autocrop -i pics -o crop -w 400 -H 400. Sie können die Verwendung in ihrer Readme-Datei erhalten.

usage: [-h] [-o OUTPUT] [-i INPUT] [-w WIDTH] [-H HEIGHT] [-v]

Automatically crops faces from batches of pictures

optional arguments:
  -h, --help            Show this help message and exit
  -o, --output, -p, --path
            Folder where cropped images will be placed.
            Default: current working directory
  -i, --input
            Folder where images to crop are located.
            Default: current working directory
  -w, --width
            Width of cropped files in px. Default=500
  -H, --height
            Height of cropped files in px. Default=500
  -v, --version         Show program's version number and exit
1
Abhishek Singh

Ich habe diesen Shell-Befehl verwendet:

for f in *.jpg;do PYTHONPATH=/usr/local/lib/python2.7/site-packages python -c 'import cv2;import sys;rects=cv2.CascadeClassifier("/usr/local/opt/opencv/share/OpenCV/haarcascades/haarcascade_frontalface_default.xml").detectMultiScale(cv2.cvtColor(cv2.imread(sys.argv[1]),cv2.COLOR_BGR2GRAY),1.3,5);print("\n".join([" ".join([str(item) for item in row])for row in rects]))' $f|while read x y w h;do convert $f -gravity NorthWest -crop ${w}x$h+$x+$y ${f%jpg}-$x-$y.png;done;done

Sie können opencv und imagemagick unter OS X mit brew install opencv imagemagick Installieren.

1
Lri

Ich denke, die beste Option ist Google Vision API ..__, aktualisiert, verwendet maschinelles Lernen und verbessert sich mit der Zeit.

In der Dokumentation finden Sie Beispiele: https://cloud.google.com/vision/docs/other-features

0
Hernán Acosta

Hinzufügen zu @Israel Abebe Version. Wenn Sie vor der Bilderweiterung einen Zähler hinzufügen, zeigt der Algorithmus alle erkannten Gesichter an. Den Code anbringen, genau wie bei Israel Abebe. Fügen Sie einfach einen Zähler hinzu und akzeptieren Sie die Kaskadendatei als Argument. Der Algorithmus funktioniert wunderbar! Danke @Israel Abebe für das!

import cv2
import os
import sys

def facecrop(image):
facedata = sys.argv[1]
cascade = cv2.CascadeClassifier(facedata)

img = cv2.imread(image)

minisize = (img.shape[1],img.shape[0])
miniframe = cv2.resize(img, minisize)

faces = cascade.detectMultiScale(miniframe)
counter = 0
for f in faces:
    x, y, w, h = [ v for v in f ]
    cv2.rectangle(img, (x,y), (x+w,y+h), (255,255,255))

    sub_face = img[y:y+h, x:x+w]
    fname, ext = os.path.splitext(image)
    cv2.imwrite(fname+"_cropped_"+str(counter)+ext, sub_face)
    counter += 1
return

facecrop("Face_detect_1.jpg")

PS: Als Antwort hinzufügen. Konnte aufgrund eines Punktproblems keinen Kommentar hinzufügen.

0
Mrunal

Gesicht erkennen und dann zuschneiden und das zugeschnittene Bild in einem Ordner speichern.

import numpy as np
import cv2 as cv
face_cascade = cv.CascadeClassifier('./haarcascade_frontalface_default.xml')
#eye_cascade = cv.CascadeClassifier('haarcascade_eye.xml')
img = cv.imread('./face/nancy-Copy1.jpg')
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray, 1.3, 5)
for (x,y,w,h) in faces:
    cv.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
    roi_gray = gray[y:y+h, x:x+w]
    roi_color = img[y:y+h, x:x+w]
    #eyes = eye_cascade.detectMultiScale(roi_gray)
    #for (ex,ey,ew,eh) in eyes:
     #   cv.rectangle(roi_color,(ex,ey),(ex+ew,ey+eh),(0,255,0),2)
    sub_face = img[y:y+h, x:x+w]
    face_file_name = "face/" + str(y) + ".jpg"
    plt.imsave(face_file_name, sub_face)
plt.imshow(sub_face)

0
ashish bansal