-
Notifications
You must be signed in to change notification settings - Fork 13.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Face_recognition and Multiprocessing troubles #314
Comments
There's a couple of problems at least with the code that have to be worked out before I could try to debug that specific issue. First, this line: self.pool.map(self.threadComparison, [buff,names,enc]) doesn't really make any sense. You are sending I'm guessing you might be trying to do something like where you send one element of each array together as three parameters to function_parameters = zip(
buff,
names,
enc
)
pool.starmap(self.threadComparison, function_parameters) ... but I could be wrong. But what you are currently doing doesn't make sense to me. Next, I'm not really sure what the self.found.append(vals[1][val]) When you call Instead, you need to return the result for one single lookup from each call to Next, you'll want to assign the result of the So that doesn't exactly answer your question, but your code right now doesn't "work" in a conceptual sense, so I'm guessing the error is the side effect of some bad global data getting passed in the If that still doesn't fix it, you need to figure out what bad value is getting passed in as part of the second parameter to the pool.map() function. Hope that helps! :) |
Thank you! I'll try re-writing my code and get back to you soon. |
Okay, I've refactored my code based on your recommendations. However, its still telling me that it cannot pickle cv2 objects for some reason? I rewrote my code to the following: def threadComparison(self, vals):
retval = None
boole = fr.compare_faces(vals[0], vals[2][0])
val = self.RecFaces(boole)
if val is not None:
retval = vals[1][val]
return retval
def searchFace(self, enc):
#Pull faces from database
values = self.fdr.select('faces', '*')
counter = 0
buff = []
names = []
findperson = None
for face in values:
buff.append(np.asarray(face[1].split(' '), dtype=float))
names.append(face[0])
#Tried debugging here, all are list, strings, etc. No cv2.VideoCapture types.
print(type(enc))
print(type(buff))
print(type(names))
if counter % 25 == 0:
searched = self.pool.map(self.threadComparison, zip(buff, names, enc))
if searched is not None:
findperson = searched
break
buff, names = []
counter += 1
findperson = self.pool.map(self.threadComparison, zip(buff, names, enc))
print(list(findperson))
if findperson is not None:
print('Name: '+ findperson)
else:
print('No entry for face...') However, I think the problem is the way I'm passing the facial encodings somehow, because when it fails to recognize my face when a picture is taken the pickling error doesn't occur. I think that the encodings from my database are fine, along with the names. Is there some other way I could pass the encodings, or do you think there could still be something wrong with the way I'm handling it? Here's the code for taking my picture and passing it to the main search function: h = HelloWorld()
#Take picture, and pass face_recognition readable frame and original frame
pframe, pics = h.Blink()
#Grab face locations, if any.
loc = fr.face_locations(pics)
#Grab face encodings, if any.
enc = fr.face_encodings(pics, loc)
#Pass facial encodings to be searched
h.searchFace(enc) |
Hello, I wanted to check back to see if you had a chance to look at this? I've been scratching my head over the problem for a while. |
`
` This code eliminates the need for a thread pool by using the face_distance function from the face_recognition library to compute the distance between the input face and all faces in the database at once. It then finds the index of the face with the smallest distance (i.e., the closest match), and returns the corresponding name if the distance is below a threshold of 0.6 (which can be adjusted based on your needs). If no match is found, it returns the string "No entry for face...". |
Description
I'm trying to parallel process the comparison of facial encodings (in anticipation for a lot of faces), however when I try to use any sort of parallel processing library (i.e. multiprocessing, concurrent.futures, etc.) I get a
TypeError: can't pickle cv2.VideoCapture objects
. I'm incredibly confused, as I don't think I'm using any cv2 objects when I compare?Here's the code snippets that generate the error:
(Sorry for the crazy code, I've been pulling my hair out over this issue)
Any help is greatly appreciated!
The text was updated successfully, but these errors were encountered: