Python 自动提取电影中所有人脸_Python实用宝典的博客-程序员宅基地

技术标签: Python 教程  算法  python  机器学习  opencv  

最近由于论文写作需要涉及到人脸的提取操作,结合以前做过的人脸识别项目:Python自动识别人脸开机 和 ffmpeg 的影片逐帧提取功能,实现了自动提取电影中所有人脸的操作。

我们知道,机器学习、深度学习算法需要数据量到达一定量级之后效果才比较好。所以我们今天的这个功能主要可以用于一些人脸识别算法的训练集提取。

1.准备

我们使用ffmpeg提取视频中的图片,它的安装方法如下:

1.1 windows安装ffmpeg :

1.http://ffmpeg.zeranoe.com/builds/,点击 download build 按钮

2.解压 ffmpeg-20170418-6108805-win64-static.zip 文件到指定目录;
将解压后的文件目录中 bin 目录(包含 ffmpeg.exe )添加进 path 环境变量(此电脑->右键->属性->高级系统设置->环境变量->编辑Path用户变量->新建-> 输入 bin目录的完整路径)中;

3.进入 cmd,输入 ffmpeg -version,可验证当前系统是否识别 ffmpeg,以及查看 ffmpeg 的版本;如果可以,则说明安装成功。

1.1 macOS安装ffmpeg:

1.Command+空格 搜索终端(Terminal)

2.输入以下命令安装homebrew:
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

3.输入以下命令安装ffmpeg:
brew install ffmpeg

1.2 安装用于提取人脸的OpenCV模块

如果你已经安装好了Python(如果没有的话请看这篇文章:超详细Python安装指南),打开CMD/终端(Termianl)输入以下命令即可安装:

pip install opencv-python

接下来,让我们先学会从影片中逐帧提取图片。

2.提取图片

FFmpeg从视频中提取图片非常简单,而且功能很强大,能选择多少秒提取一帧,或者每秒提取X帧。

如果我们只需要1秒1帧,在CMD或Terminal中输入以下命令即可:

ffmpeg -i 视频路径.mp4 -r 1 image-%5d.jpg

其中:

-r 1 代表每秒取1帧
image-%5d.jpg是指命名格式为 image-00001.jpg

如图所示:

这样就能获得视频里的帧图:

3.从图片中提取人脸

如果你阅读过我以前的这篇文章: Python自动识别人脸开机 就会知道其实用OpenCV提取人脸是一件非常简单的事情。

它只需要你将图片使用**cv2.imread函数读取进来,然后再使用一个训练好的分类器文件就能获得人脸的位置**。如下代码所示:

 def read_pic_save_face(sourcePath, targetPath, *suffix):
    """
    提取图片中的人脸

    1.对list中图片逐一进行检查,找出其中的人脸然后写到目标文件夹下
    2.haarcascade_frontalface_alt.xml 为库训练好的分类器文件
    3.下载opencv,安装目录中可找到该xml文件
    或关注 Python实用宝典 公众号后台回复 电影提取人脸 获取文件和源代码

    @param sourcePath: 图片源目录
    @param targetPath: 人脸目标目录
    @param *suffix: 图片后缀
    """

    ImagePaths=get_all_path(sourcePath, *suffix)
    count = 0
    face_cascade = cv2.CascadeClassifier('./haarcascade_frontalface_alt.xml')
    # 分类器
    for imagePath in ImagePaths:
        # 遍历所有图片
        img = cv2.imread(imagePath)
        if type(img) != str:
            faces = face_cascade.detectMultiScale(img, 1.1, 5)
            if len(faces):
                write_face(targetPath, faces)
    print ('Find '+str(count-1)+' faces to Destination '+targetPath)

获得了人脸的位置后,我们只需要将这部分位置写入到新的图片中即可:

 def write_face(imagePath, targetPath, faces, count, img):
    """
    写入脸部图片到目标目录
    @param imagePath: 图片目录
    @param targetPath: 目标目录
    @param faces: 脸部数据
    @param count: 数目
    @param img: 图片数据
    """

    for (x, y, w, h) in faces:
        # 设置人脸宽度大于16像素,去除较小的人脸
        if w>=16 and h>=16:
            # 以时间戳和读取的排序作为文件名称
            listStr = [str(int(time.time())), str(count)]
            fileName = ''.join(listStr)
            # 扩大图片,可根据坐标调整
            X = int(x)
            W = min(int(x + w),img.shape[1])
            Y = int(y)
            H = min(int(y + h),img.shape[0])
            f = cv2.resize(img[Y:H, X:W], (W-X,H-Y))
            cv2.imwrite(targetPath+os.sep+'%s.jpg' % fileName, f)
            count += 1
            print (imagePath + "have face") 

