cv2.error when training image (Overload Resolution Failed) - python

I'm learning opencv via the following link link link2. And I got error related to image training process for face recognition. Please correct me or help with the problem I'm having. thank you
System Information :
OpenCV 4.5.2.52
Python 3.9.5
Detailed Description
I need to train an images by using the code below and the results was :
- OpenCV/faces-train.py", line 50, in <module>
recognizer.train(x_train, np.array(y_labels))
cv2.error: OpenCV(4.5.2) :-1: error: (-5:Bad argument) in function 'train'
> Overload resolution failed:
> - src is not a numpy array, neither a scalar
> - Expected Ptr<cv::UMat> for argument 'src'
Code
import cv2
import os
import numpy as np
from PIL import Image
import pickle
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
image_dir = os.path.join(BASE_DIR, "images")
face_cascade = cv2.CascadeClassifier('cascade/data/haarcascade_frontalface_alt2.xml')
recognizer = cv2.face.LBPHFaceRecognizer_create()
current_id = 0
label_ids = {}
y_labels = []
x_train = []
for root, dirs, files, in os.walk(image_dir):
for file in files:
if file.endswith("png") or file.endswith("jpg") or file.endswith("jpeg") :
path = os.path.join(root, file)
label = os.path.basename(root).replace(" ", "-").lower()
# print(label, path)
if not label in label_ids:
label_ids[label] = current_id
current_id += 1
id_ = label_ids[label]
# print(label_ids)
y_labels.append(label)
x_train.append(path)
pil_image = Image.open(path).convert("L")
image_array = np.array(pil_image, "uint8")
# print(image_array)
faces = face_cascade.detectMultiScale(image_array, scaleFactor=1.5, minNeighbors=5)
for(x,y,w,h) in faces:
roi = image_array[y:y+h, x:x+w]
x_train.append(roi)
y_labels.append(id_)
# print(y_labels)
# print(x_train)
with open("labels.pickle", 'wb') as f:
pickle.dump(label_ids, f)
recognizer.train(x_train, np.array(y_labels))
recognizer.save("trainner.yml")

remove the following lines:
y_labels.append(label)
x_train.append(path)
you don't really need to append the labels or the paths since you are basically training the face recognizer to recognise/categorise faces. Likewise, you wouldnt need the path to your images as it is also not necessary. Guessing this is what caused the error!
Do let me know if the fix works! Cheers :)

Related

"!empty() in function 'cv::CascadeClassifier::detectMultiScale'"

I am trying to work on a Face Recognition system in Python OpenCV but I keep getting the following error
"!empty() in function 'cv::CascadeClassifier::detectMultiScale'"
This is the code that I'm using:
import cv2
import os
import numpy as np
from PIL import Image
import pickle
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
image_dir = os.path.join(BASE_DIR, "foto")
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_alt2.xml')
recognizer = cv2.face.LBPHFaceRecognizer_create()
current_id = 0
label_ids = {}
y_labels = []
x_train = []
for root, dirs, files in os.walk(image_dir):
for file in files:
if file.endswith("png") or file.endswith("jpg"):
path = os.path.join(root, file)
label = os.path.basename(root).replace(" ", "-").lower()
#print(label, path)
if not label in label_ids:
label_ids[label] = current_id
current_id += 1
id_ = label_ids[label]
#print(label_ids)
#y_labels.append(label) # some number
#x_train.append(path) # verify this image, turn into a NUMPY
arrray, GRAY
pil_image = Image.open(path).convert("L") # grayscale
size = (550, 550)
final_image = pil_image.resize(size, Image.ANTIALIAS)
image_array = np.array(final_image, "uint8")
#print(image_array)
faces = face_cascade.detectMultiScale(image_array, scaleFactor=1.5, minNeighbors=5)
for (x,y,w,h) in faces:
roi = image_array[y:y+h, x:x+w]
x_train.append(roi)
y_labels.append(id_)
#print(y_labels)
#print(x_train)
with open("pickles/face-labels.pickle", 'wb') as f:
pickle.dump(label_ids, f)
recognizer.train(x_train, np.array(y_labels))
recognizer.save("recognizers/face-trainner.yml")
What am I doing wrong?
You need to put the full path to the file.
Example:
face_cascade = cv2.CascadeClassifier('C:\\working_Dir\\data\\codes\\OpenCV\\classifiers\\haarcascade_frontalface_alt2.xml')
You can download these codes from the github Repo here : Face Detection with Python using OpenCV
I had the same issue, you need to add double slashes instead of single ones.
git clone https://github.com/opencv/opencv.git
faceCascade = cv2.CascadeClassifier('opencv/data/haarcascades/haarcascade_frontalface_default.xml')
you have to give full path of your haarcascade_frontalface_alt2.xml file
like this:-"C:\Python39\Lib\site-packages\cv2\data\haarcascade_frontalface_alt2.xml"
Xml file is missing.
Try to give full path directly like this.
face_cascade = cv2.CascadeClassifier('C:\opencv\sources\data\haarcascades\haarcascade_frontalface_default.xml')
more importantly the file should be in C Directory

