有趣,用Python算算哪个星座富豪最多!

最近经常看到关于星座的推送,我其实不信这个,但是由于推送得太多了,总有几篇会让我好奇地点进去看看。然后想想其实用Python写一篇星座相关的文章也不错。

正好,Python计算一个人的星座特别简单,因为每个星座的日期是固定的。我们只需要四行代码就能计算:

def cal_constellation(month, day):
    constellation = (u'摩羯座',u'水瓶座',u'双鱼座',u'白羊座',u'金牛座',u'双子座',u'巨蟹座',u'狮子座',u'处女座',u'天秤座',u'天蝎座',u'射手座')
    start_day = ((1,20),(2,19),(3,21),(4,21),(5,21),(6,22),(7,23),(8,23),(9,23),(10,23),(11,23),(12,23))
    return constellation[len(list(filter(lambda y:y<=(month,day), start_day)))%12]

把出生的月份和日期传入这个函数,就能得到对应的星座了。当然,这只是非常简单的第一步,接下来让我们计算2012全球富豪榜前一百名中,哪个星座的人最多,嘻嘻,期待吗?

1.获得数据

豆瓣上有个帖子帮我们列出了相应的数据,不过是以文本的形式:https://www.douban.com/group/topic/28671832/

幸好有统一的格式,我们能用正则表达式把出生日期提取出来:

(\d+) ?月 ?(\d+) ?日

在Vscode中还能直接用模式替换,变成我们想要的元组形式:

最后发现有出生月日的只有88条,没关系,够我们用了。

2.放入代码计算

将前面获得的所有日期放入数组中,然后调用我们一开始说的星座计算函数即可,当然,需要用一个字典来计算每次星座的出现:

birth_day = [
    (1, 28), (10, 28), (8, 30), (3, 5), (3, 28), (8, 17), (11, 3), (10, 4), (7, 29), (2, 20), (11, 1),
    (5, 3), (8, 4), (10, 21), (7, 7), (10, 7), (10, 28), (4, 19), (2, 14), (6, 15), (8, 12), (4, 26),
    (8, 21), (3, 26), (1, 12), (4, 2), (9, 9), (3, 7), (2, 20), (2, 9), (3, 28), (11, 5), (4, 16), (1, 14),
    (4, 12), (6, 12), (9, 1), (5, 14), (9, 21), (8, 26), (2, 23), (5, 7), (7, 24), (3, 24), (9, 26), (1, 3),
    (2, 24), (1, 21), (7, 8), (2, 16), (8, 16), (10, 10), (9, 1), (4, 21), (5, 3), (4, 28), (8, 21), (12, 1),
    (12, 14), (10, 6), (1, 27), (4, 14), (6, 4), (10, 24), (5, 11), (8, 26), (1, 1), (6, 14), (8, 11), (5, 22),
    (5, 10), (4, 10), (5, 9), (12, 22), (12, 11), (3, 20), (3, 8), (9, 22), (12, 19), (11, 17), (9, 15), (3, 25),
    (2, 7), (4, 4), (4, 1), (6, 2), (2, 13), (11, 8)
]
def cal_constellation(month, day):
    constellation = (u'摩羯座',u'水瓶座',u'双鱼座',u'白羊座',u'金牛座',u'双子座',u'巨蟹座',u'狮子座',u'处女座',u'天秤座',u'天蝎座',u'射手座')
    start_day = ((1,20), (2,19), (3,21), (4,21), (5,21), (6,22), (7,23), (8,23), (9,23), (10,23), (11,23), (12,23))
    return constellation[len(list(filter(lambda y:y<=(month,day), start_day)))%12]

result = {}
for birth in birth_day:
    constel = cal_constellation(birth[0], birth[1])
    if constel not in result:
        result[constel] = 0
    else:
        result[constel] += 1
print(result)

结果如下:

{‘水瓶座’: 7, ‘天蝎座’: 7, ‘处女座’: 8, ‘双鱼座’: 7, ‘白羊座’: 12, ‘狮子座’: 8, ‘天秤座’: 5, ‘金牛座’: 9, ‘巨蟹座’: 1, ‘双子座’: 5, ‘摩羯座’: 3, ‘射手座’: 4}

排个序吧:

print(sorted(result.items(), key=lambda item: item[1]))

结果:

