2

I am working on a Facial Recognition system using InsightFace. I want to store my labels and faces into a numpy array using np.array() and applying some filtering on them to ensure that each label has embeddings.

This is my filtering function

def filter_empty_embs(img_set: List, img_labels: List[str]):
    # filtering where insightface could not generate an embedding
    good_idx = [i for i,x in enumerate(img_set) if x]
    
    if len(good_idx) == len(img_set):
        clean_embs = [e[0].embedding for e in img_set]
        clean_labels = img_labels
        
    else:
        # filtering eval set and labels based on good idx
        clean_labels = np.array(img_labels)[good_idx]
        clean_set = np.array(img_set, dtype=object)[good_idx]
        
        # generating embs for good idx
        clean_embs = [e[0].embedding for e in clean_set]
    
    return clean_embs, clean_labels

This is the function where I extract embeddings:

# sorting files
files = os.listdir(YALE_DIR)
files.sort()
eval_set = list()
eval_labels = list()
probe_set = list()
probe_labels = list()
IMAGES_PER_IDENTITY = 11
for i in tqdm(range(1, len(files), IMAGES_PER_IDENTITY), unit_divisor=True): # ignore the README.txt file at files[0]
    # print(i)
    probe, eval = create_probe_eval_set(files[i:i+IMAGES_PER_IDENTITY])
    
    # store eval embs and labels
    eval_set_t, eval_labels_t = generate_embs(eval)
    eval_set.extend(eval_set_t)
    eval_labels.extend(eval_labels_t)
    
    # store probe embs and labels
    probe_set_t, probe_labels_t = generate_embs(probe)
    probe_set.extend(probe_set_t)
    probe_labels.extend(probe_labels_t)

Lastly, here where I call the functions and everything should work:

evaluation_embs, evaluation_labels = filter_empty_embs(eval_set, eval_labels)
probe_embs, probe_labels = filter_empty_embs(probe_set, probe_labels)

However, I am facing the following error in the filter_empty_embs function

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
~\AppData\Local\Temp/ipykernel_488/1310330242.py in <module>
----> 1 evaluation_embs, evaluation_labels = filter_empty_embs(eval_set, eval_labels)
      2 probe_embs, probe_labels = filter_empty_embs(probe_set, probe_labels)

~\AppData\Local\Temp/ipykernel_488/117740786.py in filter_empty_embs(img_set, img_labels)
     10         # filtering eval set and labels based on good idx
     11         clean_labels = np.array(img_labels)[good_idx]
---> 12         clean_set = np.array(img_set, dtype=object)[good_idx]
     13 
     14         # generating embs for good idx

ValueError: invalid __array_struct__

Apparently the problem is in the img_set variable that I am using. which is a list of the type object that will contain images but I don't know what exactly the problem is and how to fix it.

Numpy version: 1.21.2 and I cant go back with it due to other decencies.

Thanks in advance !!

5
  • does this work np.array(img_set) Commented Oct 18, 2021 at 16:09
  • No, same thing. That what is making me think that the problem in the img_set Commented Oct 18, 2021 at 18:32
  • Actually, I found out that this method works find with numpy 1.19 which means it is deprecated. So, is there a new way with numpy 1.21.2 ? Commented Oct 20, 2021 at 7:59
  • What is good_idx, a scalar or list/array? You say img_set is a list of some sort of image objects. What are those objects? Looks like it's trying to make an object dtype array of those images, specifically for the purpose of applying the good_idx indexing. Commented Oct 20, 2021 at 8:06
  • the good_idx is a list of indices. img_set are the images. So, basically I am retrieving the indices were the embeddings were generated and mapping them with the corresponding images. Commented Oct 24, 2021 at 7:21

1 Answer 1

2

Your problem is in the embedding the list returned by insightface contain a lot of thing which are not valid for Numpy.

to get only the embedding you have to use :

emb_res = app.get(rgb_arr)
res = emb_res[0].embedding

You don't need the filtering function at all. just replace the generate_embs function with this one:

def generate_embs(img_fpaths: List[str]):
  embs_set = list()
  embs_label = list()

  for img_fpath in img_fpaths:  
    print('tratamento: ',img_fpath)                    
    # read grayscale img
    img = Image.open(os.path.join(YALE_DIR, img_fpath)) 
    img_arr = np.asarray(img)  
    
    # convert grayscale to rgb
    im = Image.fromarray((img_arr * 255).astype(np.uint8))
    rgb_arr = np.asarray(im.convert('RGB'))       
   
    # generate Insightface embedding
    emb_res = app.get(rgb_arr)
    try:
     res = emb_res[0].embedding
     # append emb to the eval set
     embs_set.append(res)          
     # append label to eval_label set
     embs_label.append(img_fpath.split("_")[0])
    except:
     print('no embedding found for this image')
  return embs_set, embs_label

Then replace these 2 lines:

evaluation_embs, evaluation_labels = filter_empty_embs(eval_set, eval_labels)
probe_embs, probe_labels = filter_empty_embs(probe_set, probe_labels)

with

evaluation_embs, evaluation_labels = eval_set, eval_labels
probe_embs, probe_labels = probe_set, probe_labels

With a try you can check if the embedding is created or not directly no need to filter it after to create the sets

Then it should work with numpy 1.20.0

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.