problem with circle correct eye detection in opencv - python

I have a problem with correct eye detection in the program below. The problem is the detection of eyes in the wrong place. If anyone knows the answer please help
import numpy as np
import cv2
cap = cv2.VideoCapture(0)
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
eye_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_eye.xml')
while True:
ret, frame = cap.read()
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray, 1.3, 5)
for (x, y, w, h) in faces:
cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 0, 0), 5)
roi_gray = gray[y:y + w, x:x + w]
roi_color = frame[y:y + h, x:x + w]
eyes = eye_cascade.detectMultiScale(roi_gray, 1.3, 5)
for (ex, ey, ew, eh) in eyes:
# center_coordinates = ex + ew // 2, ey + eh // 2
radius = eh // 2
cv2.circle(roi_color, (ex, ey), radius, (0, 0, 255), 5)
#cv2.rectangle(roi_color, (ex, ey), (ex + ew, ey + eh), (0, 255, 0), 5)
cv2.imshow('frame', frame)
if cv2.waitKey(1) == ord('q'):
break
cap.release()
cv2.destroyAllWindows()

When you draw a rectangle with cv2.rectangle you need top-left and bottom-right corners but when you draw a circle with cv2.circle you need the centre point. You are using cv2.circle with the same coordinates as with the initial rectangles, you need to transform them to the centre before. Add this and it should work
for (ex,ey,ew,eh) in eyes:
radius = eh//2
eye_x = int(ex+0.5*ew)
eye_y = int(ey+0.5*ey)
cv2.circle(roi_color, (eye_x, eye_y), radius, (0, 0, 255), 5)

Related

How to stop flipping the text when flipping the frame in cv2