怎么样,是不是特别简单?完整代码如下:

#-*-coding:utf8-*-
import os
import cv2
import time

def get_all_path(dirpath, *suffix):
    """
    获得所有路径

    @param dirpath: 目录
    @param *suffix: 后缀
    """

    PathArray = []
    for r, ds, fs in os.walk(dirpath):
        for fn in fs:
            if os.path.splitext(fn)[1] in suffix:
                fname = os.path.join(r, fn)
                PathArray.append(fname)
    return PathArray

def write_face(imagePath, targetPath, faces, count, img):
    """
    写入脸部图片到目标目录
    @param imagePath: 图片目录
    @param targetPath: 目标目录
    @param faces: 脸部数据
    @param count: 数目
    @param img: 图片数据
    """

    for (x, y, w, h) in faces:
        # 设置人脸宽度大于16像素,去除较小的人脸
        if w>=16 and h>=16:
            # 以时间戳和读取的排序作为文件名称
            listStr = [str(int(time.time())), str(count)]
            fileName = ''.join(listStr)
            # 扩大图片,可根据坐标调整
            X = int(x)
            W = min(int(x + w),img.shape[1])
            Y = int(y)
            H = min(int(y + h),img.shape[0])
            f = cv2.resize(img[Y:H, X:W], (W-X,H-Y))
            cv2.imwrite(targetPath+os.sep+'%s.jpg' % fileName, f)
            count += 1
            print (imagePath + "have face")

def read_pic_save_face(sourcePath, targetPath, *suffix):
    """
    提取图片中的人脸

    1.对list中图片逐一进行检查,找出其中的人脸然后写到目标文件夹下
    2.haarcascade_frontalface_alt.xml 为库训练好的分类器文件
    3.下载opencv,安装目录中可找到该xml文件
    或关注 Python实用宝典 公众号后台回复 电影提取人脸 获取文件和源代码

    @param sourcePath: 图片源目录
    @param targetPath: 人脸目标目录
    @param *suffix: 图片后缀
    """

    ImagePaths=get_all_path(sourcePath, *suffix)
    count = 0
    face_cascade = cv2.CascadeClassifier('./haarcascade_frontalface_alt.xml')
    # 分类器
    for imagePath in ImagePaths:
        # 遍历所有图片
        img = cv2.imread(imagePath)
        if type(img) != str:
            faces = face_cascade.detectMultiScale(img, 1.1, 5)
            if len(faces):
                write_face(imagePath, targetPath, faces, count, img)
    print ('Find '+str(count-1)+' faces to Destination '+targetPath)
 
if __name__ == '__main__':
    sourcePath = 'frames/greenbooks'
    targetPath1 = 'target/greenbooks'
    read_pic_save_face(sourcePath, targetPath1, '.jpg', '.JPG', 'png', 'PNG')

最后让我们来看看效果:

大部分提取都是正确的,当然不排除有些例外出现,这时候你就要手动去除了,比如说这个(汗):

您这也能分类成人脸???嗯???(不过仔细看还真挺像的)

我们的文章到此就结束啦,如果你希望我们今天的Python 教程,请持续关注我们,如果对你有帮助,麻烦在下面点一个赞/在看哦,有任何问题都可以在下方留言区留言,我们都会耐心解答的!


​Python实用宝典 (pythondict.com)
不只是一个宝典
欢迎关注公众号:Python实用宝典

原文来自Python实用宝典:Python 自动提取电影中所有人脸

Python实用宝典

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/u010751000/article/details/106746746

智能推荐

ubuntu的键盘F1~F12没有反应/出现问题(被系统强制为功能键了)_Ac君的博客-程序员宅基地

Linux/Ubuntu系统的F1~F5、F6~F12按键没反应,出问题了,被识别为unknow键(功能建),修复ubuntu外接键盘的F1~F12按键问题,ubuntu系统按F5键触发系统功能

php与ffmpeg和mencoder处理视频_php mencoder.exe_bingcool空间的博客-程序员宅基地

http://www.dayanmei.com/blog.php/ID_959.htm在经历了一个自己摸索的过程和看过一个网络上的一个收费视频网站的解决方案后,谈一下我自己的在windows下的视频解决方案,如有不对之处请指正,本文仅对视频网站解决方案做简单描述,本站原创,转载请注明出处.刚 到公司后接到的第一个项目竟然是视频网站,对于如何调用其他程序都不知道的我来说,难道可想而知,不过还

来自知乎-Web 建站技术中,HTML、HTML5、XHTML、CSS、SQL、JavaScript、PHP、ASP.NET、Web Services 是什么?_驭乐MJ的博客-程序员宅基地

