Loop through directory and save all faces in other directory - python

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)

Related

I tried to display out all the images in a folder into a single cv2 frame at a time.But it only shows out one image forever

images = []
folder=r'C:\Users\lenovo\anaconda3\mainproject\violations'
for filename in os.listdir(folder):
img = cv2.imread(os.path.join(folder,filename))
if img is not None:
images.append(img)
cv2.namedWindow(winname)
cv2.moveWindow(winname, 300,100)
for img in images:
cv2.imshow(winname, img)
cv2.waitKey()
cv2.destroyAllWindows()
This code does work but displays out only one image.I need to display out all the images from violations folder at a time.
The wait key is indented away from the if loop. correct that to as follow
for img in images:
cv2.imshow(winname, img)
cv2.waitKey(0)

How to save multiple images in one folder by using open cv?

Here is the code that i'm trying to modify. To read and save all the images at once in one folder, however I got error when I tried to save it
import cv2
import glob
import numpy as np
#empty lists
image_list=[]
images = []
for img in glob.glob(r"C:\Users\user\Documents\Dataset\Test\Abnormal_Resize\Abnormal_Crop\*.png"):
n= cv2.imread(img)
images.append(n)
print (img)
#limit list to 236 elements
image_list = image_list[:100]
#Resizing the image for compatibility
for img in image_list:
image = cv2.resize(image, (500, 600))
#The initial processing of the image
#image = cv2.medianBlur(image, 3)
image_bw = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
#The declaration of CLAHE
#clipLimit -> Threshold for contrast limiting
clahe = cv2.createCLAHE(clipLimit = 5)
final_img = clahe.apply(image_bw)
cv2.imwrite(path+r"C:\Users\user\Documents\Dataset\Test\Abnormal_Resize\Abnormal_Crop\Abnormal_Cntrst\contrast_"+str(i)+".png", final_img)
It seems like there are multiple issues with this code.
i is not defined.
images list has all the images appended and while processing you are making use of the empty list variable image_list
You are probably looking for a solution like this.
import cv2
import glob
import numpy as np
input_path = r"<your_input_folder_path>/*.png"
# make sure below folder already exists
out_path = '<your_output_folder_path>/'
image_paths = list(glob.glob(input_path))
for i, img in enumerate(image_paths):
image = cv2.imread(img)
image = cv2.resize(image, (500, 600))
#The initial processing of the image
#image = cv2.medianBlur(image, 3)
image_bw = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
#The declaration of CLAHE
#clipLimit -> Threshold for contrast limiting
clahe = cv2.createCLAHE(clipLimit = 5)
final_img = clahe.apply(image_bw)
cv2.imwrite(out_path + f'{str(i)}.png', final_img)

Crop bunch of images in a directory in python open cv

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()

OpenCV image cropping error

I executed a program that reads all .jpg files from directory, performs face detection, crops the faces and saves them.
The problem is that when run an official python program I am able to detect all faces, but it saves only few faces from every image.
What am I doing wrong?
import cv2
import sys
import glob
cascPath = "haarcascade_frontalface_default.xml"
# Create the haar cascade
faceCascade = cv2.CascadeClassifier(cascPath)
files=glob.glob("*.jpg")
for file in files:
# Read the image
image = cv2.imread(file)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# Detect faces in the image
faces = faceCascade.detectMultiScale(
gray,
scaleFactor=1.1,
minNeighbors=5,
minSize=(30, 30),
flags = cv2.cv.CV_HAAR_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
# Dubugging boxes
# cv2.rectangle(image, (x, y), (x+w, y+h), (0, 255, 0), 2)
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)
As Gall said in the comments, the problem comes from your indentation. Your last three lines are not executed for each face as their indentation does not make them part of the loop over the faces. You want something like this:
# Draw a rectangle around the faces
for (x, y, w, h) in faces:
image = image[y-top:y+h+bottom, x-left:x+w+right]
cv2.imwrite("cropped_{1}_{0}".format(str(file),str(x)), image)
Note that with this code, there is a possibility of filename collision (2 faces with same in x in an image). You may want want to use a unique string to avoid that problem. A simple counter would do the trick.
problem your code is that when the first person cuts out the image, following already tries to cut not from the original image, and already from a certain first person so it's code you look think everyone will understand
import numpy as np
import cv2
import sys
import glob
cascPath = "haarcascade_frontalface_default.xml"
faceCascade = cv2.CascadeClassifier(cascPath)
img = cv2.imread('3.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
faces = faceCascade.detectMultiScale(
gray,
scaleFactor=1.1,
minNeighbors=5,
minSize=(30, 30),
#flags = cv2.cv.CV_HAAR_SCALE_IMAGE
flags=0
)
print "Found {0} faces!".format(len(faces))
left = 10
right = 10
top = 10
bottom = 10
i=0
count=0
for (x, y, w, h) in faces:
print x, y, w, h, i
i=i+1
img = img[y-top:y+h+bottom, x-left:x+w+right]
cv2.imwrite('foo{}.png'.format(count), img)
count += 1
img=cv2.imread('3.jpg')

How can i get array from 'imshow()' in opencv?

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

Categories