目录
系统总体
思路
- 选择分类文件夹
- 选择要分类的已知人物图片
- 为分类人物命名新文件夹
- 将人物图片与要分类文件夹下的每张图进行比对
- 比对成功将图片移入分类人物文件夹
- 容错设置(暂时想到的错误已经进行处理,未发现的错误会写入error.txt文件里)
整体代码
# #!/usr/bin/env python
# # -*- coding: utf-8 -*-
# # @Time : 2020/02/23 20:21
# # @Author : Cxk
# # @File : face_info.py
import face_recognition
import os
import shutil
from tkinter import *
from tkinter.messagebox import *
from tkinter import filedialog
import threading
def recognition(known_image,unknown_image):
try:
results=[]
face_encoding = face_recognition.face_encodings(known_image)[0]
# print("face_encoding :{}".format(unknown_face_encoding))
#获取每个图像文件中每个面部的面部编码
#由于每个图像中可能有多个面,所以返回一个编码列表。
unknown_face=face_recognition.face_encodings(unknown_image)
for i in range(len(unknown_face)):
known_faces = [face_encoding]
# #结果是True/false的数组,未知面孔known_faces阵列中的任何人相匹配的结果
results = face_recognition.compare_faces(known_faces, unknown_face[i])
# print(results)
if results[0]==True:
break
else:
continue
return results
except Exception as e:
cuowu="shibie "+str(e)
with open('error.txt','a') as file_handle: # .txt可以不自己新建,代码会自动新建
file_handle.write(cuowu) # 写入
file_handle.write('\n')
def cxk(path,path2,image):
#已知人物的图片
known_image = face_recognition.load_image_file(image)
# unknow_image = face_recognition.load_image_file("0.jpg")
# print(shibie(know_image,unknow_image))
# path=os.getcwd()+"\未知"
# path2=os.getcwd()+"\陈赫"
old_name=os.listdir(path)
for i in old_name:
try:
name =os.path.join(path,i)
unknown_image = face_recognition.load_image_file(name)
if recognition(known_image,unknown_image)[0]==True:
shutil.move(name, path2)
else:
pass
except Exception as e:
cuowu="cxk "+str(e)
with open('error.txt','a') as file_handle: # .txt可以不自己新建,代码会自动新建
file_handle.write(cuowu) # 写入
file_handle.write('\n')
class Rootpage(object):
def __init__(self, master=None):
self.root = master
winWidth = 400
winHeight = 400
screenWidth = self.root.winfo_screenwidth()
screenHeight = self.root.winfo_screenheight()
x = int((screenWidth - winWidth) / 2)
y = int((screenHeight - winHeight) / 2)
# 设置窗口初始位置在屏幕居中
self.root.geometry("%sx%s+%s+%s" % (winWidth, winHeight, x, y))
# 设置窗口图标
# root.iconbitmap("./image/icon.ico")
# 设置窗口宽高固定
self.root.resizable(0, 0)
self.name = StringVar()
self.Folderpath=""
self.Filepath=""
self.createPage()
def createPage(self):
Label(root,font=("微软雅黑", 20),text="").pack()
Label(root,font=("微软雅黑", 20),text="").pack()
Button(root,text='选择文件夹', bd =5,command=self.open_fold).pack()
Button(root,text='选择图片', bd =5,command=self.open_file).pack()
Label(root,font=("微软雅黑", 20),text="请输入该人物名称").pack()
entry=Entry(root,font="Helvetica 13 bold", bd =5,width=8,textvariable=self.name).pack()
Button(root,text='开启分类', bd =5,command=self.fun).pack()
def open_fold(self):
self.Folderpath = filedialog.askdirectory() #获得选择好的文件夹
old_name=os.listdir(self.Folderpath)
if old_name==[]:
showinfo(title='错误', message='你所选择的文件夹为空,请重新选择!')
else:
Label(root,font=("微软雅黑", 10),text=self.Folderpath).pack()
def open_file(self):
self.Filepath = filedialog.askopenfilename() #获得选择好的文件
try:
known_image = face_recognition.load_image_file(self.Filepath)
face_encoding = face_recognition.face_encodings(known_image)[0]
except:
showinfo(title='错误', message='你所选择的图片无人脸信息,请重新选择!')
else:
Label(root,font=("微软雅黑", 10),text=self.Filepath).pack()
def start(self):
name=self.name.get()
if name=="" or self.Folderpath=="" or self.Filepath=="":
showinfo(title='错误', message='请检查是否选择文件夹或者图片又或者名字是否为空!')
else:
showinfo(title='提示', message='后台分类已开始\n请稍等,完成后将会有提示!')
path2=os.path.abspath(os.path.join(self.Folderpath,".."))#返回上一目录
path2=path2+"\%s"%name
if not os.path.exists(path2):#判断一个目录是否存在
os.makedirs(path2)
cxk(self.Folderpath,path2,self.Filepath)
os.startfile(path2)
showinfo(title='提示', message='分类已完成,已为你打开该人物文件夹!')
def fun(self):
th=threading.Thread(target=self.start)
th.setDaemon(True)#守护线程
th.start()
if __name__ == "__main__":
root = Tk()
root.title('依据人脸分类图片')
Rootpage(root)
root.mainloop()
附带一键百度关键词图片下载(源码忘了在那本书上的了)
图片下载模块忘了在那本书看到的了,有知道的说一下我备注一下作者,文件批量重命名自个加的,可以直接加在spidler函数内的,没去整了。
# -*- coding:utf-8 -*-
import requests,os #首先导入库
import re
#设置默认配置
MaxSearchPage = 20 # 收索页数
CurrentPage = 0 # 当前正在搜索的页数
NeedSave = 0 # 是否需要储存
folder_path = ''#文件保存位置
#图片链接正则和下一页的链接正则
def imageFiler(content):# 通过正则获取当前页面的图片地址数组
return re.findall('"objURL":"(.*?)"',content,re.S)
def nextSource(content): # 通过正则获取下一页的网址
next = re.findall('<div id="page">.*<a href="(.*?)" class="n">',content,re.S)[0]
return next
#爬虫主体
def spidler(source):
content = requests.get(source).text # 通过链接获取内容
imageArr = imageFiler(content) # 获取图片数组
global CurrentPage
for imageUrl in imageArr:
global NeedSave
if NeedSave: # 如果需要保存图片则下载图片,否则不下载图片
global DefaultPath
try:
# 下载图片并设置超时时间,如果图片地址错误就不继续等待了
picture = requests.get(imageUrl,timeout=10)
except:
continue
# 创建图片保存的路径
imageUrl = imageUrl.replace('/','').replace(':','').replace('?','')
pictureSavePath = imageUrl
fp = open(os.path.join(folder_path,pictureSavePath),'wb') # 以写入二进制的方式打开文件
fp.write(picture.content)
fp.close()
global MaxSearchPage
if CurrentPage <= MaxSearchPage: #继续下一页爬取
if nextSource(content):
CurrentPage += 1
# 爬取完毕后通过下一页地址继续爬取
spidler("http://image.baidu.com" + nextSource(content))
#爬虫的开启方法
def beginSearch(key,page):
"""
page搜索页面,数字上加两页就是实际搜索页面,列如page=-1,实际搜索页面为一页
"""
global MaxSearchPage,NeedSave,folder_path
MaxSearchPage = page
NeedSave = 1 #是否保存,值0不保存,1保存
folder_path=key+"/"
if os.path.exists(folder_path) == False:
os.makedirs(folder_path)
StartSource = "http://image.baidu.com/search/flip?tn=baiduimage&ie=utf-8&word=" + str(key) + "&ct=201326592&v=flip" # 分析链接可以得到,替换其`word`值后面的数据来搜索关键词
spidler(StartSource)
print("完成!")
def rename(name):
"""
# beginSearch("周冬雨",-1)
# 1.os.name——判断现在正在实用的平台,Windows 返回 ‘nt'; Linux ...
# 2.os.getcwd()——得到当前工作的目录。
# 3.os.remove()——删除指定文件
# 4.os.rmdir()——删除指定目录 删除文件夹,不好演示,自己试一下
# 5.os.mkdir()——创建目录 就是在指定目录新建一个文件夹
"""
beginSearch(name,-1)#下载图片
path=os.getcwd()+"\%s"%name
old_name=os.listdir(path)
# print(old_name)
new_name=[]
j=0
for i in old_name:
new_name.append(str(j))
j+=1
# print(new_name)
for x, y in zip(old_name, new_name):
os.renames(path+"\%s"%x,path+"\%s.jpg"%y)
print("已改名!")
a=os.listdir(path)
print(a)
rename("周冬雨")
总结
- face_recognition有自带的文件夹分类的,此次属于重复造轮子,算是个人界面版
- 很多细节已经有注释
- 还有我不是标题党,哈哈哈,做这个还真是为了整理跟女朋友这几年的照片。
- 对了,我女票是周冬雨。
- 其余不多说了,有兴趣探讨的留言或私信,博客只是用来记录,以后不会花太多时间在分享细节上