[(‘巨蟹座’, 1), (‘摩羯座’, 3), (‘射手座’, 4), (‘天秤座’, 5), (‘双子座’, 5), (‘水瓶座’, 7), (‘天蝎座’, 7), (‘双鱼座’, 7), (‘处女座’, 8), (‘狮子座’, 8), (‘金牛座’, 9), (‘白羊座’, 12)]

白羊座惊为天人达到了12位。12/88 = 14%啊,这个比例相当牛皮了。然而我的巨蟹座只有1位,枯了,难道我没有成为富豪的天赋??

不过,大家也不要伤心。我们只取了88名富豪的数据还不够多,像这样的数据分析大概要8888名富豪的出生日期才能得到一个比较靠谱的结果。

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


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

比PS还好用!Python 20行代码批量抠图

在日常的工作和生活中,我们经常会遇到需要抠图的场景,即便是只有一张图片需要抠,也会抠得我们不耐烦,倘若遇到许多张图片需要抠,这时候你的表情应该会很有趣。

Python能够成为这样的一种工具:在只有一张图片,需要细致地抠出人物的情况下,能帮你减少抠图步骤;在有多张图片需要抠的情况下,能直接帮你输出这些人物的基本轮廓,虽然不够细致,但也够用了。

DeepLabv3+ 是谷歌 DeepLab语义分割系列网络的最新作 ,这个模型可以用于人像分割,支持任意大小的图片输入。如果我们自己来实现这个模型,那可能会非常麻烦,但是幸运的是,百度的paddle hub已经帮我们实现了,我们仅需要加载模型对图像进行分割即可。

1.准备

为了实现这个实验,Python是必不可少的,如果你还没有安装Python,建议阅读我们的这篇文章哦:超详细Python安装指南

然后,我们需要安装百度的paddlepaddle, 进入他们的官方网站就有详细的指引:
https://www.paddlepaddle.org.cn/install/quick

根据你自己的情况选择这些选项,最后一个CUDA版本,由于本实验不需要训练数据,也不需要太大的计算量,所以直接选择CPU版本即可。选择完毕,下方会出现安装指引,不得不说,Paddlepaddle这些方面做的还是比较贴心的(就是名字起的不好)

要注意,如果你的Python3环境变量里的程序名称是Python,记得将语句改为Python xxx,如下进行安装:

python -m pip install paddlepaddle -i https://mirror.baidu.com/pypi/simple

还需要安装paddlehub:

pip install -i https://mirror.baidu.com/pypi/simple paddlehub

2.编写代码

整个步骤分为三步:

1.加载模型
2.指定待抠图的图片目录
3.抠图

import os
import sys
import paddlehub as hub

# 1.加载模型
humanseg = hub.Module(name="deeplabv3p_xception65_humanseg")

# 2.指定待抠图图片目录
path = './source/'
files = []
dirs = os.listdir(path)
for diretion in dirs:
    files.append(path + diretion)

# 3.抠图
results = humanseg.segmentation(data={"image": files})

for result in results:
    print(result['origin'])
    print(result['processed'])

不多不少一共20行代码。抠图完毕后会在本地文件夹下产生一个叫做humanseg_output的文件夹。这里面存放的是已经抠图成功的图片。

本文20行代码及所有图片,请在公众号后台回复:Python自动抠图 下载。

3.结果分析

不得不承认,谷歌的算法就素厉害啊。只要背景好一点,抠出来的细节都和手动抠的细节不相上下,甚至优于人工手段。

不过在背景和人的颜色不相上下的情况下,会产生一些问题,比如下面这个结果:

背后那个大叔完全被忽略掉了(求大叔的内心阴影面积)。尽管如此,这个模型是我迄今为止见过的最强抠图模型,没有之一。

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


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

Python 20行代码检测人脸是否佩戴口罩

最近,口罩成为绝对热门的话题,在疫情之下,出门不戴口罩不仅对自己不负责,对他人而言也是一种潜在的威胁。所以许多小区都有保安在门口守着,谁要是不戴口罩就吼回去(吓死我了)

尽管如此,人工检测总有可能漏掉人,而且无时无刻地盯着,保安叔叔也特别累。今天我们就来尝试用计算机自动检测人脸是否佩戴口罩的可行性,如果可行,那么根据我们以前的推送:人脸检测自动开机,就可以做一个实时摄像头,如果发现有人没戴口罩则发送警告给保安,以提高保安的工作效率。

