查看: 1811|回复: 0

给你的电脑做个简单的“人脸识别认证”

[复制链接]
  • TA的每日心情
    开心
    2019-11-4 13:48
  • 签到天数: 14 天

    连续签到: 1 天

    [LV.3]偶尔看看II

    发表于 2019-2-27 16:32:46 | 显示全部楼层 |阅读模式
    分享到:
    在我们的办公室,锁定屏幕是您需要快速开发的习惯。 因为如果你将你的计算机解锁,有人会玩得开心并改变你的壁纸或别名你sudo( linux系统管理指令,注*文章作者使用Linux系统)的东西。

    有一天,我开始思考,为什么我不能自动化呢? 在这里,我来到Face Recognition python库。 它的设置和使用非常简单。

    但首先要做的事情。 我们需要检查是否可以从python锁定屏幕以及如何操作。


    1.png
    锁定屏幕

    我在Cinnamon桌面环境中使用Linux Mint。 幸运的是在Cinnamon案例中,使用screensaver命令锁定或解锁屏幕非常容易。

    1. cinnamon-screensaver-command --activate  # to lock the screen
    2. cinnamon-screensaver-command --deactivate  # to unlock the screen
    复制代码
    从python运行终端命令并不是什么大问题:
    1. from subprocess import call
    2. LOCK_ARGS = {
    3.     True: '--activate',
    4.     False: '--deactivate',
    5. }
    6. def lock_screen(lock):
    7.     call(('cinnamon-screensaver-command', LOCK_ARGS[lock]))
    8. lock_screen(True)  lock_screen(False)
    复制代码


    设置face_recognition
    2.jpeg
    下一步是认出你可爱的脸。 我们将使用人脸识别库。 你可以在数据库中找到很多很好的例子,我相信一个对我们很有用。

    它使用OpenCV从相机捕获流。 我还决定使用构造神经网络来定位框架中的面部。 要有更好的准确性。
    1. from threading import Timer
    2. import cv2
    3. import face_recognition
    4. def load_user_encoding():
    5.     user_image = face_recognition.load_image_file(os.path.join(BASE_DIR, 'user.jpg'))
    6.     user_image_face_encoding = face_recognition.face_encodings(user_image, num_jitters=10)[0]

    7.     return user_image_face_encoding
    8. def find_user_in_frame(frame, user_encoding):
    9.     face_locations = face_recognition.face_locations(frame, model='cnn')
    10.     face_encodings = face_recognition.face_encodings(frame, face_locations, num_jitters=2)

    11.     for face_encoding in face_encodings:
    12.         matches = face_recognition.compare_faces((user_encoding, ), face_encoding, tolerance=0.9)

    13.         return any(matches)
    复制代码
    1. if __name__ == '__main__':
    2.     user_encoding = load_user_encoding()
    3.     video_capture = cv2.VideoCapture(0)  lock_timer = None
    4.     process_this_frame = True
    5.    
    6.     while True:
    7.         ret, frame = video_capture.read()
    8.         small_frame = cv2.resize(frame, (0, 0), fx=0.25, fy=0.25)
    9.         rgb_small_frame = small_frame[:, :, ::-1]

    10.         if process_this_frame:
    11.             user_found = find_user_in_frame(rgb_small_frame, user_encoding)

    12.             if user_found:
    13.                 print('user found')
    14.                 lock_screen(False)

    15.                 if lock_timer is not None:  lock_timer.cancel()
    16.                     lock_timer = None
    17.             else:
    18.                 print('user not found')

    19.                 if lock_timer is None:  lock_timer = Timer(5, lock_screen, (True,))
    20.                     lock_timer.start()

    21.         process_this_frame = not process_this_frame
    复制代码
    如你所见,我使用threading.Timer在5秒后锁定屏幕,以防用户找不到。 我建议在锁定屏幕之前稍等一下,因为有时它无法识别某些画面上的脸部。 或者你可以暂时离开。

    优化
    使用该解决方案,它有一个令人讨厌的延迟用于读取帧和坏帧。 所以我决定对其进行优化,并使用多处理将识别过程移到单独的过程中








    首先,我们需要重写我们的函数来查找用户,以便它能够被Process和Pipe 调用代替返回;
    1. def find_user_in_frame(conn, frame, user_encoding):
    2.     face_locations = face_recognition.face_locations(frame, model='cnn')
    3.     face_encodings = face_recognition.face_encodings(frame, face_locations, num_jitters=2)

    4.     found_user = False
    5.     for face_encoding in face_encodings:
    6.         matches = face_recognition.compare_faces((user_encoding, ), face_encoding, tolerance=0.9)

    7.         found_user = any(matches)
    8.         if found_user:
    9.             break

    10.     conn.send(found_user)
    复制代码

    在此之后我们需要调用该函数multiprocessing.Process在main中的循环当中

    1. if __name__ == '__main__':
    2.     user_encoding = load_user_encoding()
    3.     video_capture = cv2.VideoCapture(0)  lock_timer = None

    4.     parent_conn, child_conn = Pipe()
    5.     find_user_process = None
    6.     while True:
    7.         ret, frame = video_capture.read()

    8.         small_frame = cv2.resize(frame, (0, 0), fx=0.25, fy=0.25)

    9.         rgb_small_frame = small_frame[:, :, ::-1]

    10.         if find_user_process is None:
    11.             find_user_process = Process(target=find_user_in_frame, args=(child_conn, rgb_small_frame, user_encoding))
    12.             find_user_process.start()
    13.         elif find_user_process is not None and not find_user_process.is_alive():
    14.             user_found = parent_conn.recv()
    15.             find_user_process = None

    16.             if user_found:
    17.                 print('user found')
    18.                 lock_screen(False)
    19.                 if lock_timer is not None:
    20.                     lock_timer.cancel()
    21.                     lock_timer = None
    22.             else:
    23.                 print('user not found')
    24.                 if lock_timer is None:
    25.                     lock_timer = Timer(LOCK_TIMEOUT, lock_screen, (True,))
    26.                     lock_timer.start()
    复制代码
    现在它工作更顺畅,延迟很小。


    谢谢阅读! 希望它很有趣,你很喜欢它。

    源代码可以在github上找到:https://github.com/Ignisor/face-screenlock
    英文原文:Simple “Face ID” for your PC



    翻译:callofduty890
    来源:AI研习社




    回复

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    手机版|小黑屋|与非网

    GMT+8, 2024-4-24 00:54 , Processed in 0.130338 second(s), 19 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.