face recognition does not detect any with OpenCV - python

I am beginner at using OpenCv2, I am trying to detect faces with the following function:
def faceDetection(test_img):
gray_img=cv2.cvtColor(test_img,cv2.COLOR_BGR2GRAY)#convert color image to grayscale
face_haar_cascade=cv2.CascadeClassifier(cv2.data.haarcascades +'haarcascade_frontalface_default.xml')#Load haar classifier
faces=face_haar_cascade.detectMultiScale(gray_img,scaleFactor=1.32,minNeighbors=5)#detectMultiScale returns rectangles
return faces,gray_img
However, sometimes the faces are detected for some of the photos and the others not. For example it's dected the face in this photo:
However, it didn't detect the face in this photo
I do not know what went wrong in the second picture, as I believe it's with good quality and the face is shown almost similar to the first photo. Any idea?

My reference is here.
Here is the code and output:
import cv2
import sys
def detectFaceOpenCVHaar(faceCascade, frame, inHeight=300, inWidth=0):
frameOpenCVHaar = frame.copy()
frameHeight = frameOpenCVHaar.shape[0]
frameWidth = frameOpenCVHaar.shape[1]
if not inWidth:
inWidth = int((frameWidth / frameHeight) * inHeight)
scaleHeight = frameHeight / inHeight
scaleWidth = frameWidth / inWidth
frameOpenCVHaarSmall = cv2.resize(frameOpenCVHaar, (inWidth, inHeight))
frameGray = cv2.cvtColor(frameOpenCVHaarSmall, cv2.COLOR_BGR2GRAY)
faces = faceCascade.detectMultiScale(frameGray)
bboxes = []
for (x, y, w, h) in faces:
x1 = x
y1 = y
x2 = x + w
y2 = y + h
cvRect = [int(x1 * scaleWidth), int(y1 * scaleHeight),
int(x2 * scaleWidth), int(y2 * scaleHeight)]
bboxes.append(cvRect)
cv2.rectangle(frameOpenCVHaar, (cvRect[0], cvRect[1]), (cvRect[2], cvRect[3]), (0, 255, 0),
int(round(frameHeight / 150)), 4)
return frameOpenCVHaar, bboxes
if __name__ == "__main__" :
faceCascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
frame = cv2.imread("/ur/image/directory/to/face.jpg")
outOpencvHaar, bboxes = detectFaceOpenCVHaar(faceCascade, frame)
cv2.imshow("Face Detection Comparison", outOpencvHaar)
key = cv2.waitKey(0)
cv2.destroyAllWindows()
Output

Related

How do i make detection only on spesific area

