1

I have a program that is using OpenCV to identify faces and profiles. The default Haar cascade is set for frontal or right profile identifier. To find a left profile, I simply flip the image and it runs the right profile search on that flipped image. It can then easily identify where the profile is in the flipped image.

My issue is that when it tries to draw a box around the face, it is on the opposite side of the image due to the flip.

So the fix I need to do is make the coordinates for the face which are currently a Numpy array of "x,y,w,h = face", flip the array to the opposite side of the screen. Height and width are tracked as 0 to 320 and 0 to 240, the webcam capture size.

I think I need to convert my 320X240 numpy array into a plot, flip the plot for the left side profile coordinates, and that should have the rectangle drawing over the face again.

Does anyone have suggestions on how to manage this?

Code as follows:

from multiprocessing import Process, Queue
import imutils
from imutils.video import WebcamVideoStream
from imutils.video import FPS
import time
import cv2
import numpy as np
import random

#Video Prep
camWandH = np.array([320, 240]) #set camera frame height and width here
camCenter = [(camWandH[0]/2),(camWandH[1]/2)] #Ordered as Pan and Tilt
print("Center of screen is " + str(camCenter[0]) + ", " + str(camCenter[1]))
frontalface = cv2.CascadeClassifier("haarcascade_frontalface_default.xml")
profileface = cv2.CascadeClassifier("haarcascade_profileface.xml")
cv2.namedWindow('CreepyEye', cv2.WINDOW_NORMAL)
vs = WebcamVideoStream(src=0).start() #If src is changed to a URL it will use that as the camera