当然,想要识别人脸是否佩戴口罩,需要做很多训练数据的收集,不过最近百度开源了他们的人脸口罩识别模型:PaddleHub 口罩检测。我们今天就来试试这个模型的效果。

1.准备

为了实现这个实验,Python是必不可少的,如果你还没有安装Python,建议阅读我们的这篇文章哦:超详细Python安装指南

然后,我们需要安装百度的paddlepaddle, 进入他们的官方网站就有详细的指引:
https://www.paddlepaddle.org.cn/install/quick

根据你自己的情况选择这些选项,最后一个CUDA版本,由于本实验不需要训练数据,也不需要太大的计算量,所以直接选择CPU版本即可。选择完毕,下方会出现安装指引,不得不说,Paddlepaddle这些方面做的还是比较贴心的(就是名字起的不好)

要注意,如果你的Python3环境变量里的程序名称是Python,记得将语句改为Python xxx,如下进行安装:

python -m pip install paddlepaddle -i https://mirror.baidu.com/pypi/simple

还需要安装paddlehub:

pip install -i https://mirror.baidu.com/pypi/simple paddlehub

2.编写代码

Paddlehub作为一个深度学习平台,用起来还是相当方便的,尤其是对于我这种(调包小王子)非研究型应用者。一共就只有四个步骤:

  • 1.引入模块和图片
  • 2.载入模型
  • 3.分类与预测
  • 4.结果展示

把我们需要测试的图片保存在该代码文件的同一目录下,命名为3.jpg:

想看这个小姐姐摘下口罩的样子

代码如下:

import paddlehub as hub
import matplotlib.pyplot as plt
import matplotlib.image as mpimg

# 1.待预测图片
test_img_path = ["./3.jpg"]

# 2.载入模型
module = hub.Module(name="pyramidbox_lite_mobile_mask")

# 3.预测
input_dict = {"image": test_img_path}
results = module.face_detection(data=input_dict)

# 4.结果展示
img = mpimg.imread("detection_result/3.jpg")
plt.figure(figsize=(10, 10))
plt.imshow(img)
plt.axis('off')
plt.show()

没错,你没看错,就是这么简单。去掉空行和注释只有12行代码,再狠一点,把matplot展示部分全部去掉,只有6行代码。

再再狠一点,把test_img_path和input_path变量以及module.face_detection语句合并,你会发现只有3行代码:

import paddlehub as hub
module = hub.Module(name="pyramidbox_lite_mobile_mask")
results = module.face_detection(data={"image": ["./3.jpg"]}) 

执行完后的分类结果在同一目录下的detection_result目录下查看即可。所以说,说20行代码是谦虚,3行代码就够了。

3.结果展示

我们测试的那张图片,结果如下:

MASK:97.64% 代表这个人戴了口罩,可信度为97.64%。
NO MASK: 97.41% 代表这个人没戴口罩,可信度为97.41%

最后面那个大叔也是MASK,但是它的可信度只有54.31%,所以很可能是误判,在我们实际应用的时候,只需要把警告阈值(比如80%)提高,即可筛去这些不可信的分类。

不过,这个模型有一个缺点就是,对于远距离的人判断并不是很精确:

离镜头最近的这个人可能是因为侧脸的原因,脸部特征不明显识别不出来。但是远处的这些戴着口罩却被识别为没戴口罩的,就是这个模型的锅了。不过,通过阈值过滤和缩短摄像头摄影距离还是可以将这个模型用于实际生活中的。

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


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

Python 强大的模式匹配工具—Pampy

在自然语言处理界,模式匹配可以说是最常用的技术。甚至可以说,将NLP技术作为真实生产力的项目都少不了模式匹配

什么是模式匹配呢?在计算机科学中,往往是检查给定的序列或字符串中是否有符合某种模式的片段。比如说:“啊,你的AK-47打得真准”,如果我们将 “啊,你的_____打得真准 ” 作为一种模式,则会将AK-47匹配出来。

实现模式匹配往往都是用正则表达式,但是如果你想识别特别复杂的模式,编写正则表达式就会变得非常非常麻烦。而Pampy这个项目能解决你不少的烦恼。

pampy使用例子

1.安装

赶紧让我们来试一下,安装Pampy前,你要确保Python和pip已经成功安装在电脑上噢,如果没有,请访问这篇文章:超详细Python安装指南

