Count number of detections with OpenCV lib with Python - python

I have started to learn OpenCV lib in Python. I want to write a code that will detect faces and eyes on the photo but also count number of detections.
I have wrote a picture that has 6 people on it.
You can download the image form here:
https://www.sendspace.com/file/cznbqa
I wrote a code that detect faces and eyes, but I do not know how to count number of detections.
Also, my code detect 4/8 faces and 1/12 eyes on the photo so...I probably have some issues in the code, If you can help me with that also, I would be very thankful.
# Standard imports
import cv2
import numpy as np
# Read image
my_image = cv2.imread("ljudi.jpg", 1)
# data for detecting faces and eyes
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_alt.xml')
eye_cascade = cv2.CascadeClassifier('haarcascade_eye.xml')
img = cv2.imread("ljudi.jpg", 1)
gray = cv2.cvtColor(img, 0)
faces = face_cascade.detectMultiScale(gray, 1.2, 4)
for (x,y,w,h) in faces:
#detect face with bule rectangle
#rec. start point (x,y), rec. end point (x+w, y+h), blue color(255,0,0), line width 2
face_rec = cv2.rectangle(img, (x,y), (x+w, y+h), (255,0,0), 1)
roi_gray = gray[y:y+h, x:x+w]
roi_color = img[y:y+h, x:x+w]
eyes = eye_cascade.detectMultiScale(roi_gray, 1.1, 2)
for (ex,ey,ew,eh) in eyes:
eye_rec = cv2.rectangle(roi_color, (ex,ey), (ex+ew, ey+eh), (0,255,0), )
cv2.imshow('img', img)
cv2.waitKey(0)

From the OpenCV documentation:
https://www.docs.opencv.org/2.4/modules/objdetect/doc/cascade_classification.html#cascadeclassifier-detectmultiscale
Detects objects of different sizes in the input image. The detected objects are returned as a list of rectangles.
where a rectangle for the Python bindings simply seems to be of type list [x,y,w,h] (https://www.docs.opencv.org/2.4/modules/core/doc/basic_structures.html#rect).
To the number of faces / rectangles returned inside the list can easily be retrieved by getting the length of the list (i.e. number of items inside), which is done with the Python builtin function len(): https://docs.python.org/3/library/functions.html#len.

Related

How to customize parameters for face detection by using face cascade

I have a simple face detection implementation as following
import cv2
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + "haarcascade_frontalface_default.xml")
filename = "path/to/image"
img = cv2.imread(filename)
cv2.imshow("Original image", img)
face_region = face_cascade.detectMultiScale(img, 1.1, 4)
for (x, y, w, h) in face_region:
cv2.rectangle(img, (x, y), (x+w, y+h), (255, 0, 0), 2)
cv2.imshow("Output", img)
cv2.waitKey(0)
after running the code, I got the following result
As you can see that, the implementation detects two faces! How can I get rid of this kind of false detection?
first delete the textual data like in this link Delete OCR word from Image (OpenCV,Python)
after that try to use you face detection code...then it will improve your accuracy

How to get each value of x,y,w,h in this crop image?

i want to ask something. In opencv there is cv2.rectangle to build a rectangle of object interest. After I got the object interest which is represent with rectangle, I want to get the region of interest box. To do that I used crop = frame[y:y+h, x:x+w].
Now I want to get the value of x,y,w,h of that cropped box. How to do that?
Here is my code
while bol:
capture = cv2.VideoCapture(0)
ret, frame = capture.read()
#load object detector
path = os.getcwd()+'\haarcascade_frontalface_default.xml'
face_cascade = cv2.CascadeClassifier(path)
#convert image to grayscale
imgGray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
for (x, y, w, h) in face_cascade.CascadeClassifier(imgGray):
cv2.rectangle(frame, (x,y), (x+w, y+h), (255,255,255), 3)
_croppedImage = frame[y:y+h, x:x+w]
ROI = _croppedImage
how to get value of x,y,w,h of _croppedImage ?
The value of x & y for _croppedImage is of no importance and significance. This is because the _croppedImage is simply an image cropped out of another image.
To get the w & h for _croppedImage, you can use .shape() method. w & h of an image is simply the width and height of the image respectively.
h, w = _croppedImage[:2]

How to recognize head movement in open CV?

Good afternoon, I currently have some code which detects eyes and faces using haar cascades, I was curious to see if anybody knows how to get the program to recognize movement of the head e..g. nod or movement of the eye e.g. blink.
Here is what i currently have:
import cv2
import numpy as np
"""
Created on Mon Mar 2 11:38:49 2020
#author: bradl
"""
# Open Camera
camera = cv2.VideoCapture(0)
camera.set(10, 200)
face_cascade = cv2.CascadeClassifier('haarcascades/face.xml')
##smile = cv2.CascadeClassifier('haarcascades/smile.xml')
eye_cascade = cv2.CascadeClassifier('haarcascades/eye.xml')
while True:
ret, img = camera.read()
## converts to gray
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
## determines what a face is and how it is found
faces = face_cascade.detectMultiScale(gray, 1.3, 5)
for (x,y,w,h) in faces:
## Determines the starting and ending co-ordinates for a blue rectangle to be drawn around the face
cv2.rectangle (img, (x,y), (x+w, y+h), (255,0,0), 2)
## Declares the region of the image where the eyes will be
roi_gray = gray[y:y+h, x:x+w]
roi_color = img[y:y+h, x:x+w]
## Determines what an eye is based on the eye haar cascade xml file
eyes = eye_cascade.detectMultiScale(roi_gray)
for (ex,ey,ew,eh) in eyes:
##Draws green rectangles around the co-ordintates for eyes
cv2.rectangle(roi_color, (ex, ey),(ex+ew,ey+eh), (0,255,0),2)
##Displays camera
cv2.imshow('Image',img)
##Requires the user to press escape to exit the program
k = cv2.waitKey(40)
if k == 27:
break
Does anybody have any ideas to get the program to recognize head or eye movement?
There are a number of ways to detect eye blinking.
In the ROI of the eyes apply white color detection.
Draw contours of around this mask, if the area of the contour is above a threshold you can interpret the eye is open, whenever there is a sudden change in the area of the contour, that is the point of a blink.
This method would fail if you move towards and away from the camera.
Another way of doing this would be face landmark detection using a library like DLIB.