while True:
    # Capture frame-by-frame
    frame = vs.read()
    # Our operations on the frame come here
    frame = imutils.resize(frame, width=camWandH[0])
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    cv2.flip(gray,1,gray)   #   flip the image
    face = np.array([0,0,0,0])  # This will hold the array that OpenCV returns when it finds a face: (makes a rectangle)
    Cface = np.array([0,0])     # Center of the face: a point calculated from the above variable
    lastface = 0        # 1 = frontal, 2 = right profile, 3 = left profile

    faceFound = False   # This variable is set to true if, on THIS loop a face has already been found
    cv2.imshow('CreepyEye',gray)
    #Find Faces
    if not faceFound:
        if lastface == 0 or lastface == 1:
            fface = frontalface.detectMultiScale(gray, 1.3, 4, 0, (80,80))      
            if fface != ():         
                lastface = 1        
                for f in fface:     # f in fface is an array with a rectangle representing a face
                    faceFound = True
                    face = f

    if not faceFound:               # if we didnt find a face yet...
        if lastface == 0 or lastface == 2:
            pfacer = profileface.detectMultiScale(gray, 1.3, 4,0,(80,80))
            if pfacer != ():        # if we found a profile face...
                lastface = 2
                print("pfacer is " + str(pfacer))
                for f in pfacer:
                    faceFound = True
                    face = f

    if not faceFound:               # a final attempt
        if lastface == 0 or lastface == 3:  # flipped profile face search because the Profile is only tuned for right profiles
            grayRev = cv2.flip(gray,1)
            pfacel = profileface.detectMultiScale(grayRev, 1.3, 4,0,(80,80))
            if pfacel != ():
                lastface = 3
                print("pfacel is " + str(pfacel))
                for f in pfacel:
                    faceFound = True
                    face = f

    if not faceFound:       # if no face was found...-
        lastface = 0        # the next loop needs to know
        face = np.array([0,0,0,0])  # so that it doesn't think the face is still where it was last loop

    if faceFound == True:
        x,y,w,h = face
        Cface = [(face[2]/2+face[0]),(face[3]/2+face[1])]   # we are given an x,y corner point and a width and height, we need the center
        centerPan = "middle "   
        centerTilt = ""
        print("Center of face is " + str(Cface[0]) + ", " + str(Cface[1]))
        if lastface == 1:
            #Draw a rectangle around every found face
            cv2.rectangle(gray,(x,y),(x+w,y+h),(255,255,255),1)
            cv2.putText(gray, "Frontal Face Detected", (x,y-10), cv2.FONT_HERSHEY_SIMPLEX, .5, (255,255,255), 1, cv2.LINE_AA)
            cv2.circle(gray, (int(Cface[0]), int(Cface[1])), 1, 255, 2)
            cv2.putText(gray, "Center", (int(Cface[0]), int(Cface[1])), cv2.FONT_HERSHEY_SIMPLEX, .3, (255,255,255), 1, cv2.LINE_AA)
        elif lastface == 2:
            #Draw a rectangle around every found face
            cv2.rectangle(gray,(x,y),(x+w,y+h),(255,255,255),1)
            cv2.putText(gray, "Right Profile Detected", (x,y-10), cv2.FONT_HERSHEY_SIMPLEX, .5, (255,255,255), 1, cv2.LINE_AA)
            cv2.circle(gray, (int(Cface[0]), int(Cface[1])), 1, 255, 2)
            cv2.putText(gray, "Center", (int(Cface[0]), int(Cface[1])), cv2.FONT_HERSHEY_SIMPLEX, .3, (255,255,255), 1, cv2.LINE_AA)
        elif lastface == 3:
            #Draw a rectangle around every found face
            cv2.rectangle(grayRev,(x,y),(x+w,y+h),(255,255,255),1)
            cv2.putText(grayRev, "Left Profile Detected", (x,y-10), cv2.FONT_HERSHEY_SIMPLEX, .5, (255,255,255), 1, cv2.LINE_AA)
            cv2.circle(grayRev, (int(Cface[0]), int(Cface[1])), 1, 255, 2)
            cv2.putText(grayRev, "Center", (int(Cface[0]), int(Cface[1])), cv2.FONT_HERSHEY_SIMPLEX, .3, (255,255,255), 1, cv2.LINE_AA)
            gray = cv2.flip(grayRev,1)

        #print("Face position is " + str((face)))
        #Draws dot in center of camera display
        cv2.circle(gray, (int(camCenter[0]), int(camCenter[1])), 1, 255, 2)
        cv2.putText(gray, "Center of Camera", (int(camCenter[0]), int(camCenter[1])),cv2.FONT_HERSHEY_SIMPLEX, .3, (255,255,255), 1, cv2.LINE_AA)

        # Display the resulting frame
        #cv2.putText(gray, "Face is " + centerTilt + centerPan + " of camera center", (10,220), cv2.FONT_HERSHEY_SIMPLEX, .5, (255,255,255), 1, cv2.LINE_AA)
        cv2.imshow('CreepyEye',gray)
        cv2.waitKey(33) #Displays image for length of a single frame in 30 FPS
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break

    if not faceFound:       # if no face was found...-
        print("Entering search mode")
        cv2.putText(gray, "Searching Mode Active", (10,220), cv2.FONT_HERSHEY_SIMPLEX, .5, (255,255,255), 1, cv2.LINE_AA)
        cv2.imshow('CreepyEye',gray)
        cv2.waitKey(33) #Displays image for length of a single frame in 30 FPS
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break

# When everything done, release the capture
#vs.release()
cv2.destroyAllWindows()

closed as off-topic by Steve Robillard, techraf, joan, Darth Vader Dec 11 '17 at 7:40

This question appears to be off-topic. The users who voted to close gave this specific reason:

  • "This question does not appear to be specific to the Raspberry Pi within the scope defined in the help center." – Steve Robillard, techraf, joan, Darth Vader
If this question can be reworded to fit the rules in the help center, please edit the question.

  • Why don't you just change the x value in your result to (320-x)? Am I misunderstanding something? – Mark Smith Dec 10 '17 at 22:59
  • 1
    The Pi is not relevant to your problem. For code related problems please use StackOverflow. – Darth Vader Dec 11 '17 at 7:43

Browse other questions tagged or ask your own question.