打开Cmd(开始—运行—CMD)或Terminal(command+空格输入Terminal). 输入以下命令安装Pampy:

pip install pampy

看到 Successfully installed pampy-0.3.0 则说明安装成功。

2.使用

特性1: HEAD 和 TAIL

HEAD和TAIL能代表某个模式的前面部分或后面部分。

比如将特定模式后的元素都变成元组:

from pampy import match, HEAD, TAIL, _

x = [-1, -2, -3, 0, 1, 2, 3]

print(match(x, [-1, TAIL], lambda t: [-1, tuple(t)]))
# => [-1, (-2, -3, 0, 1, 2, 3)] 

将特定模式前的元素设为集合,后面的元素设为元组:

from pampy import match, HEAD, TAIL, _

x = [-1, -2, -3, 0, 1, 2, 3]

print(match(x, [HEAD, _, _, 0, TAIL], lambda h, a, b, t: (set([h, a, b]), tuple(t))))
# => ({-3, -1, -2}, (1, 2, 3)) 

特性2:甚至能匹配字典中的键

在你不知道哪个键下有某个值的时候,这招非常好用:

from pampy import match, HEAD, TAIL, _
my_dict = {
    'global_setting': [1, 3, 3],
    'user_setting': {
        'face': ['beautiful', 'ugly'],
        'mind': ['smart', 'stupid']
    }
}
result = match(my_dict, { _: {'face': _}}, lambda key, son_value: (key, son_value))
print(result)
# => ('user_setting', ['beautiful', 'ugly']) 

特性3: 搭配正则

不仅如此,它还能搭配正则一起使用哦:

import re
from pampy import match, HEAD, TAIL, _
def what_is(pet):
    return match(pet,
        re.compile('(\w+),(\w)\w+鳕鱼$'),     lambda mygod, you: you + "像鳕鱼",
    )

print(what_is('我的天,你长得真像鳕鱼'))     # => '你像鳕鱼' 

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


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

Python 优化—算出每条语句执行时间

用Python写的程序,确实在性能上会比其他语言差一些,这是因为Python为了最大化开发效率,牺牲了一定的运行效率。开发效率和运行效率往往是鱼与熊掌不可兼得的关系。

不过,程序性能较差有很多原因,并不能全把锅甩到Python身上,我们应该首先从自己的代码上找原因,找原因最快的方法就是算出自己写的语句或函数的执行时间。这时候,很多人都会选择用以下的形式打印出语句的执行时间:

import time
a = time.time()
temp = [index*index for index in range(1000000)]
b = time.time()
print(b-a) 

这是一种比较低效的做法,如果你有上万条语句要测试,想用这个方法来找到瓶颈简直是大海捞针。幸好,得益于Python强大的社区功能,我们有很多关于效率的模块可以使用,今天要介绍的是 line_profiler , 它可以算出函数里每条语句的占用时间。

我们将使用上次电影人脸识别中的代码进行讲解:Python 识别电影中的人脸,不过要注意,这篇推送里的函数少传递了几个参数,正确参数请点击该推送下方的阅读原文进行查看哦。

1.准备

Python环境当然是必备的,如果你还没有安装Python,可以看这篇文章:超详细Python安装指南

打开cmd/terminal输入以下命令安装line_profile:

 pip install line_profiler

windows机器如果出现 Microsoft Visual C++ 14.0 is required 这样的错误,请前往微软官网,下载vs2015勾选”适用于visual C++2015的公共工具” 进行安装。

如果出现:ModuleNotFoundError: No module named 'skbuild'的情况,请输入以下命令安装scikit-build:

pip install scikit-build

实在还是安装不上的话,可以下载anaconda,输入以下命令安装:

conda install -c anaconda line_profiler

2.使用

使用方式非常简单,比如原来我们在读取人脸的代码中,主函数是这样的:

if __name__ == '__main__':
    sourcePath = 'frames/greenbooks'
    targetPath1 = 'target/test'
    read_pic_save_face(sourcePath, targetPath1, '.jpg', '.JPG', 'png', 'PNG') 

我们要测的是read_pic_save_face函数中所有语句的执行时间,只需要这样调用line_profiler:

if __name__ == '__main__':
    sourcePath = 'frames/test'
    targetPath1 = 'target/test'
    # read_pic_save_face(sourcePath, targetPath1, '.jpg')

    profile = LineProfiler(read_pic_save_face)
    profile.runcall(read_pic_save_face, sourcePath, targetPath1, '.jpg')
    profile.print_stats()

