写真美女套图:爬虫+美女脸部识别+DCGAN脸部自动生成
所有具体的内容信息,代码解析,步骤分析请到我的博客观看具体教程。
http://blog.csdn.net/sileixinhua/article/details/78816683
谢谢。
所有代码请到我的github上下载,请star一下,谢谢大家了。
https://github.com/sileixinhua/BeautifulGirls
本文主要是以爬虫爬取下来的图片为数据,做一个只针对美女脸部识别,和一个DCGAN合成美女脸的模型。
第一部分:写爬虫主要看需求来决定工具的使用,python无非是众多语言中比较成熟的一个,如果要分析json,要分布式,就用scrapy,如果功能要求简单的就用BeautifulSoup+requests就可以了。requests用于和服务器的交互,BeautifulSoup解析HTML页面格式数据,并提取想要的信息。
第二部分:现在脸部,物体的识别多是用tensorflow等机器学习框架来做,但是其实在很早的时候用opencv就可以做了,现在opencv也有DNN等功能,这里美女脸部识别主要是用了opencv的cascades识别功能,这部分基本不要写什么代码,但是过程会比较繁琐。
第三部分:有人说近十年深度学习的重要发现就是GAN,第三部分就是用了GAN+CNN的变种DCGAN,GAN主要是用来根据现有的数据发现其中的模式生成数据,图像,语音等,主要组成部分为生成器和判别器,生成器是原始数据加噪声来合成新的数据,判别器主要是根据原始数据判别生成数据的相似度,准确度。
windows10
Python3.5
https://www.python.org/downloads/
BeautifulSoup
https://www.crummy.com/software/BeautifulSoup/bs4/doc/index.zh.html
Requests
http://docs.python-requests.org/en/master/#
可能需要的python包安装(Python3环境)
pip3 install BeautifulSoup
pip3 install requests
pip3 install lxml
这里还是推荐使用Python3,但是用Python2的同学,把上述命令的“pip3”改成“pip”就可以了。
目标网址:http://www.xingmeng365.com/
爬虫需要抓取的页面:
爬虫需要抓取的页面地址:
爬虫获取HTML页面信息的地址:
SpiderDownloadImages.py
# 2017年11月10日 19点24分
# 作者:橘子派_司磊
# 爬虫:抓美女套图
# 目标网址:http://www.xingmeng365.com/
from bs4 import BeautifulSoup
import requests
import os
import urllib.request
# 在mian.py当前位置创建图片收集的文件夹Photos
if not os.path.exists('Photos'):
os.makedirs('Photos')
num = 67
image_list = []
id = 7
while(id <= 559):
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:23.0) Gecko/20100101 Firefox/23.0'}
url = requests.get('http://www.xingmeng365.com/articles.asp?id='+str(id), headers=headers)
# 此处用 “,str(id)” 的话,逗号打印出来会变成 “id=&2”
print("当前爬取的网址为:"+url.url)
html_doc = url.text
# 此处用url不带".text"的话报错,Python: object of type 'Response' has no len()
# 错误解决
# https://stackoverflow.com/questions/36709165/python-object-of-type-response-has-no-len
soup = BeautifulSoup(html_doc,"lxml")
for link in soup.find_all('img'):
if "/upload" in link.get('src'):
# id=7以后,"../../"改为"/upload"
image_url = link.get('src')
# 获得的图片地址有错,需要改成
# http://www.xingmeng365.com/upload/image/20170811/20170811203590079007.jpg
# 即把 “../../” 改为 “http://www.xingmeng365.com/”
# id=7 以后为/upload/image/20170811/20170811210596789678.jpg
# 即http://www.xingmeng365.com/upload/image/20170811/20170811210545754575.jpg
image_url = "http://www.xingmeng365.com/" + image_url[1:]
# id=7以后,[6:]改为[1:]
print("开始下载第"+str(num+1)+"张图片:"+image_url)
file = open('Photos/'+str(num)+'.jpg',"wb")
req = urllib.request.Request(url=image_url, headers=headers)
try:
image = urllib.request.urlopen(req, timeout=10)
pic = image.read()
except Exception as e:
print("第"+str(num+1)+"张图片访问超时,下载失败:"+image_url)
continue
# 遇到错误,网站反爬虫
# urllib.error.HTTPError: HTTP Error 403: Forbidden
# 原因是这里urllib.request方法还需要加入“, headers=headers”
# 头文件来欺骗,以为我们是客户端访问
file.write(pic)
print("第"+str(num+1)+"张图片下载成功")
file.close()
num = num + 1
id = id + 1
视网络情况而定,一共花费7293.5秒,爬取15684张图。
这里文件夹下所有的图像数据就保存在Photos文件夹里,一共有15684张图。
现在大家都在用TensorFlow等神经网络框架做识别,过程繁琐,有些功能可以直接用OpenCV做到,而且封装好的开发工具包可以节省很多时间,效果也还可以。
这里解释一下OpenCV自带的cascades识别,官网信息地址。
https://docs.opencv.org/3.0.0/d7/d8b/tutorial_py_face_detection.html
首先安装OpenCV后,源码目录下\opencv\sources\data\haarcascades,就有很多自带的人脸识别.xml 文件,这个文件里包含的就是要识别出物体的信息。
Python3 + OpenCV
OpenCV的window安装直接官网https://opencv.org/下载源码,把bin路径添加到系如变量即可
在Ubuntu上的安装比较繁琐,我找到的最简单的方式是:
https://www.youtube.com/watch?v=2Pboq2LFoaI
http://www.daslhub.org/unlv/wiki/doku.php?id=opencv_install_ubuntu
整个过程安装比较耗时,大概一刻钟左右。
在Python中安装OpenCV开发包需要如下命令:
pip3 install opencv-python
这里如果是Python2就把“pip3”改成“pip”即可。
本实验步骤有点繁琐,请仔细查阅,经过第一部分,文件下已经有Photos文件夹,这里是所有美女写真套图的数据集。
- 我们需要用OpenCV自带的脸部识别把所有美女套图的脸部截取下来,存放进Faces文件夹里。
- 然后用OpenCV自己的方法创建我们自己的cascades的识别器,用来识别美女的脸部,丑的不识别,这一步主要就是生成.xml文件,文件里包含的就是美女脸部的信息。Negative文件夹里是背景,即负面Negative数据,用来和真实的脸部数据做对比,让训练器知道哪些是美女脸,哪些不是。结果会生成进data文件夹里,结果是一个.xml类型的文件,具体步骤如下代码分析所示。
- 用我们自己生成的.xml文件来识别美女的脸部,丑的不识别。
这一部分的实验主要是OpenCV的脸部识别器我用错了,所以从截取的脸部信息就有噪声数据,即不是脸部的图也被截取下来混进去了,所以效果不是很好,如果要提高效果,可以用别的脸部识别分类器,或者手动删除非脸部图片,并加大Negative文件夹里的图片即可。
首先是上面实验分析的第一步,截图美女脸部图像
TakeImgFace.py
import cv2
import sys
import os.path
from glob import glob
# C:\Code\BeautifulGirls\Faces
# C:\Code\BeautifulGirls\Photos
# 一共有15683张写真美图
# 本文件是用来从Photos写真美图文件夹中,用opencv自带的人脸识cascade别出脸部并截图保存到Faces文件夹中
# 在opencv的自带人脸检测中,haarcascade_frontalface_alt效果最好,缺点是时间长
def detect(filename, cascade_file="C:\\OpenCV\\opencv\\build\\etc\\haarcascades\\haarcascade_frontalface_alt.xml"):
if not os.path.isfile(cascade_file):
raise RuntimeError("%s: not found" % cascade_file)
# 这里确认找到cascades识别器,找不到显示not found,地址请根据你的自己安装位置修改一下
cascade = cv2.CascadeClassifier(cascade_file)
# 导入识别器
image = cv2.imread(filename)
# 读取图片
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 获取图片的灰度图
gray = cv2.equalizeHist(gray)
faces = cascade.detectMultiScale(gray,
scaleFactor=1.1,
minNeighbors=5,
minSize=(48, 48))
# 识别脸部
for i, (x, y, w, h) in enumerate(faces):
# 定义脸部在图像上的坐标
face = image[y: y + h, x:x + w, :]
# 获取坐标位置的图
face = cv2.resize(face, (96, 96))
# 重新定义大小
save_filename = '%s-%d.jpg' % (os.path.basename(filename).split('.')[0], i)
# 定义保存图片的地址
cv2.imwrite("Faces/" + save_filename, face)
# 保存图片
if __name__ == '__main__':
if os.path.exists('Faces') is False:
os.makedirs('Faces')
# 检查Faces文件夹,没有就创建一个
file_list = glob('Photos/*.jpg')
for filename in file_list:
detect(filename)
这步完成之后,在faces文件夹里会有很多很多的美女脸部的截图,但是识别器可以用更好的,我这里只做示范,有些噪音数据就先放着不管了,你们自己做的时候想提高效果可以手动去除噪音数据,或者用更好的分类器。
\opencv\sources\data\haarcascades文件下有很多识别器,你们可以自己试试效果如果。用效果最好的那个即可。
接下来就是重难点了,用OpenCV的cascades创建我们自己的识别器。
首先需要获取正面和负面数据的数据列表信息。
CreateInfoTxt.py
import os
# 创建positive.txt和negative.txt文件
# 文件内容是数据集的list
def Create_faces_info_lst():
for file_type in ['Faces']:
for img in os.listdir(file_type):
if file_type == 'Faces':
line = file_type+'/'+img+' 1 0 0 48 48\n'
with open('info.lst','a') as f:
f.write(line)
if __name__=="__main__":
Create_faces_info_lst()
上面的代码运行之后会生成一个info.lst文件,里面会有Faces正面数据里的数据列表(让OpenCV知道你一共有多少正面数据有哪些),然后下载去我的github里下载背景即负面数据的数据集,https://github.com/sileixinhua
info.lst文件如下所示:
负面Negative文件夹数据如下所示:
这个时候有会用到Faces文件夹下美女脸部数据,info.lst正面数据列表信息(让OpenCV知道你一共有多少正面数据有哪些),从我github上下载的Negative文件夹,接下在本地项目文件夹下打开cmd。linux的打开terminal。运行如下命令
opencv_createsamples -info info.lst -num 14229 -w 48 -h 48 -vec positive.vec
这一行命令是根据正面数据的信息创建positive.vec文件,用来告诉opencv正面数据的特征。
如果报错"Parameters can not be written, because file data/params.xml can not be opened.",请在项目文件夹里创建一个名字为“data”的文件夹,
opencv_traincascade -data data -vec positive.vec -bg bg.txt -numPos 12000 -numNeg 202 -numStages 20 -w 48 -h 48
这一行命令就是训练我们的cascades识别器了,存放地址为data文件夹,vec就是我们上一步创建的positive.vec,bg就是Negative文件夹里负面数据的列表,训练区块为20个,根据数据集的大小可以调整,输入为高48,宽48。这里我做错了,应该填96。(这里一错又导致我效果不好),这里我一共花了2天采用CPU计算完毕。
全部计算结束后请再次输入一次上面的命令
opencv_traincascade -data data -vec positive.vec -bg bg.txt -numPos 12000 -numNeg 202 -numStages 20 -w 48 -h 48
用来把每一个区块的.xml结果信息合成为一个.xml文件
然后把data文件夹里生成的.xml文件改为你想要的名字,我就改为BeautifulFacaCascade.xml。
下一步就是第二部分的最后一部,识别美女脸部,我记录了视频和图片两种,代码如下所示:
CascadaBeautifulFace.py
import cv2
import os
import numpy as np
# opencv_createsamples -info info.lst -num 14229 -w 48 -h 48 -vec positive.vec
# create data file
# or will error "Parameters can not be written, because file data/params.xml can not be opened."
# opencv_traincascade -data data -vec positive.vec -bg bg.txt -numPos 12000 -numNeg 202 -numStages 20 -w 48 -h 48
# opencv_traincascade -data data -vec positive.vec -bg bg.txt -numPos 12000 -numNeg 202 -numStages 20 -w 48 -h 48
# ----------------------------------------------------------------------------------------------
# use video
# beautiful_face_cascade = cv2.CascadeClassifier('C:\\Code\\BeautifulGirls\\BeautifulFacaCascade.xml')
# cap = cv2.VideoCapture(0)
# while 1:
# ret, img = cap.read()
# gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# beautiful_face = beautiful_face_cascade.detectMultiScale(gray, 1.3, 5)
# # 这里参数可改成 5
# # detectMultiScale()
# # https://docs.opencv.org/2.4/modules/objdetect/doc/cascade_classification.html
# # minSize – Minimum possible object size. Objects smaller than that are ignored.
# # maxSize – Maximum possible object size. Objects larger than that are ignored.
# for (x,y,w,h) in beautiful_face:
# cv2.rectangle(img,(x,y),(x+w,y+h),(255,255,0),2)
# cv2.imshow('img',img)
# k = cv2.waitKey(30) & 0xff
# if k == 27:
# break
# cap.release()
# cv2.destroyAllWindows()
# ---------------------------------------------------------------------------------------
# use image
BeautifulFacaCascade = cv2.CascadeClassifier('C:\\Code\\BeautifulGirls\\BeautifulFacaCascade.xml')
img = cv2.imread('0.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
BeautifulFaca = BeautifulFacaCascade.detectMultiScale(gray, 500, 500)
for (x,y,w,h) in BeautifulFaca:
cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
cv2.imshow('img',img)
cv2.waitKey(0)
cv2.destroyAllWindows()
其实这一部分结果不是很好,原因有两个,一是脸部截取的数据有噪音,二是负面数据太少,但是我训练这些用了32G8核的7700K用了2天,应该改用GPU运算,最近事情比较多,我也就没再次训练了,有兴趣的同学可以自己再试一试。
第二部分十分繁琐,如果描述的不清楚,大家可以去网上搜索一下OpenCV Cascades,中文信息不多,最好用Google搜索。
Python3 + Tensorflow
Tensorflow的安装在windows上十分繁琐,linux也一样。主要是cudnn和cuda的安装麻烦。
去YouTuBe上去找视频看的话,但是绝大部分都是一年两年以前的视频。
安装请按照官方网站的来https://www.tensorflow.org/versions/master/install/install_linux
但是windows和linux上不用gpu运算的话可以用cpu运算,安装就十分简单了,本文第三部分实验我就是在自己笔记本上cpu运算的,耗时3,4小时而已。
安装命令如下:
pip3 install tensorflow
Python2的改“pip3”为“pip”。
上周我实验室的电脑系统崩了,还好我都有备份。但是我重装ubuntu之后,发现现在tensorflow不支持最新的cuda9,结果现在cuda官网只有9,测试失败之后又重装的系统装cuda8配cudnn,大家以后装tensorflow的时候可以注意,网上的教程一天一遍,过几个月基本都没用,还是要按照官方的安装指导来。
这部分实验都在文件夹DCGAN里。
首先在DCGAN文件夹下创建data文件夹,并把之前Faces文件夹复制到data文件夹里。
这里的代码我是直接在github上找到的代码,可以直接用。
https://github.com/carpedm20/DCGAN-tensorflow
在DCGAN文件下打开cmd或者terminal,运行如下命令。
python main.py --input_height 96 --input_width 96 --output_height 48 --output_width 48 --dataset Faces --crop --train --epoch 300 --input_fname_pattern "*.jpg"
这个人的代码十分有用,推荐有兴趣的同学好好看看分析一下。但是看之前还是建议把“花书”看了。
运行的效果如下图所示:
实验结果如下所示:
再训练下去只会更加清晰,有条件的同学可以把结果传群里,谢谢。