I'm working on a project trying to do object detection and text detection using both yolo and easyocr. Since I'm a beginner and really new to computer vision, I would be glad if someone can help me.
Here's the code:
import cv2
import numpy as np
import easyocr
# Load Yolo
net = cv2.dnn.readNet('yolov4-tiny-custom_3000.weights', 'yolov4-tiny-custom.cfg')
classes = []
with open("obj.names", "r") as f:
classes = [line.strip() for line in f.readlines()]
layer_names = net.getLayerNames()
output_layers = [layer_names[i - 1] for i in net.getUnconnectedOutLayers()]
colors = np.random.uniform(0, 255, size=(len(classes), 3))
cap = cv2.VideoCapture('car1.mp4')
# Declare Ocr
cascade_src = 'haarcascade_russian_plate_number.xml'
cascade = cv2.CascadeClassifier(cascade_src)
reader = easyocr.Reader(['en'], gpu = False)
# Declare Ocr
while True:
_, frame = cap.read()
height, width, channels = frame.shape
#frame = cv2.resize(frame, (800, 600))
# Yolo Detection
# Detecting objects
blob = cv2.dnn.blobFromImage(frame, 0.00392, (416, 416), (0, 0, 0), True, crop=False)
net.setInput(blob)
outs = net.forward(output_layers)
# Showing informations on the screen
class_ids = []
confidences = []
boxes = []
for out in outs:
for detection in out:
scores = detection[5:]
class_id = np.argmax(scores)
confidence = scores[class_id]
if confidence > 0.5:
# Object detected
center_x = int(detection[0] * width)
center_y = int(detection[1] * height)
w = int(detection[2] * width)
h = int(detection[3] * height)
# Rectangle coordinates
x = int(center_x - w / 2)
y = int(center_y - h / 2)
boxes.append([x, y, w, h])
confidences.append(float(confidence))
class_ids.append(class_id)
indexes = cv2.dnn.NMSBoxes(boxes, confidences, 0.5, 0.4)
for i in range(len(boxes)):
if i in indexes:
x, y, w, h = boxes[i]
label = str(classes[class_ids[i]])
color = colors[class_ids[i]]
cv2.rectangle(frame, (x, y), (x + w, y + h), color, 2)
cv2.putText(frame, label, (x, y + 30), cv2.FONT_HERSHEY_PLAIN, 3, color, 3)
print("Jenis Mobil: " +label)
# Text Reader Using Ocr
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
plate = cascade.detectMultiScale(gray, 1.1, 5)
for x,y,w,h in plate:
wT,hT,cT = frame.shape
a,b = (int(0.02*wT),int(0.02*hT))
plate2 = frame[y+a:y+h-a,x+b:x+w-b,:]
cv2.rectangle(frame,(x,y),(x+w,y+h),(60,60,255),2)
cv2.rectangle(frame,(x-1,y-40),(x+w+1,y),(60,60,255),-1)
result = reader.readtext(plate2)
for detek in result:
top_left = (int(detek[0][0][0]), int(detek[0][0][1]))
bottom_right = (int(detek[0][2][0]), int(detek[0][2][1]))
text = detek[1]
cv2.putText(frame,text,(x,y-10),cv2.FONT_HERSHEY_SIMPLEX,0.9,(255,255,255),2)
print("Nomor Kendaran: " + text)
# Text Reader Using Ocr
cv2.imshow("Detection", frame)
key = cv2.waitKey(1)
if key == 27:
break
cap.release()
cv2.destroyAllWindows()
I am trying to use ROI to detect the object but I am not able to do it.
Any advice please?
Crop the image before it is fed to the model
while True:
_, frame = cap.read()
im_crop = im[y1:y2, x1:x2] # set x1,x2,y1,y2 based on your ROI
blob = cv2.dnn.blobFromImage(frame, 0.00392, (416, 416), (0, 0, 0), True, crop=False)
this will speed up the inference time as well as there is less data to process by the model

LBPHFaceRecognizer predict function always return 1