I'm trying to make an app that can recognize face, eyes and the smile.
But everything is working good except the text on the box which is created when smiling. Because when I flipped the frame (frame that capture by 1cv2.VideoCapture(0)`), the text is also flipped.
How can I stop it? Any help please....
Here is my code,
import cv2
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + "haarcascade_frontalface_default.xml")
eye_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + "haarcascade_eye.xml")
smile_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + "haarcascade_smile.xml")
cap = cv2.VideoCapture(0)
while True:
_, img = cap.read()
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
fsced = face_cascade.detectMultiScale(gray, 1.1, 4)
eyes = eye_cascade.detectMultiScale(gray, 1.3, 5)
for (x, y, w, h) in fsced:
center_cordinates = x + w // 2, y + h // 2
radius = w // 2
cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 3)
roi_gray = gray[y : y + h, x : x +w]
roi_colour = img[y : y + h, x : x +w]
smiles = smile_cascade.detectMultiScale(roi_gray, 1.8, 20)
for (sx, sy, sw, sh) in smiles:
cv2.rectangle(roi_colour, (sx, sy), ((sx + sw), (sy + sh)), (0, 0, 255), 2)
cv2.putText(roi_colour, "Smile", (sx, sy), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)
for (ex, ey, ew, eh) in eyes:
center_cordinates_eye = ex + ew // 2, ey + eh // 2
radius_eye = w // 10
cv2.circle(img, center_cordinates_eye, radius_eye, (5, 50, 10), thickness=2, lineType=8, shift=0)
img = cv2.flip(img, 1)
cv2.imshow('img', img)
if cv2.waitKey(1) == ord('q'):
break
cap.release()
cv2.destroyWindow('img')
In this code you can see the text "Smile". when I run the code, this text will flip.
I tried changing the text after the flipping, But nothing good.
Like this,
Text = "" # This Text = "" is at the start of the code
"""
Other code
"""
img = cv2.flip(img, 1)
Text = "Smile"
In the moment when you do:
cv2.putText(roi_colour, "Smile", (sx, sy), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)
You "melt" the text into the image, you cannot modify it per se after that.
Regarding:
I tried changing the text after the flipping, But nothing good. Like this,
What you did was you actually changed the value of the string "Text", you can print it below, it is indeed changed, but the np.array/openCV image is not.
You can however gather the coordinates for the text into a list let's say and then in a loop add the text after the flipping.
smiles_coordinates = []
for (sx, sy, sw, sh) in smiles:
cv2.rectangle(roi_colour, (sx, sy), ((sx + sw), (sy + sh)), (0, 0, 255), 2)
smiles_coordinates.append((sx,sy)) # Here the "sy" is probably fine, but figure out correct "sx" as a homework
And then after the flip
for (sx, sy) in smile_coordinates:
cv2.putText(roi_colour, "Smile", (sx, sy), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)

auto detect face only when the human is in motion and take a snapshot with opencv

I'm working on Face recognition project in python, trying to take a snapshot of a human face from an IP cam whenever a human comes in the cam steam. Here is the code:
import numpy as np
import cv2
import time
#import the cascade for face detection
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
def TakeSnapshotAndSave():
video = cv2.VideoCapture("rtsp://user:password#0.0.0.0:553/Streaming/Channels/401")
width = 1500
height = 1080
dim = (width, height)
num = 0
while True:
_, frame = video.read()
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray, 1.3, 5)
for (x, y, w, h) in faces:
cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 0, 0), 2)
roi_gray = gray[y:y + h, x:x + w]
roi_color = frame[y:y + h, x:x + w]
x = 0
y = 20
text_color = (0, 255, 0)
cv2.imwrite('opencv' + str(num) + '.jpg', frame)
num = num + 1
frame = cv2.resize(frame, (1500, 1000))
cv2.imshow("Lodhran Camera", frame)
k = cv2.waitKey(1)
if k == ord('q'):
break
video.release()
cv2.destroyAllWindows()
if __name__ == "__main__":
TakeSnapshotAndSave()
But it takes the image of the full frame not only the face, while I just want the only faces to be snapped and to be saved like if the frame has 5 humans in the frame at the same time, the out put will be 5 images of the faces of that 5 humans, not the full frame with all humans. Any help with the code will be appreciated, thanks in advance.
I guess you need to modify your code to make a cropped image for every facebox and then write the cropped image, not a basic frame:
for (x, y, w, h) in faces:
cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 0, 0), 2)
roi_gray = gray[y:y + h, x:x + w]
roi_color = frame[y:y + h, x:x + w]
cropped_frame = frame[(x, y), (x + w, y + h)]
cv2.imwrite("some_name.jpg", cropped_frame)
...

Webcam stops working after running the opencv python code [duplicate]

This question already has answers here:
error: (-215) !empty() in function detectMultiScale
(26 answers)
Closed 10 months ago.
I am trying to do face and eye recognition with rectangles for eyes and face using OpenCv Python.
I read some of the questions and I tried the answers below the questions on similiar topics but still getting the error. The code that i've tried activates the webcam and in a second it stops working.
Here the error message:
error: OpenCV(4.5.4-dev) D:\a\opencv-python\opencv-python\opencv\modules\objdetect\src\cascadedetect.cpp:1689: error: (-215:Assertion failed) !empty() in function 'cv::CascadeClassifier::detectMultiScale'
Here my code that i have tried:
import numpy as np
import cv2
cap = cv2.VideoCapture(0)
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
eye_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_eye_default.xml')
while True:
ret, frame = cap.read()
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray, 1.3, 5)
for (x, y, w, h) in faces:
cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 0, 0), 5)
roi_gray = gray[y:y+w, x:x+w]
roi_color = frame[y:y+h, x:x+w]
eyes = eye_cascade.detectMultiScale(roi_gray, 1.3, 5)
for (ex, ey, ew, eh) in eyes:
cv2.rectangle(roi_color, (ex, ey), (ex + ew, ey + eh), (0, 255, 0), 5)
cv2.imshow('frame', frame)
if cv2.waitKey(1) == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
Thank you.
Edit: I noticed that once I run the code the webcam has been activated and if there is no face in front of the camera it stays active without any error but once I show my face it stops working.
Hope this will work !
import numpy as np
import cv2
cap = cv2.VideoCapture(0)
face_cascade = cv2.CascadeClassifier("haarcascade_frontalface_default.xml")
eye_cascade = cv2.CascadeClassifier("haarcascade_eye.xml")
while True:
ret, frame = cap.read()
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray, 1.3, 5)
for (x, y, w, h) in faces:
cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 0, 0), 5)
roi_gray = gray[y:y+w, x:x+w]
roi_color = frame[y:y+h, x:x+w]
eyes = eye_cascade.detectMultiScale(roi_gray, 1.3, 5)
for (ex, ey, ew, eh) in eyes:
cv2.rectangle(roi_color, (ex, ey), (ex + ew, ey + eh), (0, 255, 0), 5)
cv2.imshow('frame', frame)
if cv2.waitKey(1) == ord('q'):
break
cap.release()
cv2.destroyAllWindows()

How to make a mesh within rectangle using drawing functions of the OpenCV?

This is my full code.
import cv2
import numpy as np
cap = cv2.VideoCapture(0)
width = cap.get(3) # float
height = cap.get(4) # float
print (width, height)
while (1):
_, img = cap.read()
if _ is True:
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
else:
continue
# blue color
blue_lower = np.array([86,0,90], np.uint8)
blue_upper = np.array([163, 64, 145], np.uint8)
blue = cv2.inRange(hsv, blue_lower, blue_upper)
kernal = np.ones((9, 9), "uint8")
blue = cv2.dilate(blue, kernal)
res_blue = cv2.bitwise_and(img, img, mask=blue)
# Tracking blue
(_, contours, hierarchy) = cv2.findContours(blue, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
for pic, contour in enumerate(contours):
area = cv2.contourArea(contour)
if (area > 2000):
print (area)
x, y, w, h = cv2.boundingRect(contour)
img = cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 2)
cv2.putText(img, "Blue Colour", (x, y), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 0, 0))
# cv2.putText(img, "Blue Colour", (x, y), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 0, 0))
cv2.imshow("Color Tracking", img)
if cv2.waitKey(10) & 0xFF == ord('q'):
cap.release()
cv2.destroyAllWindows()
break
I would like to mesh all rectangles as these pictures.
you can see the mesh of the contour next to them.
In my case, I would like to mesh rectangles themselves.
This picture is taken from this video

Create Mask Inside ROI selection

Hi I am trying to make the eyes that is circled to be white. I know we cant delete the eyes so i wanted to mask it, but i couldnt figure out a way. Below is my code.
import cv2
import os
cascPathface = os.path.dirname(
cv2.__file__) + "/data/haarcascade_frontalface_alt2.xml"
cascPatheyes = os.path.dirname(
cv2.__file__) + "/data/haarcascade_eye_tree_eyeglasses.xml"
faceCascade = cv2.CascadeClassifier(cascPathface)
eyeCascade = cv2.CascadeClassifier(cascPatheyes)
while True:
img = cv2.imread('man1.png')
newImg = cv2.resize(img, (600,600))
gray = cv2.cvtColor(newImg, cv2.COLOR_BGR2GRAY)
faces = faceCascade.detectMultiScale(gray,
scaleFactor=1.1,
minNeighbors=5,
minSize=(60, 60),
flags=cv2.CASCADE_SCALE_IMAGE)
for (x,y,w,h) in faces:
cv2.rectangle(newImg, (x, y), (x + w, y + h),(0,255,0), 2)
faceROI = newImg[y:y+h,x:x+w]
eyes = eyeCascade.detectMultiScale(faceROI)
for (x2, y2, w2, h2) in eyes:
eye_center = (x + x2 + w2 // 2, y + y2 + h2 // 2)
radius = int(round((w2 + h2) * 0.25))
frame = cv2.circle(newImg, eye_center, radius, (255, 0, 0), 4)
# Display the resulting frame
cv2.imshow('Image', newImg)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
last = cv2.imwrite('faces_detected.png', faceROI)
cv2.destroyAllWindows()
This is the image where i want the eyes to be white:
In order to mask the eyes, change the thickness parameter in the cv2.circle method to -1. That will fill the circle with the specified color.
Change the code from frame = cv2.circle(newImg, eye_center, radius, (255, 0, 0), 4) to frame = cv2.circle(newImg, eye_center, radius, (255, 0, 0), -1).
Refer: https://www.geeksforgeeks.org/python-opencv-cv2-circle-method/
Kindly do upvote the solution, if you find it helpful.

Categories

Resources