I am trying to make it so when a face was detected, it would run a python command once instead of spamming it, for example print()
try:
import cv2
cap = cv2.VideoCapture(0)
pTime = 0
cascPath=os.path.dirname(cv2.__file__) "/data/haarcascade_frontalface_default.xml"
faceCascade = cv2.CascadeClassifier(cascPath)
face_detected = True
while True:
success, img = cap.read()
img = cv2.flip(img, 1)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
imgRGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
cTime = time.time()
fps = 1 / (cTime - pTime)
pTime = cTime
face_count = 0
cv2.putText(img, f'FPS:{int(fps)}', (20, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
faces = faceCascade.detectMultiScale(
gray,
scaleFactor=1.1,
minNeighbors=5,
minSize=(30, 30),
flags=cv2.CASCADE_SCALE_IMAGE
)
for (x, y, w, h) in faces:
cv2.rectangle(img, (x, y), (x w, y h), (0, 255, 0), 2)
face_count = face_count 1
cv2.putText(img, 'Face num ' str(face_count), (x-10, y-10),
cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)
cv2.putText(img, f'Faces Detected: {face_count}', (20, 70), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
if face_count > 0: # If one or more faces were detected
print("a face was detected")
elif face_count == 0: # If no faces were detected
print("the face magically disappeared")
cv2.imshow("Face Recognition", img)
if cv2.waitKey(1) & 0xFF == ord(' '):
cv2.destroyAllWindows()
break
except KeyboardInterrupt:
print("[KeyboardInterrupt] Exiting...")
time.sleep(2)
exit()
how can i make while the face is detected, it prints only once instead of spamming (without using something like \r
)
CodePudding user response:
You need to introduce state and react only when it changes.
Without copy-pasting your entire code, I'll just show you the idea.
# the state variable
seeing_faces = False
while True:
frame = get_frame()
faces = detect_faces(frame)
there_are_faces_now = (len(faces) > 0)
# compare state to current detection, different? state CHANGES
if there_are_faces_now and not seeing_faces:
print("NOW I see faces")
elif seeing_faces and not there_are_faces_now:
print("no longer seeing faces")
else:
# no change
# update state
seeing_faces = there_are_faces_now
CodePudding user response:
You can track the number of detected faces every frame and execute the command you want when the number of faces increases:
try:
import cv2
cap = cv2.VideoCapture(0)
pTime = 0
cascPath=os.path.dirname(cv2.__file__) "/data/haarcascade_frontalface_default.xml"
faceCascade = cv2.CascadeClassifier(cascPath)
face_detected = True
currentFaces = 0
while True:
success, img = cap.read()
img = cv2.flip(img, 1)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
imgRGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
cTime = time.time()
fps = 1 / (cTime - pTime)
pTime = cTime
face_count = 0
cv2.putText(img, f'FPS:{int(fps)}', (20, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
faces = faceCascade.detectMultiScale(
gray,
scaleFactor=1.1,
minNeighbors=5,
minSize=(30, 30),
flags=cv2.CASCADE_SCALE_IMAGE
)
for (x, y, w, h) in faces:
cv2.rectangle(img, (x, y), (x w, y h), (0, 255, 0), 2)
face_count = face_count 1
cv2.putText(img, 'Face num ' str(face_count), (x-10, y-10),
cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)
cv2.putText(img, f'Faces Detected: {face_count}', (20, 70), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
print(f"Faces Detected: {face_count}", end="\r")
#if face_count > 0: # If one or more faces were detected
# print("a face was detected")
#elif face_count == 0: # If no faces were detected
# print("the face magically disappeared")
if face_count > currentFaces:
print("Command to execute, face detected")
currentFaces = face_count
cv2.imshow("Face Recognition", img)
if cv2.waitKey(1) & 0xFF == ord(' '):
cv2.destroyAllWindows()
break
except KeyboardInterrupt:
print("[KeyboardInterrupt] Exiting...")
time.sleep(2)
exit()