I am developing a facial recognition system and for that I have selected LBPH algorithm for doing the task. I have collected the sample images of user and trained it. The problem is while recognizing the face, the predict() of LBPHRecognizer always return same value for label but different value for confidence. Even if the face is unknown it returns 1.
Technologies I have been using : Python 3.7.4, OpenCV 4.1.2
Code to collect sample image
import cv2
import numpy as np
import os
import requests
import time
from PIL import Image
class CollectFaceWebCam():
def __init__(self, sid):
self.studentId = sid
#capture webcam
self.LiveWebCamera = cv2.VideoCapture(0)
#pre-trained dataset (haar-cascade classifier)
self.faceDataSet = cv2.CascadeClassifier('resources/haarcascade_frontalface_default.xml')
#sample image capture counter
self.imgCounter = 0
self.directoryName = 'sampleImgFolder'
#check path
if not os.path.exists(self.directoryName):
os.makedirs(self.directoryName)
if not os.path.exists(self.directoryName + '/' + self.studentId):
os.makedirs(self.directoryName + '/' + self.studentId)
def gen(self):
while True:
condition, frame = self.LiveWebCamera.read() #capture frame
img = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)#conversion to gray scale
#face detection
faces = self.faceDataSet.detectMultiScale( # Detect face sizes
img,
scaleFactor=1.3,
minNeighbors=5,
minSize=(100, 100),
flags=cv2.CASCADE_SCALE_IMAGE
)
for (x, y, w, h) in faces:
end_crd_x = x + w # face start coordinates
end_crd_y = y + h #face end coordinate
#draw rectangle
##parms image, start plot, end plot, thickness, color
cv2.rectangle(frame, (x, y), (end_crd_x, end_crd_y), (0, 255, 33), 1)
#accepts multiple face
if len(faces) >= 0:
#face must be single in frame
if len(faces) == 1:
detectedImg = img[y:y + h, x:x + w]
#checking blurness of image
blurValue = cv2.Laplacian(detectedImg, cv2.CV_64F).var()
#ignoring the blury images
if not blurValue <= 60:
newImg = img[y:y + h, x:x + w] #new img
#saving the detected faces
filename = '{}\{}\{}\{}_{}'.format(os.getcwd(), self.directoryName, self.studentId, self.studentId, self.imgCounter) + '.jpg'
cv2.imwrite(filename, newImg)
self.imgCounter += 1
else:
cv2.putText(frame,"Multiple Face not allowed", (50,150), cv2.FONT_HERSHEY_SIMPLEX, 1, (237, 20, 5), thickness=2)
cv2.putText(frame,"Collecting Sample", (50,100), cv2.FONT_HERSHEY_SIMPLEX, 1, (250, 250, 250), thickness=3)
cv2.putText(frame,"Image Count " + str(self.imgCounter), (50,200), cv2.FONT_HERSHEY_SIMPLEX, 2, (237, 20, 5), thickness=2)
cv2.imshow('Collecting Sample', frame) # display frames
k = cv2.waitKey(100) & 0xff # capture when user press 'esc'
if k == 27:
break
elif self.imgCounter == 110:
break
self.LiveWebCamera.release() #stop video capture
cv2.destroyAllWindows() #close all windows
class CleanSampleImages():
def __init__(self):
self.faceDataset = cv2.CascadeClassifier('resources/haarcascade_frontalface_default.xml')
self.eyeDataset = cv2.CascadeClassifier('resources/haarcascade_eye.xml')
self.targetFolder = 'sampleImgFolder'
def checkFace(self):
os.chdir(self.targetFolder)
for directory in os.listdir():
os.chdir(directory)
for files in os.listdir():
imagePath = '{}/{}'.format(os.getcwd(), files)
imagePil = Image.open(imagePath).convert('L')
imageNumpy = np.array(imagePil) #conversion of normal image to numpy array
#detect face
faces = self.faceDataset.detectMultiScale(imageNumpy)
#deleting image file if face is not found
if not len(faces) == 1:
os.remove(files)
break
for (x, y, w, h) in faces:
#detect eye from selected
eyes = self.eyeDataset.detectMultiScale(imageNumpy)
if not len(eyes) > 0 and len(eyes) <=2:
#deleting image file if eye count of image is less than 0 or more than 2
os.remove(files)
os.chdir('../')
os.chdir('../')
#id must be in X-X-ID eg. a-b-342
t = CollectFaceWebCam('sa-t-1')
t.gen()
clean = CleanSampleImages
c.checkFace()
Above code consist of two class CollectFaceWebCam and CleanSampleImages. CollectFaceWebCam works for collecting the sample images. and CleanSampleImages works for cleaning the collected data. if the image does not consist of face the file is deleted.
Code to Train images
import os
import cv2
import numpy as np
from PIL import Image
class Trainer():
def __init__(self):
self.recognizer = cv2.face.LBPHFaceRecognizer_create()
self.targetImagesDirectory="sampleImgFolder"
self.dataset = cv2.CascadeClassifier('resources/haarcascade_frontalface_default.xml')
def getImgwithId(self):
sampleImage, sampleImageId = [], []
filename = '{}\\{}'.format(os.getcwd(), self.targetImagesDirectory)
if os.path.exists(filename):
os.chdir(filename)
print('current path is ' + os.getcwd())
for f in os.listdir():
imgPath = os.path.join(filename, f)
os.chdir(imgPath)
for file in os.listdir():
#reteving id from filename (filename format : ta-s-ID_Filename.jpg)
id = file.split('_')
id = id[0].split('-')
id = id[2]
imageFilePath = imgPath + '\\' + file
imagePil = Image.open(imageFilePath).convert('L')
#conversion to numpy array
imageNp = np.array(imagePil, 'uint8')
faces = self.dataset.detectMultiScale(imageNp)
for (x, y, w, h) in faces:
sampleImage.append(imageNp)
sampleImageId.append(id)
os.chdir('../')
os.chdir('../')
return sampleImage, np.array(sampleImageId, dtype = int)
def train(self, data, label):
try:
self.recognizer.train(data, label)
self.msg = 'Training Successful'
print('writting')
self.recognizer.write('date.yml')
print('writing finished')
except:
self.msg = 'Core: Training Error'
print('except')
tr = Trainer()
sampleFaces, sampleFaceId = (tr.getImgwithId())
tr.train(sampleFaces, sampleFaceId)
Code to recognize face
import os
import cv2
import numpy as np
from PIL import Image
class Recognizer():
def __init__(self):
self.recognizer = cv2.face.LBPHFaceRecognizer_create()
self.recognizer.read('date.yml')
self.targetImagesDirectory="sampleImgFolder"
self.dataset = cv2.CascadeClassifier('resources/haarcascade_frontalface_default.xml')
self.captureVideo = cv2.VideoCapture(0)
self.font = cv2.FONT_HERSHEY_SIMPLEX = 2 # Font
self.predictedUser = []
def gen(self):
while True:
condition, frame = self.captureVideo.read() #capture frame
img = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)#conversion to gray scale
#face detection
faces = self.dataset.detectMultiScale( # Detect face sizes
img,
scaleFactor=1.3,
minNeighbors=5,
minSize=(100, 100),
flags=cv2.CASCADE_SCALE_IMAGE
)
for (x, y, w, h) in faces:
end_crd_x = x + w # face start coordinates
end_crd_y = y + h #face end coordinate
#draw rectangle
##parms image, start plot, end plot, thickness, color
cv2.rectangle(frame, (x, y), (end_crd_x, end_crd_y), (0, 255, 33), 1)
predictUser, confidence = self.recognizer.predict(img[y:y+h,x:x+w])
self.predictedUser.append(predictUser)
cv2.imshow('test', frame)
k = cv2.waitKey(100) & 0xff # capture when user press 'esc'
if k == 27:
break
self.captureVideo.release()
cv2.destroyAllWindows()
r = Recognizer()
r.gen()
print(r.predictedUser)
"predictUser, confidence = self.recognizer.predict(img[y:y+h,x:x+w])" line of code in Recognizer class always return same value for label. The output of code to recognize face is attached below:
I would love to know why and where the problem is, as My skills and research could not lead me to identification of problem.
It might because of the data-collection process. I see you using a cascade classifier multiple times, you could limit it. While checking for a face on webcam, you could use classifiers at the time and store only the extracted/cropped faces. Also during prediction, use confidence as a threshold to limit the false prediction.