这样就可以获得该函数所有语句的执行时间报表。当然,它还有许多其他的调用方法,具体可以看line_profiler说明文档: https://github.com/rkern/line_profiler

3.阅读报告

line_profiler报告包括几个部分:
Line: 语句位于第几行
Hits: 该行被执行的次数
Time: 该语句运行的总时间
Per Hit: 该语句运行一次的平均耗时
% Time: 该语句占总时间的比重

可以看到,我们的这份代码主要是在face_cascade.detectMultiScale 耗时最久,这是opencv的分类器执行效率问题。知道了是这里的效率问题,优化就有一个目标了。

这一部分的优化,我们可以从硬件方面入手,让OpenCV在GPU上运行算法,这样做性能将远超在CPU上运行的性能,这是绝招。其次就是利用多线程计算(没试过,不确定是否有用,或许下次可以试一下)。

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


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

Python 绘制悼念的词云蜡烛

谨以此文悼念伟大的李文亮医生。

《有的人》— 臧克家
有的人活着,他已经死了。
有的人死了,他还活着。
有的人,骑在人民头上:“啊,我多伟大!”。
有的人,俯下身子给人民当牛马。
有的人,把名字刻入石头,想“不朽”。
有的人,情愿作野草,等着地下的火烧。
有的人,他活着别人就不能活。
有的人,他活着为了多数人更好地活。
骑在人民头上的,
人民把他摔垮。
给人民作牛马的,
人民永远记住他!
把名字刻入石头的,
名字比尸首烂得更早;
只要春风吹到的地方,
到处是青青的野草。
他活着别人就不能活的人,
他的下场可以看到;
他活着为了多数人更好地活着的人,
群众把他抬举得很高,很高。

无奈才学疏浅,无法用更多的语言描述我对他的敬意。但是作为程序员,我也有我的悼念方式:用代码绘制词云组成的蜡烛用以悼念。

1.准备

基于Python,绘制悼念的词云蜡烛我们需要用到的包有:

  • pip install matplot
  • pip install scipy==1.2.1
  • pip install wordcloud
  • pip install jieba
  • pip install codecs
  • pip install pandas
  • pip install numpy

打开CMD/Terminal 输入以上命令即可安装。如果你还没有安装Python,可以阅读此篇文章:超详细Python安装指南

然后需要找到生成词云的文本和相关图片,这里我用的是BBC的一篇报道,还有这张蜡烛图片:

来源:图品汇

2.编写代码

整体代码如下,我编写了非常详细的注释,大家不懂得可以根据注释的提示进行查询和学习。

# coding:utf-8
import jieba
import numpy
import codecs
import pandas
import matplotlib.pyplot as plt
from scipy.misc import imread
import matplotlib.pyplot as plt
from wordcloud import WordCloud, ImageColorGenerator
from wordcloud import WordCloud
  
def load_file_segment():
    # 加载我们自己的词典
    jieba.load_userdict("mywords.txt")
    # 读取文本文件并分词
    f = codecs.open(u"text.txt",'r',encoding='utf-8')
    # 打开文件
    content = f.read()
    # 读取文件到content中
    f.close()
    # 关闭文件
    segment=[]
    # 保存分词结果
    segs=jieba.cut(content) 
    # 对整体进行分词
    for seg in segs:
        if len(seg) > 1 and seg != '\r\n':
            # 如果说分词得到的结果非单字,且不是换行符,则加入到数组中
            segment.append(seg)
    return segment
 
def get_words_count_dict():
    segment = load_file_segment()
    # 获得分词结果
    df = pandas.DataFrame({'segment':segment})
    # 将分词数组转化为pandas数据结构
    words_count = df.groupby(by=['segment'])['segment'].agg({"计数":numpy.size})
    # 按词分组,计算每个词的个数
    words_count = words_count.reset_index().sort_values(by="计数",ascending=False)
    # reset_index是为了保留segment字段,排序,数字大的在前面
    return words_count
 
words_count = get_words_count_dict()
# 获得词语和频数

bimg = imread('candle.jpeg')
# 读取我们想要生成词云的模板图片
wordcloud = WordCloud(background_color='white', mask=bimg, font_path='simsun.ttc')
# 获得词云对象,设定词云背景颜色及其图片和字体
 
