0

I'm trying to get the last document from a mongodb atlas collection but it keeps returning an empty list.

My code basically adds a user to the collection then tries to associate that user with a selected picture but when trying to get that last added user's info, it displays that error even though the user is correctly added to my atlas collection.

I even used the find_one() but it basically shows the same type of error saying that NoneType is not subscribable.

My code:


def encoding_picture(picture_path, __id):
    '''
    This function is to collect encoding face features.
    The photo is encoded and saved with associated visitor's id.
    If it's first time to dump, just dump it.
    Otherwise, load 'faces_encodings.txt', append it to registered data, then dump.
    '''
    try:
        print("encoding")
        image = face_recognition.load_image_file(picture_path)
        small_image = cv2.resize(image, (0, 0), fx=0.25, fy=0.25)
        # Encode the visitor's face
        image_face_encoding = face_recognition.face_encodings(small_image)[0]
        # Associate visitor's id and encoding data of visitor's face
        data = [[__id],image_face_encoding]
    
        # Save the associated data
        # If it's first time, just dump
        if os.path.getsize('faces_encodings.txt') == 0:
            with open('faces_encodings.txt','wb') as f:
                pickle.dump(data,f)
        else:
            # Load the registered data
            with open('faces_encodings.txt','rb') as f:
                known_faces_encoding_data = pickle.load(f)
            # Append [[visitor's id],[the encoding data of visitor's face]] to the registered data
            known_faces_encoding_data = np.vstack((known_faces_encoding_data,data))
            # Then, dump
            with open('faces_encodings.txt','wb') as f:
                pickle.dump(known_faces_encoding_data, f)       
        return "success"
        
    except EOFError:
        return "fail"

def make_photo(frame):
    save.make_directory('pics')
    visitors = list(db.find().sort('_id', -1))
    print(visitors)
    # It affects dlib speed. If frame size is small, dlib would be faster than normal size frame
    small_frame = cv2.resize(frame, (0, 0), fx=0.25, fy=0.25)
    # Detect face in the frame
    face_locations = face_recognition.face_locations(small_frame)
    
    # If not detect face
    if len(face_locations) == 0:
        print("face detection fails")
        return "fail"
    
    else:
        path = 'pics/img0.jpg'
        # Save the visitor's face as '.jpg'
        save.save_photo(path, frame)
        result = encoding_picture(path, visitors['_id'])
        
        if result == "success":
            print("Success to register")
        else:
            print("Chcek picture path")
            
        return result

The error:

photo
[]
[]
Exception in thread Stream:
Traceback (most recent call last):
  File "/usr/lib/python3.7/threading.py", line 917, in _bootstrap_inner
    self.run()
  File "/home/pi/security-recognizer/python/videostream.py", line 71, in run
    enough_image = collect.make_photo(frame)
  File "/home/pi/security-recognizer/python/collect.py", line 98, in make_photo
    result = encoding_picture(path, visitors['_id'])
TypeError: list indices must be integers or slices, not str
  • what are you trying to do with this `visitors['_id']`? – sittsering Sep 10 '21 at 10:48
  • I added the funcion that needs ```visitors['_id']``` – Hakim Kadhi Sep 10 '21 at 10:54
  • what's inside `visitors` ? list of id's? are you trying to pass all the id or specfic id? – sittsering Sep 10 '21 at 11:06
  • visitors should contain a document with the information of the last added visitor – Hakim Kadhi Sep 10 '21 at 11:14
  • list cant have string as index, must be int, i.e, `visitors[0]` or `visitors[-1]`. can you show what it displays when you print `visitors`? – sittsering Sep 10 '21 at 11:26
  • I think this is an XY problem. You don't actually want to get the greatest `_id` value, because that is subject to a race condition, and a simple clock skew in any application server would mess up all future inserts. What you really want is to get back the `_id` that was used when inserting the user. For that, see https://stackoverflow.com/questions/8783753/how-to-get-the-object-id-in-pymongo-after-an-insert – Joe Sep 11 '21 at 04:54

0 Answers0