OpenCV Error: Bad argument (This Fisherfaces model is not computed yet. Did you
call Fisherfaces::train?) in cv::face::Fisherfaces::predict,
cv2.error: C:\projects\opencv-python\opencv_contrib\modules\face\src\fisher_faces.cpp:137: error: (-5) This Fisherfaces model is not computed yet. Did you call Fisherfaces::train? in function cv::face::Fisherfaces::predict
import cv2
import numpy as np
import argparse
import time
import glob
import os
import sys
import subprocess
import pandas
import random
import Update_Model
import math
#Define variables and load classifier
camnumber = 0
video_capture = cv2.VideoCapture()
facecascade = cv2.CascadeClassifier("haarcascade_frontalface_default.xml")
fishface = cv2.face.FisherFaceRecognizer_create()
try:
fishface.read("trained_emoclassifier.xml")
except:
print("no trained xml file found, please run program with --update flagfirst")
parser = argparse.ArgumentParser(description="Options for the emotion-based music player")
parser.add_argument("--update", help="Call to grab new images and update the model accordingly", action="store_true")
args = parser.parse_args()
facedict = {}
actions = {}
emotions = ["angry", "happy", "sad", "neutral"]
df = pandas.read_excel("EmotionLinks.xlsx") #open Excel file
actions["angry"] = [x for x in df.angry.dropna()] #We need de dropna() when columns are uneven in length, which creates NaN values at missing places. The OS won't know what to do with these if we try to open them.
actions["happy"] = [x for x in df.happy.dropna()]
actions["sad"] = [x for x in df.sad.dropna()]
actions["neutral"] = [x for x in df.neutral.dropna()]
def open_stuff(): #Open the file, credit to user4815162342, on the stackoverflow link in the text above
if sys.platform == "win32":
os.startfile(filename)
else:
opener ="open" if sys.platform == "darwin" else "xdg-open"
subprocess.call([opener, filename])
def crop_face(clahe_image, face):
for (x, y, w, h) in face:
faceslice = clahe_image[y:y+h, x:x+w]
faceslice = cv2.resize(faceslice, (350, 350))
facedict["face%s" %(len(facedict)+1)] = faceslice
return faceslice
def update_model(emotions):
print("Model update mode active")
check_folders(emotions)
for i in range(0, len(emotions)):
save_face(emotions[i])
print("collected images, looking good! Now updating model...")
Update_Model.update(emotions)
print("Done!")
def check_folders(emotions):
for x in emotions:
if os.path.exists("dataset\\%s" %x):
pass
else:
os.makedirs("dataset\\%s" %x)
def save_face(emotion):
print("\n\nplease look " + emotion + ". Press enter when you're ready to have your pictures taken")
input() #Wait until enter is pressed with the raw_input() method
video_capture.open(0)
while len(facedict.keys()) < 16:
detect_face()
video_capture.release()
for x in facedict.keys():
cv2.imwrite("dataset\\%s\\%s.jpg" %(emotion, len(glob.glob("dataset\\%s\\*" %emotion))), facedict[x])
facedict.clear()
def recognize_emotion():
predictions = []
confidence = []
for x in facedict.keys():
pred, conf = fishface.predict(facedict[x])
cv2.imwrite("images\\%s.jpg" %x, facedict[x])
predictions.append(pred)
confidence.append(conf)
recognized_emotion = emotions[max(set(predictions), key=predictions.count)]
print("I think you're %s" %recognized_emotion)
actionlist = [x for x in actions[recognized_emotion]] #get list of actions/files for detected emotion
random.shuffle(actionlist) #Randomly shuffle the list
open_stuff(actionlist[0]) #Open the first entry in the list
def grab_webcamframe():
ret, frame = video_capture.read()
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))
clahe_image = clahe.apply(gray)
return clahe_image
def detect_face():
clahe_image = grab_webcamframe()
face = facecascade.detectMultiScale(clahe_image, scaleFactor=1.1, minNeighbors=15, minSize=(10, 10), flags=cv2.CASCADE_SCALE_IMAGE)
if len(face) == 1:
faceslice = crop_face(clahe_image, face)
recognize_emotion()
return faceslice
else:
print("no/multiple faces detected, passing over frame")
def run_detection():
while len(facedict) != 10:
detect_face()
recognize_emotion = recognize_emotion()
return recognize_emotion
if args.update:
update_model(emotions)
else:
video_capture.open(camnumber)
run_detection()
how can i resolve it?
Related
I am new to python. Currently I am working on a project to detect face using retinaface and opencv. I am using the retinafacewrapper from the retinaface git. Below is my code and I tried to run the code on an .mov video file and i got this error TypeError: detect_face() missing 1 required positional argument: 'img'. I need some help on this. Thank you.
from retinaface import RetinaFace
import cv2
def build_model():
from retinaface import RetinaFace
face_detector = RetinaFace.build_model()
return face_detector
def detect_face(face_detector, img , align = True):
from retinaface import RetinaFace
from retinaface.commons import postprocess
#---------------------------------
resp = []
# The BGR2RGB conversion will be done in the preprocessing step of retinaface.
# img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) #retinaface expects RGB but OpenCV read BGR
"""
face = None
img_region = [0, 0, img.shape[0], img.shape[1]] #Really?
faces = RetinaFace.extract_faces(img_rgb, model = face_detector, align = align)
if len(faces) > 0:
face = faces[0][:, :, ::-1]
return face, img_region
"""
#--------------------------
obj = RetinaFace.detect_faces(img, model = face_detector, threshold = 0.9)
if type(obj) == dict:
for key in obj:
identity = obj[key]
facial_area = identity["facial_area"]
y = facial_area[1]
h = facial_area[3] - y
x = facial_area[0]
w = facial_area[2] - x
img_region = [x, y, w, h]
#detected_face = img[int(y):int(y+h), int(x):int(x+w)] #opencv
detected_face = img[facial_area[1]: facial_area[3], facial_area[0]: facial_area[2]]
if align:
landmarks = identity["landmarks"]
left_eye = landmarks["left_eye"]
right_eye = landmarks["right_eye"]
nose = landmarks["nose"]
#mouth_right = landmarks["mouth_right"]
#mouth_left = landmarks["mouth_left"]
detected_face = postprocess.alignment_procedure(detected_face, right_eye, left_eye, nose)
resp.append((detected_face, img_region))
return resp
path = "database/images/org_3fc67bdc820dc3c1_1647514190000.mov"
cap = cv2.VideoCapture(path)
# Video
while True:
ret, img = cap.read()
img = cv2.resize(img,(640,360))
img = detect_face(img)
cv2.imshow('Face detector', img)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
Download/Clone this repo and run pose_detection_retinaface.py file. This is the complete code for using retinaface for face detection.
So i have a folder with images I am trying to make cluster of near similar images in a python dictionary with Imagehash as the key and a list of similar images as their value, how can i prevent for a image to generate a new key if it's already present in any of the other dictionary key list here is the code that I have done so far:
from PIL import Image
import imagehash
import cv2
import numpy as np
import dhash
import distance
norm_cache: dict = dict()
def _get_image(image_path: str) -> Image:
try:
img_arr = cv2.imread(image_path)
img_arr = cv2.resize(img_arr, (512, 512), interpolation=cv2.INTER_AREA)
# Convert image into 3 channels if it contains 4
if len(img_arr.shape) > 2 and img_arr.shape[2] == 4:
img_arr = cv2.cvtColor(img_arr, cv2.COLOR_BGRA2BGR)
# using W3C luminance calc to convert into gray-scale
data = np.inner(img_arr, [299, 587, 114]) / 1000.0
return Image.fromarray(np.uint8(data),"L")
except SyntaxError:
pass
def find_similar_images(userpath):
import os
global norm_cache
def is_image(filename):
f = filename.lower()
return f.endswith(".png") or f.endswith(".jpg") or \
f.endswith(".jpeg") or f.endswith(".bmp") or f.endswith(".gif")
image_filenames = [os.path.join(userpath, path) for path in os.listdir(userpath) if is_image(path)]
images = {}
buffer = []
for img in image_filenames:
if (len(buffer) == 0):
print("Original list is empty, Appending first image to buffer.")
buffer.append(img)
continue
gray1 = _get_image(img)
h1r,h1c = dhash.dhash_row_col(gray1)
hash1 = dhash.format_hex(h1r,h1c)
images[hash1] = images.get(hash1, []) + [img]
for each in buffer:
if each in norm_cache:
print(f"cached val found for {each}")
gray2 = norm_cache[each]
h2r,h2c = dhash.dhash_row_col(gray2)
hash2 = dhash.format_hex(h2r,h2c)
else:
print("No cached_val found, Computing and storing in norm_cache")
gray2 = _get_image(each)
h2r,h2c = dhash.dhash_row_col(gray2)
hash2 = dhash.format_hex(h2r,h2c)
norm_cache[each] = gray2 # Update cache...
print(f"Comparing ---> {img}:{hash1} with {each}:{hash2}")
if(distance.hamming(hash1,hash2) <= 22):
//what should i put in here
unique = 0
for k, img_list in images.items():
if(len(img_list) >= 1):
print(''.join(img_list))
unique = unique + 1
print(unique)
if __name__ == '__main__':
import sys, os
userpath = <Image folder/>
find_similar_images(userpath=userpath)
I have a code that recognizes some people faces which are in my dataset and it uses opencv. It works perfectly when a person who is in my dataset come to front of webcam and it shows his name perfectly.
But when another person who is not in my dataset, it shows same name too. It should show "Unknown". Here it is my code;
import sys
import os
import time
from datetime import datetime
import cv2
from skimage.filters import threshold_mean
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cm as cm
def Draw_Text(img, sTxt, aX=30, aY=30):
if ""==sTxt: return
cv2.putText(image, str(sTxt) ,(aX,aY), font,
fntSize,(0,255,255), fntThickness,cv2.LINE_AA)
def CvBGR_To_RGB(img):
return cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
def Load_LabelIDs(fn):
labelNames = []
with open(fn) as f:
data = f.readlines()
for i in range(len(data)):
lines = str(data[i]).split("\\n")
for s in lines:
labelNames.append(s)
return labelNames
labelNames = Load_LabelIDs('labelIDs.txt')
labelDics = {}
for s in labelNames:
strs = str(s).split("=")
labelDics[strs[0]] = strs[1].split("\n")[0]
font = cv2.FONT_HERSHEY_SIMPLEX
fntSize = 1
fntThickness = 1
fnClassfier = 'haarcascade_frontalface_default.xml'
faceCascade = cv2.CascadeClassifier(fnClassfier)
fname = "trainner.yml"
recognizer = cv2.face.LBPHFaceRecognizer_create()
recognizer.read(fname)
camera = cv2.VideoCapture(0)
while True:
return_value,image = camera.read()
imgInfo = np.asarray(image).shape
if len(imgInfo)<2: break
imgH=imgInfo[0]
imgW=imgInfo[1]
imgChannel=imgInfo[2]
gray=cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
faces=faceCascade.detectMultiScale(gray, 1.3, 5)
for(x,y,w,h) in faces:
cv2.rectangle(image,(x,y),(x+w,y+h),(0,255,0),3)
Id,conf = recognizer.predict(gray[y:y+h,x:x+w])
#print (conf)
key = "{}".format(Id)
if (key in labelDics):
Id = labelDics[key]
else:
Id="Unknown"
newimg = cv2.putText(image, str(Id), (x+2,y+h-5), cv2.FONT_HERSHEY_SIMPLEX, 1, (150,255,0),2)
try:
Draw_Text(image, "esc:exit")
cv2.imshow('image',image)
key = cv2.waitKey(5) & 0xFF
if key == 27: #esc ord('s'):
#cv2.imwrite('test.jpg',image)
break
except ValueError:
break
camera.release()
cv2.destroyAllWindows()
I tried to edit
if (key in labelDics):
Id = labelDics[key]
else:
Id="Unknown"
But after many tries, I couldn't find. Can you help me?
EDIT:
My labelIDs.txt file contains only this line 1=wicaledon. So If I add print(key, Id, labelDics) it shows always 1 1 {'1': 'wicaledon'} even known or unknown person see the camera.
I am using Chainer for written digit recognition. I have trained a model on the MNIST database. However I cannot for some reason classify a single example. My guess was that I didn't choose the right format for the example but I've tried it many ways and I still cannot resolve this issue. Apologies if this is obvious, I'm unexperienced at Python.
This is what the error looks like
Code:
import chainer
import chainer.functions as F
import chainer.links as L
import os
import sys
from chainer.training import extensions
import numpy as np
from tkinter.filedialog import askopenfilename
from PIL import Image
from chainer import serializers
from chainer.dataset import concat_examples
from chainer.backends import cuda
from chainer import Function, gradient_check, report, training, utils, Variable
from chainer import datasets, iterators, optimizers, serializers
from chainer import Link, Chain, ChainList
CONST_RESUME = ''
class Network(chainer.Chain):
def __init__(self, n_units, n_out):
super(Network, self).__init__()
with self.init_scope():
self.l1 = L.Linear(None, n_units)
self.l2 = L.Linear(None, n_units)
self.l3 = L.Linear(None, n_out)
def __call__(self, x):
h1 = F.sigmoid(self.l1(x))
h2 = F.sigmoid(self.l2(h1))
return self.l3(h2)
def query_yes_no(question, default="no"):
"""Ask a yes/no question via raw_input() and return their answer.
"question" is a string that is presented to the user.
"default" is the presumed answer if the user just hits <Enter>.
It must be "yes" (the default), "no" or None (meaning
an answer is required of the user).
The "answer" return value is True for "yes" or False for "no".
"""
valid = {"yes": True, "y": True, "ye": True,
"no": False, "n": False}
if default is None:
prompt = " [y/n] "
elif default == "yes":
prompt = " [Y/n] "
elif default == "no":
prompt = " [y/N] "
else:
raise ValueError("invalid default answer: '%s'" % default)
while True:
sys.stdout.write(question + prompt)
choice = input().lower()
if default is not None and choice == '':
return valid[default]
elif choice in valid:
return valid[choice]
else:
sys.stdout.write("Please respond with 'yes' or 'no' "
"(or 'y' or 'n').\n")
return np.argmax(y.data)
def main():
#file_list = [None]*10
#for i in range(10):
# file_list[i] = open('data{}.txt'.format(i), 'rb')
print('MNIST digit recognition.')
usr_in : str
model = L.Classifier(Network(100, 10))
chainer.backends.cuda.get_device_from_id(0).use()
model.to_gpu()
usr_in = input('Input (t) to train, (l) to load.')
while len(usr_in) != 1 and (usr_in[0] != 'l' or usr_in[0] != 't'):
print('Invalid input.')
usr_in = input()
if usr_in[0] == 't':
optimizer = chainer.optimizers.Adam()
optimizer.setup(model)
train, test = chainer.datasets.get_mnist()
train_iter = chainer.iterators.SerialIterator(train, batch_size=100, shuffle=True)
test_iter = chainer.iterators.SerialIterator(test, 100, repeat=False, shuffle=False)
updater = training.updaters.StandardUpdater(train_iter, optimizer, device=0)
trainer = training.Trainer(updater, (10, 'epoch'), out='out.txt')
trainer.extend(extensions.Evaluator(test_iter, model, device=0))
trainer.extend(extensions.dump_graph('main/loss'))
frequency = 1
trainer.extend(extensions.snapshot(), trigger=(frequency, 'epoch'))
trainer.extend(extensions.LogReport())
if extensions.PlotReport.available():
trainer.extend(extensions.PlotReport(['main/loss', 'validation/main/loss'], 'epoch', file_name='loss.png'))
trainer.extend(extensions.PlotReport(['main/accuracy', 'validation/main/accuracy'], 'epoch', file_name='accuracy.png'))
trainer.extend(extensions.PrintReport(['epoch', 'main/loss', 'validation/main/loss', 'main/accuracy', 'validation/main/accuracy', 'elapsed_time']))
trainer.extend(extensions.ProgressBar())
if CONST_RESUME:
chainer.serializers.load_npz(CONST_RESUME, trainer)
trainer.run()
ans = query_yes_no('Would you like to save this network?')
if ans:
usr_in = input('Input filename: ')
serializers.save_npz('{}.{}'.format(usr_in, 'npz'), model)
elif usr_in[0] == 'l':
filename = askopenfilename(initialdir=os.getcwd(), title='Choose a file')
serializers.load_npz(filename, model)
else:
return
while True:
ans = query_yes_no('Would you like to evaluate an image with the current network?')
if ans:
filename = askopenfilename(initialdir=os.getcwd(), title='Choose a file')
file = Image.open(filename)
bw_file = file.convert('L')
size = 28, 28
bw_file.thumbnail(size, Image.ANTIALIAS)
pix = bw_file.load()
x = np.empty([28 * 28])
for i in range(28):
for j in range(28):
x[i * 28 + j] = pix[i, j]
#gpu_id = 0
#batch = (, gpu_id)
x = (x.astype(np.float32))[None, ...]
y = model(x)
print('predicted_label:', y.argmax(axis=1)[0])
else:
return
main()
Can you show us the error message? Otherwise it is difficult to guess where causes the error.
But I guess input shape may be different.
When you use the chainer built-in function to get dataset,
train, test = chainer.datasets.get_mnist()
These dataset image shape is (minibatch, channel, height, width). but it seems you are constructing input x as the shape (minibatch, height * width =28*28=784) which is the different shape??
You can also refer some tutorial for chainer,
chainer handson
deep learning tutorial with chainer
MNIST inference code
when i run the program I need my code to :
initialize the camera
take a picture
request user to enter paths for the current image to be stored and the image to be compared to
detect edges of currently taken picture and save in database
compare current edge image to 10 or more edge images in database
output as the edge image that has highest match percentage with current edge image
basically its like an object identification program ... can someone please help me out ?
here is the code i have done so far
from itertools import izip
import numpy as np
import cv2
from matplotlib import pyplot as plt
from PIL import Image
def take_and_save_picture(im_save):
'''Take a picture and save it
Args:
im_save: filepath where the image should be stored
'''
camera_port = 0
ramp_frames = 30
cap = cv2.VideoCapture(camera_port)
def get_image():
retval, im = cap.read()
return im
for i in xrange(ramp_frames):
temp = get_image()
print("Taking image...")
# Take the actual image we want to keep
camera_capture = get_image()
#im_save_tmp = im_save + '.jpg'
im_save_tmp = im_save
# A nice feature of the imwrite method is that it will automatically choose the
# correct format based on the file extension you provide. Convenient!
cv2.imwrite(im_save_tmp, camera_capture)
# You'll want to release the camera, otherwise you won't be able to create a new
# capture object until your script exits
# del(cap)
img1 = cv2.imread(im_save_tmp, 0)
edges = cv2.Canny(img1, 100, 200)
cv2.imwrite(im_save, edges)
cv2.waitKey(0)
cv2.destroyAllWindows()
#im1 = "/Users/Me/gop.jpg"
#im2 = "/Users/Me/aarthi.jpg"
im1 = input('enter the path of database file')
im2 = input('enter the path where captured image is to be saved')
#im1="/Users/Me/home1.png"
#im2="/Users/Me/home.png"
def compute_edges_diff(im1, im2):
'''Compute edges diff between to image files.
Args:
im1: filepath to the first image
im2: filepath to the second image
Returns:
float: percentage of difference between images
'''
#for no_file1 in range(0,10):
#template = cv2.imread('numbers1/{no_file}.png'.format(no_file=no_file1),0)
i1 = Image.open(im1)
i2 = Image.open(im2)
assert i1.mode == i2.mode, "Different kinds of images."
assert i1.size == i2.size, "Different sizes."
pairs = izip(i1.getdata(), i2.getdata())
if len(i1.getbands()) == 1:
# for gray-scale jpegs
dif = sum(abs(p1-p2) for p1,p2 in pairs)
else:
dif = sum(abs(c1-c2) for p1,p2 in pairs for c1,c2 in zip(p1,p2))
ncomponents = i1.size[0] * i1.size[1] * 3
diff = (dif / 255.0 * 100) / ncomponents
return diff
def main():
#capture_img = "/Users/Me/home1.png"
capture_img = input('enter path of the file from database')
#img_to_compare = "/Users/Me/Documents/python programs/compare/img2.jpg"
take_and_save_picture(capture_img)
diff = compute_edges_diff(im1, im2)
print "Difference (percentage):", diff
if diff > 0.5:
print im1
else :
print im2
if __name__ == '__main__':
main()
#del(cap)
this code works fine .. but i am able to compare only one image ... i need to compare the current taken images with all images in my database ...
In your main function, create a list to ask for the path for the image files, wrap the compare in a for loop:
def get_images_to_compare():
images_to_compare = []
while True:
comp_img = raw_input("Path of image to compare to: ")
if len(comp_img) <= 1:
# break if someone just hits enter
break
images_to_compare.append(comp_img)
return images_to_compare
def main():
#capture_img = "/Users/Me/home1.png"
capture_img = input('enter path of the file from database')
#img_to_compare = "/Users/Me/Documents/python programs/compare/img2.jpg"
take_and_save_picture(capture_img)
#### you have some odd var names here, basic gist, add a for loop
for comp_image in get_images_to_compare():
diff = compute_edges_diff(im1, im2)
print "Difference (percentage):", diff
if diff > 0.5:
print im1
else:
print im2
as a suggestion, avoid having global scope vars intermingled between functions, it makes code hard to read (referring to you setting im1 and im2 between two fn defs.
Code for doing the multiple compares:
def main(folder_path_to_search, files_to_compare_to, source_image_path):
#capture_img = "/Users/Me/home1.png"
capture_img = input('enter path of the file from database')
#img_to_compare = "/Users/Me/Documents/python programs/compare/img2.jpg"
take_and_save_picture(capture_img)
images_to_compare = [ os.path.join(folder_path_to_search,file_path) for file_path in os.listdir(folder_path_to_search) if file_path.endswith(files_to_compare_to) ]
for comp_image in get_images_to_compare():
diff = compute_edges_diff(source_image_path, comp_image)
print "Difference (percentage):", diff, "(", source_image_path, ":", comp_image, ")"
if __name__ == '__main__':
folder_path_to_search = raw_input("Enter folder path to search")
files_to_compare_to = raw_input("enter file extention to glob ex: '.jpg'")
source_image_path = raw_input("enter full file path of source image")
main(folder_path_to_search, files_to_compare_to, source_image_path)