# 如果你的背景色是透明的,请用这两条语句替换上面两条 
# bimg = imread(candle.jpeg')
# wordcloud = WordCloud(background_color=None, mode='RGBA', mask=bimg, font_path='simhei.ttc')
 

words = words_count.set_index("segment").to_dict()
# 将词语和频率转为字典
wordcloud = wordcloud.fit_words(words["计数"])
# 将词语及频率映射到词云对象上
bimgColors = ImageColorGenerator(bimg)
# 生成颜色
plt.axis("off")
# 关闭坐标轴
plt.imshow(wordcloud.recolor(color_func=bimgColors))
# 绘色
plt.show()

其中candle.jpeg是位于当前文件夹的蜡烛文件,simhei.ttc是位于当前文件夹的字体文件,mywords.txt是我自己生成的词表,text.txt便是用于生成词云的文本。

以上全部文件和源代码我都已上传到公众号后台,回复:悼念蜡烛 即可下载。

3.生成蜡烛词云

我将这份源代码命名为candle.py, 通过在命令行中运行:

python candle.py

即可获得该蜡烛词云

中华民族需要永远记住李文亮医生。


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

Python 自动提取电影中所有人脸

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

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

1.准备

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

1.1 windows安装ffmpeg :

1.下载:https://www.gyan.dev/ffmpeg/builds/ffmpeg-release-essentials.zip

2.解压 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实用宝典终于复工啦(我咸鱼够了)!这些天,令人揪心的肺炎疫情一直闹得沸沸扬扬,口罩也被抢得断货,许多网友朋友们都只能开始给自己的头像戴口罩了(也挺好,为疫区省点医疗物资)

有个朋友(Prodesire)一早就预料到有这种情况,因此ta开发了一个工具,能让大家用一行语句就成功戴上口罩!

1.准备

老规矩,在开工前一定要安装好Python,如果还没安装请看这篇文章:超详细Python安装教程。安装完Python后我们就可以安装Prodesire开发的一个叫做face-mask的模块。

如果你是windows机器,请在 开始—运行 中输入cmd,执行
pip install face-mask

如果你是macOS机器,请command+空格,输入Terminal打开终端,执行
pip install face-mask

如果出现:CMake must be installed to build the following extensions: dlib 这样的错误,请先安装cmake:
pip install cmake

2.使用

同样地,打开cmd或终端,输入以下命令,就能在该图片的当前文件夹下生成一张戴着口罩的图片:

face-mask 该图片路径

比如说宽叔的这张图片:

输入命令 face-mask Downloads/2.jpg 即可生成戴口罩的图片:

类似的还有很多哦:

就不给大家一一尝试啦,总而言之,有基本脸部表情的,都可以戴的上这个口罩!

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


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

Python pandas高效数据处理之绘图

Pandas是Python中非常常用的数据处理工具,使用起来非常方便。它建立在NumPy数组结构之上,所以它的很多操作通过NumPy或者Pandas自带的扩展模块编写,这些模块用Cython编写并编译到C,并且在C上执行,因此也保证了处理速度。

今天我们就来体验一下它的强大之处。

1.创建数据

使用pandas可以很方便地进行数据创建,现在让我们创建一个5列1000行的pandas DataFrame:

mu1, sigma1 = 0, 0.1
mu2, sigma2 = 0.2, 0.2
n = 1000df = pd.DataFrame(
    {
        "a1": pd.np.random.normal(mu1, sigma1, n),
        "a2": pd.np.random.normal(mu2, sigma2, n),
        "a3": pd.np.random.randint(0, 5, n),
        "y1": pd.np.logspace(0, 1, num=n),
        "y2": pd.np.random.randint(0, 2, n),
    }
)
  • a1和a2:从正态(高斯)分布中抽取的随机样本。
  • a3:0到4中的随机整数。
  • y1:从0到1的对数刻度均匀分布。
  • y2:0到1中的随机整数。

生成如下所示的数据:

2.绘制图像

Pandas 绘图函数返回一个matplotlib的坐标轴(Axes),所以我们可以在上面自定义绘制我们所需要的内容。比如说画一条垂线和平行线。这将非常有利于我们:

1.绘制平均线

2.标记重点的点

import matplotlib.pyplot as plt
ax = df.y1.plot()
ax.axhline(6, color="red", linestyle="--")
ax.axvline(775, color="red", linestyle="--")
plt.show()