resize images while loading into python

Hi: I would like load some 2400 images from a folder into python 3.6 for Neural Networks, the following code works, however, it loads images in its original size, which is (2443, 320, 400, 3), after converting into an array. How do I resize it to 64x96? so it is (2443, 64, 96, 3) and less of a load on memory. Separately, how do I do it using parallel processing, so it is efficient.
Thank you!
IMAGE_PATH = 'drive/xyz/data/'
file_paths = glob.glob(path.join(IMAGE_PATH, '*.gif'))
# Load the images
images = [misc.imread(path) for path in file_paths]
images = np.asarray(images)
Inspired by this link, I tried to do the following:
from PIL import Image
basewidth = 96
IMAGE_PATH = 'drive/xyz/data/'
file_paths = glob.glob(path.join(IMAGE_PATH, '*.gif'))
# Load the images img = [misc.imread(path) for path in file_paths]
wpercent = (basewidth/float(img.size[0]))
hsize = int((float(img.size[1])*float(wpercent)))
img = img.resize((basewidth,hsize), Image.ANTIALIAS)
images = np.asarray(img)
however, it resulted in an error, written below. Any suggestions, would be greatly appreciated. Thank you.
AttributeError Traceback (most recent call last)
<ipython-input-7-56ac1d841c56> in <module>()
9 img = [misc.imread(path) for path in file_paths]
10
---> 11 wpercent = (basewidth/float(img.size[0]))
12 hsize = int((float(img.size[1])*float(wpercent)))
13 img = img.resize((basewidth,hsize), Image.ANTIALIAS)
AttributeError: 'list' object has no attribute 'size'
First you may want to resize your images then you can use your same method to initialize the arrays given the output image folder.
Resizing the image
This uses PIL package for resizing images but any library should do the same as long as it provides a resize method.
You can read further down discussions from here How do I resize an image using PIL and maintain its aspect ratio?
import os, sys
import Image
size = 128, 128
for infile in sys.argv[1:]:
outfile = os.path.splitext(infile)[0] + ".gif"
if infile != outfile:
try:
im = Image.open(infile)
im.thumbnail(size, Image.ANTIALIAS)
im.save(outfile, "GIF")
except IOError:
print "cannot create thumbnail for '%s'" % infile
Parallelism Example
Regarding parallelism you can use this example as a base and move on from there.
This is from the python docs https://docs.python.org/3/library/multiprocessing.html
from multiprocessing import Process
def f(name):
print('hello', name)
if __name__ == '__main__':
p = Process(target=f, args=('bob',))
p.start()
p.join()

histogram.cpp:3915: error: (-215) _src.type() == CV_8UC1 in function cv::equalizeHist

