你是否厌倦了Rickrolling?如果是这样,面部识别可能是你正在寻找的解决方案!
外国的梗“Rickrolling”到底是什么?:https://www.zhihu.com/question/295966711
大致意思就是你的好友给你发一个很吸引人的东西,然后你兴致勃勃地点进去发现被超链接跳转到了Rick Astley的歌曲《Never Gonna Give You Up》的MV界面,随着这首歌开头魔性的鼓点响起,恭喜你,你就被Rickroll了。
虽然通过音频指纹检测Rickroll是更直观的方法,但我相信使用面部识别是一种更有趣和可靠的方法。我相信它更可靠,因为
这是此操作的过于简化的流程图。
我们将使用face-recognition
包,该包使用dlib
的深度学习技术来识别人脸。这是通过在对象的脸上生成界标并将其保存,以与其他面部界标进行比较来实现的。
首先,我们需要导入我们的包。我们将使用的三个主要包是face-recognition
、opencv-python
和yt-dlp
。我选择了yt-dlp
而不是YoutubeDL
,因为我发现它下载视频的速度要快得多。
# import packages
import face_recognition # to detect Rick's face
import cv2 # to read the video
import sys
from yt_dlp import YoutubeDL # to downoad the video
import tempfile # to create a temp folder to store the downloaded video
import uuid # to create the unique folder name for the temp folder
from termcolor import colored # to add some spice to the program
现在我们需要下载用户想要查看的 Youtube 视频。在这种情况下,URL 将作为终端中的第一个参数提供。
因此,让我们获取 URL 并设置一些其他变量,例如临时文件夹位置和我们将保存视频的路径。
# get options & set variables
youtube_url = sys.argv[1] # the video URL the user wants to check
temp_folder = f'{tempfile.gettempdir()}/{uuid.uuid1()}' # the location of the temp folder
video_location = f'{temp_folder}/output.mp4' # the location the video will be saved to
然后我们可以创建一个简单的记录器来消除输出混乱和语音错误。
# create logger for video downloader
class Logger(object):
def debug(self, msg):
pass
def warning(self, msg):
pass
def error(self, msg):
print(msg)
最后,我们可以使用yt-dlp
模块下载视频。我们要确保我们制定了输出格式mp4
,因为这是我们在设置video_location
变量时定义的。
# download video
with YoutubeDL({
'outtmpl': f'{temp_folder}/output', # save to temp folder
'format': 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/mp4', # make sure it comes out as an mp4
'logger': Logger() # pipe output to logger
}) as ydl:
ydl.download([youtube_url])
print(colored('Video downloaded.', 'green'))
我们必须从 Rick Astley 的现有图片中获取面部编码。这让我们可以将它与视频中的其他面孔进行比较。
# get rick's face encoding
rick_face_encodings = [
face_recognition.face_encodings(face_recognition.load_image_file('./images/rick.jpg'))[0],
]
我们现在必须循环遍历视频中的每 10 帧以扫描面部。测试后,我决定每 10 帧检查一次,因为检查每一帧是不必要的,而且会浪费时间和系统资源。如果帧中有一张脸,我们可以获得它的编码并将其与 Rick 的脸进行比较。
让我们从捕获循环开始。
cap = cv2.VideoCapture(video_location) # create video capture
count = 0 # frame count
while True:
if count % 10 != 0: # only check every 10th frame
continue
success, frame = cap.read() # read the current frame
count += 1 # update frame count
cap.release() # release the video capture
我们现在可以在循环内搜索帧以查找任何面孔,获取它们的编码并将它们与 Rick 的进行比较。我们不会遍历帧中的所有面孔,因为我们要查找的场景只有一个人。
faces = face_recognition.face_encodings(frame) # get all the faces in the frame
if faces: # if a face is found
result = face_recognition.compare_faces(rick_face_encodings, faces[0]) # compare rick's face encoding with the one found in the frame
if result: # if the face encoding match
print(colored('Rick roll detected!', 'red'))
break
else: # skip frame if there are no faces
continue
最后但并非最不重要的一点是,如果视频捕获以没有匹配结束(将其放在循环的顶部),则没有检测到 rickrolls。
if not success:
cap.release()
print(colored('No rick rolls found!', 'green'))
break
现在,如果你运行python3 main.py 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'
它应该输出Rick roll detected!
.
做得好!你刚刚使用面部识别制作了一个 rickroll 检测器。你可以在此处找到完成的代码:https://gist.github.com/obvialex/4d153920b3c9e5a361c629456f63a5f1
联系客服