我们还可以自定义一张图上显示多少个表:

fig, ax = plt.subplots(2, 2, figsize=(14,7))
df.plot(x="index", y="y1", ax=ax[0, 0])
df.plot.scatter(x="index", y="y2", ax=ax[0, 1])
df.plot.scatter(x="index", y="a3", ax=ax[1, 0])
df.plot(x="index", y="a1", ax=ax[1, 1])
plt.show()

3.绘制直方图

Pandas能够让我们用非常简单的方式获得两个图形的形状对比:

df[["a1", "a2"]].plot(bins=30, kind="hist")
plt.show()

还能允许多图绘制:

df[["a1", "a2"]].plot(bins=30, kind="hist", subplots=True)
plt.show()

当然,生成折线图也不在画下:

df[['a1', 'a2']].plot(by=df.y2, subplots=True)
plt.show()

4.线性拟合

Pandas还能用于拟合,让我们用pandas找出一条与下图最接近的直线:

最小二乘法计算和该直线最短距离:

df['ones'] = pd.np.ones(len(df))
m, c = pd.np.linalg.lstsq(df[['index', 'ones']], df['y1'], rcond=None)[0]

根据最小二乘的结果绘制y和拟合出来的直线:

df['y'] = df['index'].apply(lambda x: x * m + c)
df[['y', 'y1']].plot()
plt.show()

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


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

Python 30秒就能学会的漂亮短代码(译3)

1.分组

对一个列表根据所需要的大小进行细分:

from math import ceil

def chunk(lst, size):
  return list(
    map(lambda x: lst[x * size:x * size + size],
      list(range(0, int(ceil(len(lst) / size))))))

效果如下:

EXAMPLES
chunk([1, 2, 3, 4, 5], 2) # [[1,2],[3,4],5]

return中,map的第二个参数是一个列表,map会将列表中的每一个元素用于调用第一个参数的 function 函数,返回包含每次 function 函数返回值的新列表。

2.数字转数组

同样是一则关于map的应用,将整形数字拆分到数组中:

def digitize(n):
  return list(map(int, str(n)))

效果如下:

EXAMPLES
digitize(123) # [1, 2, 3]

它将整形数字n转化为字符串后,还自动对该字符串进行了序列化分割,最后将元素应用到map的第一个参数中,转化为整形后返回。

3.非递归斐波那契

还记得菲波那切数列吗,前两个数的和为第三个数的值,如0、1、1、2、3、5、8、13….

如果使用递归来实现这个数列,效率非常低下,我们使用非递归的方式实现:

def fibonacci(n):
  if n <= 0:
    return [0]

  sequence = [0, 1]
  while len(sequence) <= n:
    next_value = sequence[len(sequence) - 1] + sequence[len(sequence) - 2]
    sequence.append(next_value)

  return sequence

效果如下:

EXAMPLES
fibonacci(7) # [0, 1, 1, 2, 3, 5, 8, 13]

这样看是很简单,但是思维要绕的过来哦。

4.下划线化字符串

批量统一变量名称或者字符串格式。

from re import sub

def snake(s):
  return '_'.join(
    sub('([A-Z][a-z]+)', r' \1',
    sub('([A-Z]+)', r' \1',
    s.replace('-', ' '))).split()).lower()

效果如下:

EXAMPLES
snake('camelCase') # 'camel_case'
snake('some text') # 'some_text'
snake('some-mixed_string With spaces_underscores-and-hyphens') # 'some_mixed_string_with_spaces_underscores_and_hyphens'
snake('AllThe-small Things') # "all_the_small_things"

re.sub用于替换字符串中的匹配项。这里其实是一个“套娃”用法,一开始可能不太好理解,需要慢慢理解。

第一个替换,是将s字符串中,使用’ ‘替换’-‘。

第二个替换,是针对第一个替换后的字符串,对符合'([A-Z]+)’正则表达式的字符区段(全大写的单词)用r’ \1’替换,也就是用空格区分开每一个单词。

第三个替换,是对第二个替换后的字符串,对符合'([A-Z][a-z]+)’正则表达式的字符区段(也就是首字母大写,其他字母小写的词语)用r’ \1’替换,也是将单词用空格分隔开。

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


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

有趣好用的Python教程

退出移动版
微信支付
请使用 微信 扫码支付