files2 = [f for f in listdir(dstpath) if isfile(join(dstpath,f))]
for image in files2:
img = cv2.imread(os.path.join(dstpath,image))
equ = cv2.equalizeHist(img)
dstPath2 = join(dstpath,image)
cv2.imwrite(dstPath2,equ)
I have a folder consisting of grayscale images in jpg format but when I run my above code for Histogram equalization it gives me the above mentioned error. Pls help
imread load image in color mode by default. Try to use img = cv2.imread(your_image_path,cv2.IMREAD_GRAYSCALE) instead
#author: Quantum
"""
import cv2
import os
from os import listdir,makedirs
from os.path import isfile,join
path = r'' # Source Folder
dstpath = r'' # Destination Folder
try:
makedirs(dstpath)
except:
print ("Directory already exist, images will be written in asme folder")
# Folder won't used
files = [f for f in listdir(path) if isfile(join(path,f))]
for image in files:
try:
img = cv2.imread(os.path.join(path,image),cv2.IMREAD_GRAYSCALE)
**imgnew=cv2.equalizeHist(img)**
dstPath = join(dstpath,image)
cv2.imwrite(dstPath,imgnew)
except:
print ("{} is not converted".format(image))
All I did was added the histeq function while my files are converted to grayscale

OpenCV3, Python 3 How to train FisherFaceRecognizer dataset?

I user openCV 3 and Python 3 to train face recognize. I can train LBPHFace and EigenFace with no error but it show error when train FisherFace.
This is my code.
import os
import cv2
import numpy as np
from PIL import Image
LBPHFace=cv2.face.LBPHFaceRecognizer_create()
EigenFace=cv2.face.EigenFaceRecognizer_create()
FisherFace=cv2.face.FisherFaceRecognizer_create()
path='dataSet'
def getImagesWithID(path):
imagePaths=[os.path.join(path,f) for f in os.listdir(path)]
#print imagePaths
faces=[]
IDs=[]
for imagePath in imagePaths:
faceImg=Image.open(imagePath).convert('L')
faceNp=np.array(faceImg,'uint8')
ID=int(os.path.split(imagePath)[-1].split('.')[1])
faces.append(faceNp)
IDs.append(ID)
cv2.imshow("training" , faceNp)
cv2.waitKey(10)
return np.array(IDs), faces
Ids,faces=getImagesWithID(path)
LBPHFace.train(faces, Ids)
LBPHFace.write('recognizer/LBPHData.xml')
EigenFace.train(faces, Ids)
EigenFace.write('recognizer/EigenData.xml')
FisherFace.train(faces, Ids)
FisherFace.write('recognizer/FisherData.xml')
cv2.destroyAllWindows()
It show error like this.
Traceback (most recent call last):
File "C:\Users\lenovoITC\AppData\Local\Programs\Python\Python36-32\training.py", line 33, in <module>
FisherFace.train(faces, Ids)
cv2.error: C:\projects\opencv-python\opencv\modules\core\src\lda.cpp:1019:
error: (-5) At least two classes are needed to perform a LDA. Reason: Only one class was given! in function cv::LDA::lda
How to train FisherFaceRecognizer dataset ?
My code works perfect.
# face_trainer.py
import cv2, numpy, os
fn_haar = 'haarcascade_frontalface_default.xml'
fn_dir = 'database'
# Part 1: Create fisherRecognizer
print('Training...')
# Create a list of images and a list of corresponding names
(images, labels, names, id) = ([], [], {}, 0)
for (subdirs, dirs, files) in os.walk(fn_dir):
for subdir in dirs:
names[id] = subdir
subjectpath = os.path.join(fn_dir, subdir)
for filename in os.listdir(subjectpath):
path = subjectpath + '/' + filename
images.append(cv2.imread(path, 0))
#labels.append(int(id))
labels.append(subdir)
id += 1
(im_width, im_height) = (112, 92)
# Create a Numpy array from the two lists above
(images, labels) = [numpy.array(lis) for lis in [images, labels]]
# OpenCV trains a model from the images
model = cv2.face.FisherFaceRecognizer_create()
model.train(images, labels)
model.write('trainer/trainer.yml')

AttributeError: 'module' object has no attribute 'io' in caffe

I am trying to do a gender recognition program, below is the code..
import caffe
import os
import numpy as np
import sys
import cv2
import time
#Models root folder
models_path = "./models"
#Loading the mean image
mean_filename=os.path.join(models_path,'./mean.binaryproto')
proto_data = open(mean_filename, "rb").read()
a = caffe.io.caffe_pb2.BlobProto.FromString(proto_data)
mean_image = caffe.io.blobproto_to_array(a)[0]
#Loading the gender network
gender_net_pretrained=os.path.join(models_path,
'./gender_net.caffemodel')
gender_net_model_file=os.path.join(models_path,
'./deploy_gender.prototxt')
gender_net = caffe.Classifier(gender_net_model_file, gender_net_pretrained)
#Reshaping mean input image
mean_image = np.transpose(mean_image,(2,1,0))
#Gender labels
gender_list=['Male','Female']
#cv2 Haar Face detector
face_cascade=cv2.CascadeClassifier(os.path.join
(models_path,'haarcascade_frontalface_default.xml'))
#Getting prediction from live camera
cap = cv2.VideoCapture(0)
while True:
ret,frame = cap.read()
if ret is True:
start_time = time.time()
frame_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
rects = face_cascade.detectMultiScale(frame_gray, 1.3, 5)
#Finding the largest face
if len(rects) >= 1:
rect_area = [rects[i][2]*rects[i][3] for i in xrange(len(rects))]
rect = rects[np.argmax(rect_area)]
x,y,w,h = rect
cv2.rectangle(frame,(x,y),(x+w,y+h),(255,0,0),2)
roi_color = frame[y:y+h, x:x+w]
#Resizing the face image
crop = cv2.resize(roi_color, (256,256))
#Subtraction from mean file
#input_image = crop -mean_image
input_image = rect
#Getting the prediction
start_prediction = time.time()
prediction = gender_net.predict([input_image])
gender = gender_list[prediction[0].argmax()]
print("Time taken by DeepNet model: {}").format(time.time()-start_prediction)
print prediction,gender
cv2.putText(frame,gender,(x,y), cv2.FONT_HERSHEY_SIMPLEX, 1,(0,255,0),2)
print("Total Time taken to process: {}").format(time.time()-start_time)
#Showing output
cv2.imshow("Gender Detection",frame)
cv2.waitKey(1)
#Delete objects
cap.release()
cv2.killAllWindows()
When I am running the I am getting an error:
a = caffe.io.caffe_pb2.BlobProto.FromString(proto_data)
AttributeError: 'module' object has no attribute 'io'
How Can I solve it. I am using cnn_gender_age_prediction model. I want to make a real time gender recognition program using python and cnn_gender_age model.
io is a module in caffe package. Basically when you type import caffe, it will not automatically try to import all modules in caffe package including io. There are two solutions.
First one: import caffe.io manually
import caffe
import caffe.io
Second one: update to the latest caffe version, in which you should find a line in __init__.py under python/caffe directory:
from . import io

Categories