I have a bunch of images say 200 in a folder I want to crop all of them. I know the logic to loop through the images in the folder and perform cropping. I wrote a code for cropping of the single image but for multiple images, when I tried to loop through them it showing error.
This is for the single image. This is working fine
import numpy as np
import cv2
import os
count=0
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
img = cv2.imread('C:\\Users\\Sasidhar Mankala\\Desktop\\pythonproject\\DataBase creation\\Images\\85.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray, 1.3, 5)
for (x,y,w,h) in faces:
roi_gray = gray[y:y+h, x:x+w]
roi_color = img[y:y+h+8, x:x+w+8]
crop = img[y-8: y+h+8 , x-8: x+w+8]
image_name = str(count)+'.png'
image_path = os.path.join('C:\\Users\\Sasidhar Mankala\\Desktop\\pythonproject\\DataBase creation\\Cropped_Images',image_name)
count += 1
cv2.imwrite(image_path,crop)
cv2.waitKey(0)
cv2.destroyAllWindows()
For the multiple images, I got this far but this growing error
import numpy as np
import cv2
import os
count=0
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
directory = 'C:\\Users\\Sasidhar Mankala\\Desktop\\pythonproject\\DataBase creation\\Images'
for images in directory:
gray = cv2.cvtColor(images, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray, 1.3, 5)
for (x,y,w,h) in faces:
# img = cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
roi_gray = gray[y:y+h, x:x+w]
roi_color = images[y:y+h+8, x:x+w+8]
crop = images[y-8: y+h+8 , x-8: x+w+8]
image_name = str(count)+'.png'
image_path = os.path.join('C:\\Users\\Sasidhar Mankala\\Desktop\\pythonproject\\DataBase creation\\Cropped_Images',image_name)
count += 1
cv2.imwrite(image_path,crop)
cv2.waitKey(0)
cv2.destroyAllWindows()
the error showing is
Traceback (most recent call last):
File "c:\Users\Sasidhar Mankala\Desktop\pythonproject\DataBase creation\crop.py", line 11, in
gray = cv2.cvtColor(images, cv2.COLOR_BGR2GRAY)
TypeError: Expected Ptr<cv::UMat> for argument 'src'
I think this is happening is because of cvtColor is expecting a specific path but I don't understand how to do that.
Please help me with this. Thanks in advance
You've to iterate on the images in your directory (feel free to substitute jpg if you have another format
import glob
for images in glob.glob(''.join([directory, r"\*.jpg"])):
# Your code...
In your previous code you were iterating over a string
The problem is this line
for images in directory:
You are not getting the path for each image.
To get the path for each image do:
import os
path_to_images = 'C:/Users/Sasidhar Mankala/Desktop/pythonproject/DataBase reation/Images/'
for imgName in os.listdir(path_to_images):
imgPath = path_to_images + imgName
os.listdir(directory) returns a list of all the filenames in that directory
Another error is in the input to cvtColor. It takes an image input not an image path. So:
image = cv2.imread(imgPath)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
You were also trying to manipulate a path. Notice how in roi_color now is using the imported image and in your code it was trying to use what was supposed to be the image path (images).
faces = face_cascade.detectMultiScale(gray, 1.3, 5)
for (x,y,w,h) in faces:
# img = cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
roi_gray = gray[y:y+h, x:x+w]
roi_color = image[y:y+h+8, x:x+w+8]
crop = image[y-8: y+h+8 , x-8: x+w+8]
image_name = str(count)+'.png'
image_path = os.path.join('C:\\Users\\Sasidhar Mankala\\Desktop\\pythonproject\\DataBase creation\\Cropped_Images',image_name)
count += 1
cv2.imwrite(image_path,crop)
cv2.waitKey(0)
cv2.destroyAllWindows()
Related
I am trying to detect faces (specifically, faces with opened eyes) using OpenCV haar cascade classifier. However, I had a problem detecting the faces that do not have eyebrows and/or jaw, as shown in the following image. I had tried many haar cascade for face detection such as haarcascade_frontalface_default.xml, haarcascade_frontalface_alt_tree.xml, etc. But all of these did not work.
Here is my code:
import cv2
import os
import glob
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
eye_cascade = cv2.CascadeClassifier('haarcascade_eye_tree_eyeglasses.xml')
count = 0
path = "./test/*.png"
for index, filename in enumerate(glob.glob(path)):
img = cv2.imread(filename)
basename = os.path.splitext(os.path.basename(filename))[0]
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray, 1.3, 5)
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]
eyes = eye_cascade.detectMultiScale(roi_gray)
if len(eyes) >= 2:
count = count + 1
output_dir = './test/output'
cv2.imwrite(f'{output_dir}/{basename}.png', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
Thank you in advance!
Use facial landmarks with dlib, this method may work for you, see these two links:
facial-landmarks-dlib-opencv-python
opencv-face-recognition
Also, see this link:
dlib-and-deep-learning
If you have tensorflow installed you can use a neural net to detect faces which give much better accuracy than the simple haar classifier.
Here's an example using the MTCNN detector which uses tensorflow as the backend.
from mtcnn.mtcnn import MTCNN
from PIL import Image
import numpy as np
img = Image.open('6qNFu.png') # load the image
img = np.asarray(img, dtype='uint8') # convert to numpy array
img = img[:,:,0:3] # drop the alpha channel
detector = MTCNN() # initialize MTCNN detector
print(detector.detect_faces(img)) # use MTCNN detector to return bounding box and face metrics
Using the bounding box you can extract the face from the image. Note: if the face is truncated like in the instances above, it might return a negative coordinate which is an extrapolation of where it thinks the face might be.
Here is a the documentation on MTCNN library: https://pypi.org/project/mtcnn/
It also tells you how to install it.
I'm new in OpenCV. I'm trying to save the detected object into a new image.
What should I do?
This is the code I copied from a tutorial:
import cv2
import numpy as np
tric_cascade = cv2.CascadeClassifier('cascade.xml')
img = cv2.imread('anthon18c.png')
gray= cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
tric = tric_cascade.detectMultiScale(gray,1.01,7)
for (x,y,w,h) in tric:
img = cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
If you want to save image named img, you can use:
cv2.imwrite('/path/to/destination/image.png', img)
I would like to loop through all the images from the directory and save faces in other directory. This is my code.
cascPath = "haarcascade_frontalface_alt2.xml"
# Create the haar cascade
faceCascade = cv2.CascadeClassifier(cascPath)
import glob
files=glob.glob("*.jpg")
for file in files:
# Read the image
image = cv2.imread(file)
print(file)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# Detect faces in the image
faces = faceCascade.detectMultiScale(gray, scaleFactor=1.3, minNeighbors=4,
minSize=(30, 30), flags = cv2.CASCADE_SCALE_IMAGE)
print ("Found {0} faces!".format(len(faces)))
# Crop Padding
left = 10
right = 10
top = 10
bottom = 10
# Draw a rectangle around the faces
for (x, y, w, h) in faces:
print (x, y, w, h)
image = image[y-top:y+h+bottom, x-left:x+w+right]
print ("cropped_{1}{0}".format(str(file),str(x)))
cv2.imwrite("cropped_{1}_{0}".format(str(file),str(x)), image)
The above code expects the image to be in jpg format. It also retrieves the image from the root folder and saves in the root folder itself.
How can I loop through test_input directory and save all faces in test_output directory?
To loop through test_input, modify the string passed to glob.glob:
files = glob.glob("test_input/*.jpg")
To save to a particular output directory simply specify that directory when saving your image. Use os.path.join to join paths safely.
import os
cv2.imwrite(os.path.join("test_output", "cropped_{1}_{0}".format(str(file),str(x))), image)
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()
I use opencv to open a camera, it shows face area croping in another window at once, so i have 2 windows in the same time. So i would like to show image and get array at once. Below is my script
import numpy as np
import cv2
# load clasifier from file
face_cascade = cv2.CascadeClassifier('cascades\haarcascade_frontalface_default.xml')
img = cv2.VideoCapture(0)
while(1):
#Read images
h,f=img.read()
gray = cv2.cvtColor(f, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray, 1.3, 5)
for (x,y,w,h) in faces:
# create rectangle
cv2.rectangle(f,(x,y),(x+w,y+h),(255,255,255),)
# crop face area
roi_gray = gray[y:y+h, x:x+w]
# showing crop face area
cv2.imshow('crop',roi_gray)
#create window camera which name is img
cv2.imshow('img',f)
key = cv2.waitKey(200)
if key in [27, ord('Q'), ord('q')]:
break
How to get array from cv2.imshow('crop',roi_gray)? Thank you