How can I capture detected image of object Yolov3 and display in flask

I am working on Real Time Object Detection using YOLOv3 with OpenCV and Python. It's works well. Currently I try to capture detected image of object and display in flask. Do someone know how to implement this features? Hope someone can helps. I got the tutorial based on this link https://medium.com/analytics-vidhya/real-time-object-detection-using-yolov3-with-opencv-and-python-64c985e14786
import cv2
import numpy as np
import os
import time
import detect as dt
from PIL import Image
labelsPath = os.path.sep.join(["yolo-coco", "coco.names"])
weightsPath = os.path.sep.join(["yolo-coco", "yolov3.weights"])
configPath = os.path.sep.join(["yolo-coco", "yolov3.cfg"])
labelsPath = os.path.sep.join(["yolo-coco", "coco.names"])
LABELS = open(labelsPath).read().strip().split("\n")
net = cv2.dnn.readNet(configPath, weightsPath)
layer_names = net.getLayerNames()
outputlayers = [layer_names[i[0] - 1] for i in net.getUnconnectedOutLayers()]
colors= np.random.uniform(0,255,size=(len(LABELS),3))
#loading image
cap0=cv2.VideoCapture(0) #0 for 1st webcam
cap1=cv2.VideoCapture(1)
font = cv2.FONT_HERSHEY_PLAIN
starting_time= time.time()
frame_id = 0
count = 0
use_cuda = 1
# configPath.cuda()
while True:
ret0,frame0= cap0.read() #
ret1,frame1= cap1.read() #
image = cv2.cvtColor(frame0, cv2.COLOR_BGR2RGB)
im_pil = Image.fromarray(image)
im_pil = im_pil.resize((200, 200))
boxes = dt.do_detect(image, im_pil, 0.5, 0.4, use_cuda)
if (ret0):
frame_id+=1
#print(frame_id)
height,width,channels = frame0.shape
#print (frame.shape)
#detecting objects
blob = cv2.dnn.blobFromImage(frame0,0.00392,(320,320),(0,0,0),True,crop=False) #reduce 416 to 320
net.setInput(blob)
outs = net.forward(outputlayers)
#print(outs)
print(outs[1])
#Showing info on screen/ get confidence score of algorithm in detecting an object in blob
class_ids=[]
confidences=[]
boxes=[]
for out in outs:
#print(out)
for detection in out:
scores = detection[5:]
class_id = np.argmax(scores)
confidence = scores[class_id]
print(confidence)
if confidence > 0.3:
#onject detected
center_x= int(detection[0]*width)
center_y= int(detection[1]*height)
w = int(detection[2]*width)
h = int(detection[3]*height)
#cv2.circle(img,(center_x,center_y),10,(0,255,0),2)
#rectangle co-ordinaters
x=int(center_x - w/2)
y=int(center_y - h/2)
#cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2)
boxes.append([x,y,w,h]) #put all rectangle areas
confidences.append(float(confidence)) #how confidence was that object detected and show that percentage
class_ids.append(class_id) #name of the object tha was detected
indexes = cv2.dnn.NMSBoxes(boxes,confidences,0.4,0.6)
result = open('C:/Users/HP/Miniconda3/envs/count_vechicle/coding/images/frame%04d.txt'%(count), 'w')
for i in range(len(boxes)):
result.write(boxes[i])
count = count + 1
success, image = vidcap.read()
result.close()
if i in indexes:
x,y,w,h = boxes[i]
label = str(LABELS[class_ids[i]])
confidence= confidences[i]
color = colors[class_ids[i]]
cv2.rectangle(frame0,(x,y),(x+w,y+h),color,2)
cv2.putText(frame0,label+" "+str(round(confidence,2)),(x,y+30),font,1,(255,255,255),2)
elapsed_time = time.time() - starting_time
fps=frame_id/elapsed_time
cv2.putText(frame0,"FPS:"+str(round(fps,2)),(10,50),font,2,(0,0,0),1)
cv2.imshow("Image0",frame0)
key = cv2.waitKey(1) #wait 1ms the loop will start again and we will process the next frame
if (ret1):
cv2.imshow("Image1",frame1)
key = cv2.waitKey(1) #wait 1ms the loop will start again and we will process the next frame
if key == 27: #esc key stops the process
break;
cap0.release()
cap1.release()
cv2.destroyAllWindows()
Using the bounding box coordinates of the detected object, you can crop a new image out of it and then save it to display.
Try this:
# extract the bounding box coordinates
(x, y) = (boxes[i][0], boxes[i][1])
(w, h) = (boxes[i][2], boxes[i][3])
crop_img = frame[y:y + h, x:x + w] #frame of video you are looping through
cv2.imwrite(<filename>, crop_img)
Update: according to your code :
if i in indexes:
x,y,w,h = boxes[i]
crop_img = frame0[y:y + h, x:x + w]
cv2.imwrite(<filename>, crop_img)
Using the box coordinates you can crop that part
Hope it helps.