一个学期前我也和楼主差不多不知道这些都是啥,一个学期之后差不多都弄懂了,来讲讲自己的理解吧 > 首先要知道网站访问大概是什么个过程:假设你在浏览器地址栏输入这个问题的地址http://www.zhihu.com/question/22689579访问过程和下图差不多,浏览器和服务器交流,服务器和数据库交流(有时候数据库就在服务器那台机子上)HTML 与 C

Linux统计文件行数_rainbow702的博客-程序员宅基地

语法:wc [选项] 文件…说明:该命令统计给定文件中的字节数、字数、行数。如果没有给出文件名,则从标准输入读取。wc同时也给出所有指定文件的总统计数。字是由空格字符区分开的最大字符串。该命令各选项含义如下:- c 统计字节数- l 统计行数- w 统计字数这些选项可以组合使用。 输出列的顺序和数目不受选项的顺序和数目的影响。 总是按下述顺序显示并且每项最多一列: 行数、字数、字节

The transparent shader receiving the shadow._LuckyJoey的博客-程序员宅基地

Shader "FX/Matte Shadow" { Properties {    _Color ("Main Color", Color) = (1,1,1,1)    _MainTex ("Base (RGB) Trans (A)", 2D) = "white" {}    _Cutoff ("Alpha cutoff", Range(0,1)) = 0.

随便推点

关于ADMM的研究_舴艋的博客-程序员宅基地

最近在研究正则化框架如何应用在大数据平台上。找到了《Distributed Optimization and Statistical Learning via the Alternating Direction Method of Multipliers》这篇文章,感觉很适合现在的研究。下面转载的一篇博客,写的很细致,很有用。业界一直在谈论大数据,对于统计而言,大数据其实意味着要不是样本量增加...

汇编看if else_洋洋dev的博客-程序员宅基地

我们先来思考几个问题1、 我们经常使用到的if else 流程语句代码 是怎么被机器读懂的?2、 它背后的本质是什么?3、从汇编的角度去看 if else 又是什么呢 ?4、不同的汇编对if else 的解释 是相同的吗?本文分别从ARM和AT&T汇编去分析一段oc代码源码- (void)cycle { int a = 6; int b = 10; if (a == b) { NSLog(@"相等"); }else {

Python中import导入上一级目录模块及循环import问题的解决_mjiansun的博客-程序员宅基地

import上一级目录的模块python中,import module会去sys.path搜索,sys.path是个列表,并且我们可以动态修改。要import某个目录的module,我们sys.path.insert(0,somedir)来加入搜索路径,就可以import了。既然这样,要import上一级目录的module,可以sys.path.insert(0,parentdir)。不过...

Unity 工具类 之 AR/VR Gaze 凝视/按键/鼠标 点击 UI/游戏物体 的交互方式实现_unity vr按钮_仙魁XAN的博客-程序员宅基地

Unity 工具类 之 AR/VR Gaze 凝视/按键/鼠标 点击 UI/游戏物体 的交互方式实现目录Unity 工具类 之 AR/VR Gaze 凝视/按键/鼠标 点击 UI/游戏物体 的交互方式实现一、简单介绍二、实现原理三、注意事项四、效果预览五、实现步骤六、关键代码七、参考工程一、简单介绍在Unity 的VR/AR开发中,一些工具类的整理,方便后期使用。在AR/VR 中,一般都会用到凝视交互,本节介绍,在 Unity ...

python利用geometry函数和shp文件进行数据的精确筛选_野生的气象小流星的博客-程序员宅基地

python利用geometry函数和shp文件进行数据的精确筛选本帖主要介绍的是利用shp文件和geometry函数实现数据的精确筛选,意思就是加入作者只需要一个省的数据,手上确是全国或者全球的数据,怎么去清洗数据,只得到符合省界经纬度圈内的数据。先上结果图(以雷电数据为例)图中是全国及周边的FY4闪电数据,但是作者只需要湖南省的,就需要数据清洗说明:1.这里只介绍重点部分,对于画图将不再介绍,源代码里面可以看懂2.geometry函数其实就在shapely库中3.该方法经作者实测应该

LoadRunner错误笔记_loadrunner26628_马超i的博客-程序员宅基地

记录一些会碰到及已经碰到的错误答案不是绝对的,因为可以引起的方面有很多。====================1.LR安装的话建议安装默认目录,还建议安装112.Loadrunner11支持IE9以上3.录制唤起浏览器时间长答:可能是不兼容4.WIN7安装LR12后,拨号连接报错797答:系统里卸载NV for HPE LG and VuGen v9.13.0.1123,LR运行...

推荐文章

热门文章

相关标签