How to mark features which are present in both arrays in OpenCV?

I'm trying to write a Python 3.7 script to detect faces and features using the OpenCV Haar classifier files which stores images as n-dimensional Numpy arrays. Right now I'm only working with two features:
- The entire face
- The eyes
Both of these are obtained using two different classifiers.
The Code detects the presence of both these features in the image and then marks them with a rectangle using the cv2.rectangle() function inside a for loop for each feature i.e, one for detected faces and one for detected eyes.
I want the script to mark the eye-rectangles ONLY if those points were found in the face array as well as the eye array. numpy.intersect1d() only finds intersection within one-dimensional arrays.
I've even tried
for x,y,w,h in eyes and x,y,w,h in faces:
and all it does is return this error message:
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
Any help would be greatly appreciated.
This is being attempted on Windows 10 64-bit, the code is written in Pycharm 2019, OpenCV is imported as CV2.
# Creating the cascade classifier objects.
face_cascade =
cv2.CascadeClassifier("haarcascade_frontalface_default.xml")
eye_cascade = cv2.CascadeClassifier("haarcascade_eye.xml")
# Entering and displaying the original image.
img = cv2.imread("filename.jpg", 1)
cv2.imshow("Original Images",img)
cv2.waitKey(0)
cv2.destroyAllWindows()
# Convert the image to Black and White and store in a variable.
gry_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gry_img, scaleFactor = 1.05, minNeighbors = 8)
eyes = eye_cascade.detectMultiScale(gry_img, scaleFactor = 1.30, minNeighbors = 12)
# Now, we mark the detected features with a rectangle on the original image.
for x,y,w,h in faces:
img = cv2.rectangle(img, (x,y), (x+w, y+h), (255, 21, 21), 3) # Blue.
for x,y,w,h in eyes:
img = cv2.rectangle(img, (x,y), (x+w, y+h), (255, 255, 24), 3) # Cyan.
cv2.imshow("Detected Faces and Eyes",img)
cv2.waitKey(0)
cv2.destroyAllWindows()
I need the eye-features to be marked only if they were ALSO found in the face-features array.
A better approach to solve this problem is already suggested in the OpenCV docs. It suggests that instead of passing the whole image for detecting the eyes, you should first detect the face, then crop the image, and use this cropped image for eyes detection. For cropping the face image you can use numpy slicing as:
for x,y,w,h in faces:
face_img = gry_img[y:y+h, x:x+w]
# Now detect the eyes in this `face_img` only.
eyes = eye_cascade.detectMultiScale(face_img, scaleFactor = 1.30, minNeighbors = 12)
Oh boy, do I feel stupid now. Well here goes:
As ZdaR said, the OpenCV documentation does indeed give a perfect example on how to achieve the result I required, the gist of which is:
for x,y,w,h in faces:
face_img = gry_img[y:y+h, x:x+w]
# Now detect the eyes in this `face_img` only.
eyes = eye_cascade.detectMultiScale(face_img, scaleFactor = 1.30, minNeighbors = 12)
What I needed to do other than this, apparently was to crop the original image to the face coordinates as well for the eye-features to be drawn upon. I'm still not sure if this should work, but for now it seems that adding that extra line does work.
Code that finally worked:
faces = face_cascade.detectMultiScale(gry_img, scaleFactor = 1.05, minNeighbors = 10)
for (x, y, w, h) in faces:
cv2.rectangle(img, (x, y),(x + w, y + h), (255, 0, 0), 3)
gry_eye = gry_img[y:y+h, x:x+w]
eye_img = img[y:y + h, x:x + w]
eyes = eye_cascade.detectMultiScale(gry_eye, scaleFactor = 1.05, minNeighbors = 5)
for (x, y, w, h) in eyes:
cv2.rectangle(eye_img, (x, y), (x + w, y + h), (255, 255, 24), 3)
Well, this has been a learning experience.
Thanks to ZdaR for the help!

Counting number of faces in Real time in python video

I am trying to create a face detection system in python using openCV that counts the total number of faces.(also it is detecting the eyes of the person).
But i want it to give the exact number of faces it detected say, by the end of day in real time.
following is the code.. any suggestions please:
import numpy as np
import cv2
face_cascade = cv2.CascadeClassifier('C:\Python27\Scripts\haarcascade_frontalface_default.xml')
eye_cascade = cv2.CascadeClassifier('C:\Python27\Scripts\haarcascade_eye.xml')
img = cv2.VideoCapture(0)
while(1):
_,f=img.read()
gray = cv2.cvtColor(f, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray, 1.3, 5)
print(len(faces))
for (x,y,w,h) in faces:
cv2.rectangle(f,(x,y),(x+w,y+h),(255,0,0),2)
roi_gray = gray[y:y+h, x:x+w]
roi_color = f[y:y+h, x:x+w]
eyes = eye_cascade.detectMultiScale(roi_gray)
for (ex,ey,ew,eh) in eyes:
cv2.rectangle(roi_color,(ex,ey),(ex+ew,ey+eh),(0,255,0),2)
cv2.imshow('img',f)
if cv2.waitKey(25) == 27:
break
cv2.destroyAllWindows()
img.release()

Categories