I have a program that detects a face when the the web cam i recording. I've created a region of interest and i want to only detect faces only within the roi. Im trying to instruct my program to operate only in that region. Have no clue how to
cap = cv2.VideoCapture(0)
Cascade_face = cv2.CascadeClassifier('C:\\Users\moham\PycharmProjects\Face\cascade\cascade.xml')
roi = cap[40:520,340:550]
while True:
success, img = cap.read()
imgGray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
faces = Cascade_face.detectMultiScale(imgGray, 1.3, 5)
for (x, y, w, h) in faces:
img = cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 3)
cv2.imshow('face_detect', img)
if cv2.waitKey(10) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyWindow('face_detect')
Try this for ROI. I do not have cascade.xml. Actually, I cannot test it.
for (x,y,w,h) in faces:
cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
roi_gray = gray[y:y+h, x:x+w]
roi_color = img[y:y+h, x:x+w]
cv2.imshow('face_detect',img)
k = cv2.waitKey(30) & 0xff
if k == 27: # press 'ESC' to quit
break
cap.release()
cv2.destroyAllWindows()
You need to create a mask using the coordinates of the ROI.
Sample image taken from this link:
Code:
img = cv2.imread('crowd.jpg')
# create background to draw the mask
black = np.zeros((img.shape[0], img.shape[1]), np.uint8)
#ROI for this image: img[40:180, 130:300]
# create the mask using ROI coordinates
black = cv2.rectangle(black, (180, 40), (300, 130), 255, -1)
# masking the image
roi = cv2.bitwise_and(img, img, mask = black)
Now you can perform face detection on roi. You need to incorporate the above snippet in your code accordingly.
Note: To draw rectangle, cv2.rectangle() follows (x1, y1), (x2, y2) order. But to crop an image, the order is reversed: crop_img = img[y1:x1, y2:x2]
Related
hi guys I want to implement (zoom in and zoom out) like digital camera to the detected faces while real-time capturing using opencv, is there is any way I can do it without just cropping the frame then display it.
here is my code ... ,,,
import cv2
# Load the cascade
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
# To capture video from webcam.
cap = cv2.VideoCapture(0)
# To use a video file as input
# cap = cv2.VideoCapture('filename.mp4')
while True:
# Read the frame
_, img = cap.read()
# Convert to grayscale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Detect the faces
faces = face_cascade.detectMultiScale(gray, 1.1, 4)
# Draw the rectangle around each face
for (x, y, w, h) in faces:
cv2.rectangle(img, (x, y), (x+w, y+h), (255, 0, 0), 2)
# Display
cv2.imshow('img', img)
# Stop if escape key is pressed
k = cv2.waitKey(30) & 0xff
if k==27:
break
# Release the VideoCapture object
cap.release()
I am trying to use face detection but I do not want the video feed window to open up when I use videocapture, this is the code I'm working on:
import cv2
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
cap = cv2.VideoCapture(0)
while True:
_, img = cap.read()
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray, 1.1, 4)
for (x, y, w, h) in faces:
cv2.rectangle(img, (x, y), (x+w, y+h), (255, 0, 0), 2)
cv2.imshow('img', img)
k = cv2.waitKey(30) & 0xff
if k==27:
break
cap.release()
I just want to somehow disable the video feed window that opens up automatically and instead get an output on the command line every time it detects a face.
I am using the code from here: https://github.com/adarsh1021/facedetection.
Thank you.
Reomve cv2.imshow('img', img) and replace it with print(faces)
cv2.imshow() is responsible for opening of image window.
My program can detect my left eye, but I want it to be able to place a dot around on the center of the detected area. I tried to calculate it but it always places the dot near the upper left hand corner. Any Ideas/Help would be appreciated.
import cv2
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
eye_cascade = cv2.CascadeClassifier('haarcascade_eye.xml')
cap = cv2.VideoCapture(0) # sets up webcam
while 1: # capture frame, converts to greyscale, looks for faces
ret, img = cap.read()
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray, 1.3, 5)
for (x, y, w, h) in faces: # draws box around face
cv2.rectangle(img, (x, y), (x + int(w / 2), y + int(h / 2)), (255, 0, 0), 2) # Draws Box Around Face
roi_gray = gray[y:y + int(h / 2), x:x + int(w / 2)] # slices grey area based off given parameters
roi_color = img[y:y + h, x:x + w] # selects region of interest (roi) based on color
eyes = eye_cascade.detectMultiScale(roi_gray) # looks for eyes
for (ex, ey, ew, eh) in eyes: # draws boxes around eyes
eye_centerX = (ex+(ex+ew))/2
eye_centerY = (ey+(ey+eh))/2
eye_center_cord = eye_centerX, eye_centerY
cv2.line(img, (int(eye_centerX), int(eye_centerY)), (int(eye_centerX), int(eye_centerY)), (0, 0, 0), 10)
cv2.imshow('img', img)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
The problem is that the eye detector module works for one eye at a time. Even if you see two eyes being boxed in the image, that for loop is actually related with one eye.
The solution would be to separate the face box into two parts and detect the left and right eyes separately by looking coordinates.
If the explanation is not clear enough, I can explain it by editing your code. Just say it .
Here is the edited code:
import cv2
left_eye_point_x = 0
right_eye_point_x = 0
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
eye_cascade = cv2.CascadeClassifier('haarcascade_eye.xml')
cap = cv2.VideoCapture(0) # sets up webcam
while 1: # capture frame, converts to greyscale, looks for faces
ret, img = cap.read()
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray, 1.3, 5)
for (x, y, w, h) in faces: # draws box around face
cv2.rectangle(img, (x, y), (x + int(w / 2), y + int(h / 2)), (255, 0, 0), 2) #
roi_gray = gray[y:y + int(h / 2), x:x + int(w / 2)]
roi_color = img[y:y + h, x:x + w]
eyes = eye_cascade.detectMultiScale(roi_gray) # looks for eyes
for (ex, ey, ew, eh) in eyes: # draws boxes around eyes
if (ex+ey)/2 < (x+y)/2:
left_eye_point_x = (ex+ey)/2
elif (ex+ey)/2 > (x+y)/2:
right_eye_point_x = (ex+ey)/2
cv2.line(img, (int(left_eye_point_x), int(right_eye_point_x)), (int(left_eye_point_x), int(right_eye_point_x)), (0, 0, 0), 10)
cv2.imshow('img', img)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
I want to change the rectangle size of this face detector i need it about 25% bigger:
import cv2
# Load the cascade
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
# Read the input image
img = cv2.imread('test.jpg')
# Convert into grayscale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Detect faces
faces = face_cascade.detectMultiScale(gray, 1.1, 4)
# Draw rectangle around the faces
for (x, y, w, h) in faces:
cv2.rectangle(img, (x, y), (x+w, y+h), (255, 0, 0), 2)
# Display the output
cv2.imshow('img', img)
cv2.waitKey()
xml: https://raw.githubusercontent.com/opencv/opencv/master/data/haarcascades/haarcascade_frontalface_default.xml
but I don't know how to do it
I have this code to detect laser points using the open cv library and I had it working when I would feed it a .jpg or .png file as an augment but now I want to get an image from a camera. "video 0" I am using Ubuntu 16.04 here is my code I marked the problem with ******
any help would greatly be appreciated:
# import the necessary packages
from imutils import contours
from skimage import measure
import numpy as np
import argparse
import imutils
import cv2
# construct the argument parse and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", required=False,
help="path to the image file")
args = vars(ap.parse_args())
camera = cv2.VideoCapture(0)
#problem is here ********************************************
ret, image = camera.read()
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blurred = cv2.GaussianBlur(gray, (11, 11), 0)
#threshold the image to reveal light regions in the
# blurred image
thresh = cv2.threshold(blurred, 200, 255, cv2.THRESH_BINARY)[1]
# perform a series of erosions and dilations to remove
# any small blobs of noise from the thresholded image
thresh = cv2.erode(thresh, None, iterations=2)
thresh = cv2.dilate(thresh, None, iterations=4)
# perform a connected component analysis on the thresholded
# image, then initialize a mask to store only the "large"
# components
labels = measure.label(thresh, neighbors=8, background=0)
mask = np.zeros(thresh.shape, dtype="uint8")
# loop over the unique components
for label in np.unique(labels):
# if this is the background label, ignore it
if label == 0:
continue
# otherwise, construct the label mask and count the
# number of pixels
labelMask = np.zeros(thresh.shape, dtype="uint8")
labelMask[labels == label] = 255
numPixels = cv2.countNonZero(labelMask)
# if the number of pixels in the component is sufficiently
# large, then add it to our mask of "large blobs"
if numPixels > 300:
mask = cv2.add(mask, labelMask)
# find the contours in the mask, then sort them from left to
# right
cnts = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)
cnts = contours.sort_contours(cnts)[0]
# loop over the contours
for (i, c) in enumerate(cnts):
# draw the bright spot on the image
(x, y, w, h) = cv2.boundingRect(c)
((cX, cY), radius) = cv2.minEnclosingCircle(c)
#x and y center are cX and cY
cv2.circle(image, (int(cX), int(cY)), int(radius),
(0, 0, 255), 3)
cv2.putText(image, "#{}".format(i + 1), (x, y - 15),
cv2.FONT_HERSHEY_SIMPLEX, 0.45, (0, 0, 255), 2)
# show the output image
cv2.imshow("Image", image)
cv2.waitKey(0)
Wrapping your camera capture in a While loop with a break condition might help:
import cv2
cap = cv2.VideoCapture(0)
while True:
ret, frame = cap.read()
cv2.imshow('frame', frame)
# ADD LOGIC HERE
print(frame.shape)
# END
if cv2.waitKey(20) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
Your is working fine & detect a face from video feed. But, you can do it another way...
'''
:: Face Detection using Haar Cascades ::
'''
import numpy as np
import cv2, argparse
# set classifiers
face_cascade = cv2.CascadeClassifier(
'/opt/opencv/main/data/haarcascades/haarcascade_frontalface_default.xml'
)
cam = cv2.VideoCapture(0)
_, img = cam.read()
# load image & convert
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# find faces; If faces are found, it returns the positions
# of detected faces as Rect(x,y,w,h).
faces = face_cascade.detectMultiScale(gray, 1.2, 5)
print "[ INFO:1] Found ", len(faces), "face(s) in this image."
for (x, y, w, h) in faces:
cv2.rectangle(
img,
(x, y),
(x+w, y+h),
(255, 100, 25),
2
)
cv2.imshow('Image', img)
cv2.waitKey(0)
cv2.destroyAllWindows()