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.
Related
So i am making a face recognition program using python which recognises and edits and writes the name of the person in an excel spreadsheet and continues if the face does not match, i suddenly encountered this issue without even making any major change in the code, i just want it to work normally and not throw any error. help?
from configparser import Interpolation
import face_recognition
import cv2
import numpy as np
import csv
import os
from datetime import datetime
video_capture = cv2.VideoCapture(0)
tata_image = face_recognition.load_image_file("faces/index4.jpg")
tata_encoding = face_recognition.face_encodings(tata_image)[0]
einstein_image = face_recognition.load_image_file("faces/index2.jpg")
einstein_encoding = face_recognition.face_encodings(einstein_image)[0]
tesla_image = face_recognition.load_image_file("faces/index.jpg")
tesla_encoding = face_recognition.face_encodings(tesla_image)[0]
eefa_image = face_recognition.load_image_file("faces/eefa.jpg")
eefa_encoding = face_recognition.face_encodings(eefa_image)[0]
teresa_image = face_recognition.load_image_file("faces/index3.jpg")
teresa_encoding = face_recognition.face_encodings(teresa_image)[0]
known_face_encoding = [
tesla_encoding,
tata_encoding,
teresa_encoding,
eefa_encoding,
einstein_encoding
]
known_faces_names = [
"Nikola Tesla",
"Ratan Tata",
"Mother Teresa",
"Eefa Khadeeja Abidi",
"Albert Einstein"
]
students = known_faces_names.copy()
face_location = []
face_encodings = []
face_names = []
s=True
now = datetime.now()
date = now.strftime("%Y-%m-%d")
f = open(date+'-attendance.csv','w+', newline='')
lnwriter = csv.writer(f)
while True:
_,frame = video_capture.read()
small_frame = cv2.resize(frame,(0,0),fx=0.25,fy=0.25)
rgb_small_frame = small_frame[:,:,::-1]
if s:
face_locations = face_recognition.face_locations(rgb_small_frame)
face_encodings = face_recognition.face_encodings(rgb_small_frame,face_locations)
face_names = []
for face_encoding in face_encodings:
matches = face_recognition.compare_faces(known_face_encoding,face_encoding)
name = ""
face_distance = face_recognition.face_distance(known_face_encoding,face_encoding)
best_match_index = np.argmin(face_distance)
if matches[best_match_index]:
name = known_faces_names[best_match_index]
face_names.append(name)
if name in known_faces_names and name in students:
students.remove(name)
print(students)
time = now.strftime("%H-%M-%S")
lnwriter.writerow([name,time])
cv2.imshow("attendance system",frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
video_capture.release()
cv2.destroyAllWindows()
f.close()
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)
hello o try to combine detect.multiscale code wit calc.hist code. i try to run this program but i can't access 'w' in for in loop.??
import cv2
import numpy as np
from matplotlib import pyplot as plt
import time
import sys
import serial
#execfile("/home/arizal/Documents/Sorting Jeruk/motor1.py")
#ser = serial.Serial('/dev/ttyACM0', 9600)
#Cascade jeruk
jeruk_cascade = cv2.CascadeClassifier('cascade.xml')
camera = cv2.VideoCapture(1)
base1 = cv2.imread('base11.jpg')
base2 = cv2.imread('base22.jpg')
base3 = cv2.imread('base33.jpg')
#Set hist parameters
hist_height = 64
hist_width = 256
nbins = 32
bin_width = hist_width/nbins
hrange = [0,180]
srange = [0,256]
ranges = hrange+srange # ranges = [0,180,0,256]
#Create an empty image for the histogram
e = np.zeros((hist_height,hist_width))
#print ("h : ",h)
#print type(h)
#x=1
this is for detect.multiscale loop
while 1:
grabbed, img = camera.read()
cam = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
if not grabbed:
"Camera could not be started."
break
# add this
# image, reject levels level weights.
jeruks = jeruk_cascade.detectMultiScale(cam, 1.03, 5)
this for cascade for in loop, for give rectangle mark on the object
# add this
for (x,y,w,h) in jeruks:
cv2.rectangle(img,(x,y),(x+w,y+h),(17,126,234),2)
font = cv2.FONT_HERSHEY_SIMPLEX
cv2.putText(img,'Jeruk',(x+w,y+h), font, 1, (17,126,234), 2, cv2.LINE_AA) #---write the text
roi_gray = cam[y:y+h, x:x+w]
roi_color = img[y:y+h, x:x+w]
and calc the histogram when the object detected
if w > 250 :
print ('w', w)
histcam = cv2.calcHist([cam], [0], None, [nbins], [0,256])
cv2.normalize(histcam,histcam, hist_height, cv2.NORM_MINMAX)
hist=np.int32(np.around(histcam))
but i got this error :
Traceback (most recent call last):
File "/home/arizal/Documents/Sorting Jeruk/doalcoba.py", line 65, in <module>
if w > 250 :
NameError: name 'w' is not defined
anyone can help me ?
I think the problem that your code has is of indentation. In the code -
for (x,y,w,h) in jeruks:
....
And
if w > 250 :
....
Are on same level of indentation. (x,y,w,h) are only available for the for loop, not outside of it. Fix you indentation -
for (x,y,w,h) in jeruks:
....
if w > 250 :
print ('w', w)
Let me know if that works
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?