How i can use this OpenCV code for face detection using python2.7

I founded this code on the web, I'd like to use it for detect my face.
#!/usr/bin/python
#----------------------------------------------------------------------------
# Face Detection Test (OpenCV)
#
# thanks to:
# http://japskua.wordpress.com/2010/08/04/detecting-eyes-with-python-opencv
#----------------------------------------------------------------------------
import cv
import time
import Image
def DetectFace(image, faceCascade):
min_size = (20,20)
image_scale = 2
haar_scale = 1.1
min_neighbors = 3
haar_flags = 0
# Allocate the temporary images
grayscale = cv.CreateImage((image.width, image.height), 8, 1)
smallImage = cv.CreateImage(
(
cv.Round(image.width / image_scale),
cv.Round(image.height / image_scale)
), 8 ,1)
# Convert color input image to grayscale
cv.CvtColor(image, grayscale, cv.CV_BGR2GRAY)
# Scale input image for faster processing
cv.Resize(grayscale, 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
#----------
# M A I N
#----------
capture = cv.CaptureFromCAM(0)
#capture = cv.CaptureFromFile("test.avi")
faceCascade = cv.Load("haarcascades/haarcascade_frontalface_default.xml")
#faceCascade = cv.Load("haarcascades/haarcascade_frontalface_alt2.xml")
#faceCascade = cv.Load("haarcascades/haarcascade_frontalface_alt.xml")
#faceCascade = cv.Load("haarcascades/haarcascade_frontalface_alt_tree.xml")
while (cv.WaitKey(15)==-1):
img = cv.QueryFrame(capture)
image = DetectFace(img, faceCascade)
cv.ShowImage("face detection test", image)
cv.ReleaseCapture(capture)
I'd like to use it for my test, but when I try to execute it I recive this error:
root#aetas:~/Scrivania# python riconoscimentofacciale.py
Traceback (most recent call last):
File "riconoscimentofacciale.py", line 63, in <module>
faceCascade = cv.Load("haarcascades/haarcascade_frontalface_default.xml")
TypeError: OpenCV returned NULL
Someone have the solution?
The question below is resolved. The solution is to create one folder that contain script and the folder haarcascades(with XML file).
Thanks to DineMartine and Dominique

Python/OpenCV capture image from webcam not working

My original python script was created to work on images already saved. I am now wanting it to capture the image and crop it. I have a working webcam section and a working crop section but I am not able to combine them and make them it. I have included the combined code. Currently it will still crop a saved image and the GUI for the webcam does display for a second but does not display any content (gray screen). Can anyone help me?
import cv
import cv2
import numpy
import Image
import glob
import os
# Static
faceCascade = cv.Load('haarcascade_frontalface_alt.xml')
padding = -1
inputimg = raw_input('Please enter the entire path to the image folder:')
outputimg = raw_input('Please enter the entire path to the output folder:')
if not os.path.exists(outputimg):
os.makedirs(outputimg)
while (padding < 0):
padding = int(raw_input('Enter crop padding:'))
capture = cv2.VideoCapture(0)
cv2.namedWindow("Face Crop")
if capture.isOpened():
frame = capture.read()
def DetectFace(image, faceCascade, returnImage=False):
#variables
min_size = (50,50)
haar_scale = 1.1
min_neighbors = 3
haar_flags = 0
DOWNSCALE = 4
# 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)
# Start video frame
minisize = (frame.shape[1]/DOWNSCALE,frame.shape[0]/DOWNSCALE)
miniframe = cv2.resize(frame, minisize)
faceCam = classifier.detectMultiScale(miniframe)
for f in faceCam:
x, y, w, h = [ v*DOWNSCALE for v in f ]
cv2.rectangle(frame, (x,y), (x+w,y+h), (0,0,255))
cv2.putText(frame, "Press ESC to close.", (5, 25),
cv2.FONT_HERSHEY_SIMPLEX, 1.0, (255,255,255))
cv2.imshow("preview", frame)
# get next frame
frame = capture.read()
raw_input('Pause for testing')
key = cv2.waitKey(20)
if key in [27, ord('Q'), ord('q')]: # exit on ESC
break
if returnImage:
return image
else:
return faces
def pil2cvGrey(pil_im):
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 imgCrop(image, cropBox, boxScale=1):
# Crop a PIL image with the provided box [x(left), y(upper), w(width), h(height)]
# Calculate scale factors
xPadding=max(cropBox[2]*(boxScale-1),int(padding))
yPadding=max(cropBox[3]*(boxScale-1),int(padding))
# Convert cv box to PIL box [left, upper, right, lower]
PIL_box=[cropBox[0]-xPadding, cropBox[1]-yPadding, cropBox[0]+cropBox[2]+xPadding, cropBox[1]+cropBox[3]+yPadding]
return image.crop(PIL_box)
def Crop(imagePattern,boxScale=1):
imgList=glob.glob(imagePattern)
if len(imgList)<=0:
return
else:
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)
fname = os.path.basename(fname)
croppedImage.save(outputimg + '\\' + fname + ' -c' + ext)
n+=1
print 'Cropping:', fname
else:
print 'No faces found:', img
# Crop all images in a folder
Crop(inputimg + '\*.png', boxScale=1)
Crop(inputimg + '\*.jpg', boxScale=1)
Also, if anyone has any code improvements please let me know as I am new to Python.
I was able to fix this by reworking the logic and flow of code. Updated code below and on github, https://github.com/aDroidman/EyeonYou
import cv
import cv2
import numpy
import Image
import glob
import os
# Static
faceCascade = cv.Load('haarcascade_frontalface_alt.xml')
padding = -1
boxScale = 1
# Needed for webcam CV2 section
HaarXML = "haarcascade_frontalface_alt.xml"
classifier = cv2.CascadeClassifier(HaarXML)
downScale = 4
webcam = cv2.VideoCapture(0)
def DetectFace(image, faceCascade, returnImage=False):
#variables
min_size = (50,50)
haar_scale = 1.1
min_neighbors = 3
haar_flags = 0
DOWNSCALE = 4
# 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):
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 imgCrop(image, cropBox, boxScale=1):
# Crop a PIL image with the provided box [x(left), y(upper), w(width), h(height)]
# Calculate scale factors
xPadding=max(cropBox[2]*(boxScale-1),int(padding))
yPadding=max(cropBox[3]*(boxScale-1),int(padding))
# Convert cv box to PIL box [left, upper, right, lower]
PIL_box=[cropBox[0]-xPadding, cropBox[1]-yPadding, cropBox[0]+cropBox[2]+xPadding, cropBox[1]+cropBox[3]+yPadding]
return image.crop(PIL_box)
def Crop(imagePattern,boxScale,outputimg):
imgList=glob.glob(imagePattern)
if len(imgList)<=0:
return
else:
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)
fname = os.path.basename(fname)
croppedImage.save(outputimg + '\\' + fname + ' -c' + ext)
n+=1
print 'Cropping:', fname
else:
print 'No faces found:', img
def CropSetup(padding, boxScale):
inputimg = raw_input('Please enter the entire path to the image folder:')
outputimg = raw_input('Please enter the entire path to the output folder:')
# Create output folder if missing
if not os.path.exists(outputimg):
os.makedirs(outputimg)
# Get padding for crop
while (padding < 0):
padding = int(raw_input('Enter crop padding:'))
# Crop images
Crop(inputimg + '\*.png', boxScale, outputimg)
Crop(inputimg + '\*.jpg', boxScale, outputimg)
print 'Option 1: Detect image from Webcam'
print 'Option 2: Crop saved images'
option = int(raw_input('Please enter 1 or 2: '))
def Webcam(webcam, classifier, downScale):
if webcam.isOpened():
rval, frame = webcam.read()
else:
rval = False
while rval:
# detect faces and draw bounding boxes
minisize = (frame.shape[1]/downScale,frame.shape[0]/downScale)
miniframe = cv2.resize(frame, minisize)
faces = classifier.detectMultiScale(miniframe)
for f in faces:
x, y, w, h = [ v*downScale for v in f ]
cv2.rectangle(frame, (x,y), (x+w,y+h), (0,0,255))
cv2.putText(frame, "Press ESC to close.", (5, 25),
cv2.FONT_HERSHEY_SIMPLEX, 1.0, (255,255,255))
cv2.imshow("Face Crop", frame)
# get next frame
rval, frame = webcam.read()
key = cv2.waitKey(10)
if key in [27, ord('Q'), ord('q')]: # exit on ESC
break
if option == 1:
Webcam(webcam, classifier, downScale)
elif option == 2:
CropSetup(padding, boxScale)
else:
print 'Not a valid input'

Categories