当前,随着人工智能、物联网等前沿技术的迅速发展,智能时代已悄然到来,"刷脸"逐渐成为了新的风潮。在人脸识别技术商业化应用领域不断扩张的趋势下,“刷脸”办事正愈发常见。
人脸识别,是基于人的脸部特征信息进行身份识别的一种生物识别技术。用摄像机或摄像头采集含有人脸的图像或视频流,并自动在图像中检测和跟踪人脸,进而对检测到的人脸进行脸部识别的一系列相关技术,通常也叫做人像识别、面部识别。
。
人脸识别,是基于人的脸部特征信息进行身份识别的一种生物识别技术。除了安防、金融这两大领域外,人脸识别还在交通、教育、医疗、警务、电子商务等诸多场景实现了广泛应用,且呈现出显著应用价值。为了进一步把握人脸识别技术所带来的重大机遇,我国出台了一系列政策予以支撑。
人脸识别最初在20世纪60年代已经有研究人员开始研究,真正进入初级的应用阶段是在90年代后期,发展至今其技术成熟度已经达到较高的程度。整个发展过程可以分为机械识别、半自动化识别、非接触式识别及互联网应用阶段。
与其他生物识别方式相比,人脸识别优势在于自然性、不被察觉性等特点。自然性即该识别方式同人类进行个体识别时所利用的生物特征相同。指纹识别、虹膜识别等均不具有自然性。不被察觉的特点使该识别方法不易使人抵触,而指纹识别或虹膜识别需利用电子压力传感器或红外线采集指纹、虹膜图像,在采集过程中体验感不佳。目前人脸识别需要解决的难题是在不同场景、脸部遮挡等应用时如何保证识别率。此外,隐私性和安全性也是值得考虑的问题。人脸识别优势明显,未来将成为识别主导技术。具体来说,相比指纹识别、虹膜识别等传统的生物识别方式,优点主要还集中在四点:非接触性、非侵扰性、硬件基础完善和采集快捷便利,可拓展性好。在复杂环境下,人脸识别精度问题得到解决后,预计人脸识别有望快速替代指纹识别成为市场大规模应用的主流识别技术。
import argparse
import os
import re
import sys
import urllib
import json
import socket
import urllib.request
import urllib.parse
import urllib.error
# 设置超时
import time
time_sleep = 0.1
def handle_baidu_cookie(original_cookie, cookies):
"""
:param string original_cookie:
:param list cookies:
:return string:
"""
if not cookies:
return original_cookie
result = original_cookie
for cookie in cookies:
result += cookie.split(';')[0] + ';'
result.rstrip(';')
return result
def get_suffix(name):
m = re.search(r'\.[^\.]*$', name)
if m.group(0) and len(m.group(0)) <= 5:
return m.group(0)
else:
return '.jpg'
# 保存图片
def save_image(rsp_data, word, max_count):
if not os.path.exists("./" + word):
os.mkdir("./" + word)
# 判断名字是否重复,获取图片长度
counter = len(os.listdir('./' + word)) + 1
for image_info in rsp_data['data']:
try:
if 'replaceUrl' not in image_info or len(image_info['replaceUrl']) < 1:
continue
obj_url = image_info['replaceUrl'][0]['ObjUrl']
thumb_url = image_info['thumbURL']
url = 'https://image.baidu.com/search/down?tn=download&ipn=dwnl&word=download&ie=utf8&fr=result&url=%s&thumburl=%s' % (urllib.parse.quote(obj_url), urllib.parse.quote(thumb_url))
time.sleep(time_sleep)
suffix = get_suffix(obj_url)
# 指定UA和referrer,减少403
opener = urllib.request.build_opener()
opener.addheaders = [
('User-agent', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36'),
]
urllib.request.install_opener(opener)
# 保存图片
filepath = './%s/%s' % (word, str(counter) + str(suffix))
urllib.request.urlretrieve(url, filepath)
if os.path.getsize(filepath) < 5:
print("下载到了空文件,跳过!")
os.unlink(filepath)
continue
except urllib.error.HTTPError as urllib_err:
print(urllib_err)
continue
except Exception as err:
time.sleep(1)
print(err)
print("产生未知错误,放弃保存")
continue
else:
print("图片下载成功,已有" + str(counter) + "张图片")
if counter == max_count:
return
counter += 1
return
def pic_num(file_path):
return len(os.listdir(file_path))
def request_json_str(request_url):
try:
user_headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:23.0) Gecko/20100101 Firefox/23.0', 'Cookie': ''}
req = urllib.request.Request(url=request_url, headers=user_headers)
page = urllib.request.urlopen(req)
user_headers['Cookie'] = handle_baidu_cookie(user_headers['Cookie'], page.info().get_all('Set-Cookie'))
rsp = page.read()
page.close()
except UnicodeDecodeError as e:
print(e)
print('-----UnicodeDecodeErrorurl:', single_page_url)
except urllib.error.URLError as e:
print(e)
print("-----urlErrorurl:", single_page_url)
except socket.timeout as e:
print(e)
print("-----socket timout:", single_page_url)
else:
return rsp
def decode_json(json_source):
try:
json_data = json.loads(json_source, strict=False)
except json.decoder.JSONDecodeError:
try:
source_replace = str(json_source.decode(encoding='utf8')).replace('\\', '\\\\')
json_data = json.loads(source_replace, strict=False)
except json.decoder.JSONDecodeError:
return None
return json_data
def download_single_page(word, page_url, max_pic_num):
print("开始下载" + page_url + "中的数据")
max_err_num = 5
err_count = 0
rsp = request_json_str(page_url)
rsp_data = decode_json(rsp)
while(rsp_data == None or 'data' not in rsp_data):
if rsp_data == None:
print("JSON字符串错误,尝试重试")
err_count += 1
else:
print("触发反爬机制,正在重试\r", end='')
if err_count > max_err_num:
print("JSON错误次数超过", max_err_num, "次,跳过该页")
return
rsp = request_json_str(page_url)
rsp_data = decode_json(rsp)
save_image(rsp_data, word, max_pic_num)
print("该页下载完成")
def get_image(word, max_pic_num):
os.mkdir('./' + word)
start_page = 1
per_page = 30
start_amount = (start_page - 1) * per_page
search = urllib.parse.quote(word)
pn = start_amount
while pic_num('./' + word) < max_pic_num:
single_page_url = 'https://image.baidu.com/search/acjson?tn=resultjson_com&ipn=rj&ct=201326592&is=&fp=result&queryWord=%s&cl=2&lm=-1&ie=utf-8&oe=utf-8&adpicid=&st=-1&z=&ic=&hd=&latest=©right=&word=%s&s=&se=&tab=&width=&height=&face=0&istype=2&qc=&nc=1&fr=&expermode=&force=&pn=%s&rn=%d&gsm=1e&1594447993172=' % (search, search, str(pn), per_page)
time.sleep(time_sleep)
download_single_page(word, single_page_url, max_pic_num)
pn += per_page
print("下载任务结束")
return
#删除原文件夹
def del_file(path):
list1 = os.listdir(path)
for i in list1:
c_path = os.path.join(path, i)
if os.path.isdir(c_path):
del_file(c_path)
else:
os.remove(c_path)
# print(path,"已被删除")
#爬图片
import os
image_name="美女"
image_count=10
if(os.path.exists(r'/home/aistudio/%s'%(image_name))):
del_file(r'/home/aistudio/%s'%(image_name))
os.rmdir(r'/home/aistudio/%s'%(image_name))
if(os.path.exists(r'/home/aistudio/output')):
del_file(r'/home/aistudio/output')
os.rmdir(r'/home/aistudio/output')
os.mkdir("output")
print("已创建文件夹output")
else:
os.mkdir("output")
print("已创建文件夹output")
get_image(image_name,image_count)
!pip install paddlehub==1.8.0
检测人脸
%matplotlib inline
# 导入所需要使用的包
import cv2
import paddlehub as hub
from matplotlib import pyplot as plt
# 加载Paddlehub人脸检测模型
face_detector = hub.Module(name="pyramidbox_lite_mobile")
def renlian(path1,path2,image_count_i): #原始图片 检测后的图片 图片数量
# 使用模型进行图片预测
result = face_detector.face_detection(paths=[r'%s/%s.jpg'%(path1,image_count_i)],
use_gpu=False,
visualization=True,
output_dir='/home/aistudio/output',
confs_threshold=0.5)
# 打印检测结果
# print(result)
# 显示可视化图片
output = cv2.imread(r'%s/%s.jpg'%(path2,image_count_i))
output = output[:,:,::-1]
plt.imshow(output)
plt.show()
path1 = r'/home/aistudio/%s'%(image_name)
path2 = r'/home/aistudio/output'
list1 = os.listdir(path1)
list2 = os.listdir(path2)
for i in range(1,image_count+1):
renlian(path1,path2,i)
修改部分代码
#爬图片
import os
image_name="鞠婧祎"
image_count=10
get_image(image_name,image_count)
path1 = r'/home/aistudio/%s'%(image_name)
path2 = r'/home/aistudio/output'
list1 = os.listdir(path1)
list2 = os.listdir(path2)
for i in range(1,image_count+1):
renlian(path1,path2,i)
更换原图片
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
# 展示待预测图片
path = '/home/aistudio/picture'
test_img_path = os.listdir(path)
print(test_img_path)
for i in test_img_path:
if i[0] =='.': test_img_path.remove(i)
test_img_path.sort()#排序
print('test_img_path:',test_img_path)
# 待预测图片
test_img_path_s = ["/home/aistudio/picture/01.jpg",
"/home/aistudio/picture/02.jpg",
"/home/aistudio/picture/03.jpg",
]
test_img_path_s=[]
for i in test_img_path:
test_img_path_s.append(path+'/'+i)
print('test_img_path_s:',test_img_path_s)
for i in test_img_path_s:
img = mpimg.imread(i)
plt.figure(figsize=(10,10))
plt.imshow(img)
plt.axis('off')
plt.show()
利用Ultra-Light-Fast-Generic-Face-Detector-1MB完成对该文件的人脸检测,只需读入该文件,将文件内容存成list,list中每个元素是待预测图片的存放路径。
ultra_light_fast_generic_face_detector_1mb_320,在预测时会将图片输入缩放为320 * 240,预测速度更快。
ultra_light_fast_generic_face_detector_1mb_640,在预测时会将图片输入缩放为640 * 480,预测精度更高。
import paddlehub as hub
module = hub.Module(name="ultra_light_fast_generic_face_detector_1mb_640")
#module = hub.Moudle(name="ultra_light_fast_generic_face_detector_1mb_320")
def cpdd(img_name):
img=[r'/home/aistudio/picture/%s'%(img_name)]
print(img)
# 多张脸单图片处理
input_dict = {"image": img}
# 预测结果展示
results = module.face_detection(data=input_dict)
for result in results:
res1 = result['data']
# print(res1)
#绘制矩形并显示
img = mpimg.imread(img[0])
for i in range(len(res1)):
img = cv2.rectangle(img,(int(res1[i]['left']),int(res1[i]['top'])),(int(res1[i]['right']),int(res1[i]['bottom'])),(0,255,0),3)
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
cv2.imwrite(r"/home/aistudio/output2/%s"%(img_name),img)
plt.figure(figsize=(10,10))
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
plt.imshow(img)
plt.axis('off')
plt.show()
def cpdds(test_img_path):
if(os.path.exists(r'/home/aistudio/output2')):
del_file(r'/home/aistudio/output2')
os.rmdir(r'/home/aistudio/output2')
os.mkdir("output2")
print("已创建文件夹 output2")
else:
os.mkdir("output2")
print("已创建文件夹 output2")
for i in test_img_path:
cpdd(i)
cpdds(test_img_path)
已创建文件夹 output2
['/home/aistudio/picture/01.jpg']
['/home/aistudio/picture/02.jpg']
['/home/aistudio/picture/03.jpg']
检测到人脸可以戴上口罩、戴上眼镜、打马赛克等,以下为人脸替换示例
def cpdd(img_name,TF=False): #TF表示是否遮挡
img=[r'/home/aistudio/picture/%s'%(img_name)]
print(img)
img_0=img
# 多张脸单图片处理
input_dict = {"image": img}
# 预测结果展示
results = module.face_detection(data=input_dict)
for result in results:
res = result['data']
# print('res=',res)
# print(type(res))
#绘制矩形并显示
img = mpimg.imread(img[0])
for i in range(len(res)):
img = cv2.rectangle(img,(int(res[i]['left']),int(res[i]['top'])),(int(res[i]['right']),int(res[i]['bottom'])),(0,255,0),3)
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
cv2.imwrite(r"/home/aistudio/output2/%s"%(img_name),img)
plt.figure(figsize=(10,10))
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
plt.imshow(img)
plt.axis('off')
plt.show()
if(TF):
z_cpdds(img_0,'/home/aistudio/mask.jpg',res)
def cpdds(test_img_path,TF=False):
if(os.path.exists(r'/home/aistudio/output2')):
del_file(r'/home/aistudio/output2')
os.rmdir(r'/home/aistudio/output2')
os.mkdir("output2")
print("已创建文件夹 output2")
else:
os.mkdir("output2")
print("已创建文件夹 output2")
for i in test_img_path:
cpdd(i,TF)
增加一个新的函数
def z_cpdds(cpNB,cpTNB,res_list):
print('cpNB,cpTNB=',cpNB,cpTNB)
#被遮挡的图片路径(列表) #用来遮挡的图片路径
#遮挡
from PIL import Image
import numpy as np
#img = mpimg.imread(cpNB[0])
img = cv2.imread(cpNB[0])
for res in res_list:
shape = (int(res['right']-res['left']),int(res['bottom']-res['top']))#人脸区域大小
image = Image.open(cpTNB).resize(shape) #用来遮挡的图片
face = img[int(res['top'])+10:int(res['top'])+image.size[1]+10, int(res['left'])+5:int(res['left'])+image.size[0]+5]#整体右下移动
#print(image.size)#宽高
#print(face.shape)#高宽
# 图片加权合成
scope_map = np.array(image)[:,:,-1] / 255
scope_map = scope_map[:,:,np.newaxis]
scope_map = np.repeat(scope_map, repeats=3, axis=2)
res_image = np.multiply(scope_map, np.array(image)[:,:,:3]) + np.multiply((1-scope_map), np.array(face))
img[int(res['top']):int(res['top'])+image.size[1],
int(res['left']):int(res['left'])+image.size[0]] = np.uint8(image)[:, : , ::-1]
plt.figure(figsize=(10,10))
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
plt.imshow(img)
plt.axis('off')
plt.show()
['01.jpg', '02.jpg', '03.jpg']
已创建文件夹 output2
['/home/aistudio/picture/01.jpg']
cpNB,cpTNB=
['/home/aistudio/picture/01.jpg']
/home/aistudio/mask.jpg
['/home/aistudio/picture/02.jpg']
cpNB,cpTNB=
['/home/aistudio/picture/02.jpg']
/home/aistudio/mask.jpg
['/home/aistudio/picture/03.jpg']
cpNB,cpTNB=
['/home/aistudio/picture/03.jpg']
/home/aistudio/mask.jpg
视频1
!pip install paddlehub==1.8.0
import cv2
import os
import numpy as np
import paddlehub as hub
def CutVideo2Image(video_path, img_path):
#将视频输出为图像
print('将视频输出为图像中')
#video_path为输入视频文件路径
#img_path为输出图像文件夹路径
cap = cv2.VideoCapture(video_path)
index = 0
while(True):
ret,frame = cap.read()
if ret:
cv2.imwrite(img_path+'/%d.jpg'%index, frame)
index += 1
else:
break
cap.release()
print('输出图像%d张'%(index))
print('视频输出为图像完毕')
def Iou(bbox1,bbox2):
#计算Iou
#bbox1,bbox为xyxy数据
area1 = (bbox1[2]-bbox1[0])*(bbox1[3]-bbox1[1])
area2 = (bbox2[2]-bbox2[0])*(bbox2[3]-bbox2[1])
w = min(bbox1[3],bbox2[3])-max(bbox1[1],bbox2[1])
h = min(bbox1[2],bbox2[2])-max(bbox1[0],bbox2[0])
if w<=0 or h<=0:
return 0
area_mid = w*h
return area_mid/(area1+area2-area_mid)
def GetFace(in_path, out_path):
#人脸检测,并计算通过的人数
print('人脸检测中')
#in_path为输入图像文件夹的路径
#out_path为输出图像文件夹的路径,并为人脸标注检测框和进行计数
files = os.listdir(in_path)
face_detector = hub.Module(name="pyramidbox_lite_server")
bbox_buffer = []
count = 0 #统计人数
for i in range(len(files)):
#文件中的每张图片
img = cv2.imread(in_path+'/%d.jpg' % i)
result = face_detector.face_detection(images=[img])
data = result[0]['data']
bbox_upgrade = []
index = []
for j in range(len(data)):
#图片中的每个bbox
left, right = int(data[j]['left']), int(data[j]['right'])
top, bottom = int(data[j]['top']), int(data[j]['bottom'])
bbox = (left, top, right, bottom)
if right>1600 and left<1600:
count = count+1
for k in range(len(bbox_buffer)):
if Iou(bbox, bbox_buffer[k])>0.1 and k not in index:
count = count-1
index.append(k)
break
bbox_upgrade.append(bbox)
cv2.rectangle(img, (left, top), (right, bottom), (0, 0, 255), 3)
else:
cv2.rectangle(img, (left, top), (right, bottom), (0, 255, 0), 3)
bbox_buffer = bbox_upgrade.copy()
cv2.putText(img,'count=%d'%count,(50,900),cv2.FONT_HERSHEY_COMPLEX,6,(0,0,255),10)
cv2.imwrite(out_path+'/%d.jpg'%i, img)
print('人脸检测完毕,共%d张'%(count))
def CombVideo(in_path, out_path, size):
#将图片合成视频
print('将图片合成视频中')
#in_path为输入图像文件夹路径
#out_path为输出视频文件路径
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
out = cv2.VideoWriter(out_path,fourcc, 30.0, size)
files = os.listdir(in_path)
for i in range(len(files)):
img = cv2.imread(in_path + '/%d.jpg' % i)
#img = cv2.resize(img, size)
out.write(img)
out.release()
print('图片合成视频完毕')
#删除文件夹内的文件和文件夹
def del_file(path):
list1 = os.listdir(path)
for i in list1:
c_path = os.path.join(path, i)
if os.path.isdir(c_path):
del_file(c_path)
else:
os.remove(c_path)
print(path,"已被删除")
#清空文件夹(不存在则创建)
def clear_path(out_path):
if(os.path.exists(out_path)): #如果该文件夹存在
del_file(out_path) #删除文件夹内的文件和文件夹
os.rmdir(out_path) #删除文件夹
os.mkdir(out_path) #创建文件夹
else:
os.mkdir(out_path)
print("已清空文件夹",out_path)
clear_path('/home/aistudio/images_initial')
clear_path('/home/aistudio/images_face')
if __name__ == '__main__':
video_initial = '/home/aistudio/抖音素材.mp4'
video_finish = '/home/aistudio/视频.mp4'
images_initial = '/home/aistudio/images_initial'
images_face = '/home/aistudio/images_face'
CutVideo2Image(video_initial, images_initial)
GetFace(images_initial, images_face)
CombVideo(images_face, video_finish,(1920,1080))
会生成一个“抖音素材.mp4.mp3”的文件
!pip install ffmpeg moviepy
import moviepy.editor as mp
def extract_audio(videos_file_path):
my_clip = mp.VideoFileClip(videos_file_path)
my_clip.audio.write_audiofile(f'{videos_file_path}.mp3')
extract_audio(r'/home/aistudio/抖音素材.mp4')
from moviepy import *
from moviepy.editor import *
import glob
video_dirs = glob.glob('/home/aistudio/视频.mp4')
audio = AudioFileClip("/home/aistudio/抖音素材.mp4.mp3")# 提取音轨
for video_dir in video_dirs:
video = VideoFileClip(video_dir)# 读入视频
video = video.set_audio(audio)# 将音轨合成到视频中
video.write_videofile("/home/aistudio/将音轨合成到视频中/" + video_dir.split("/")[-1])# 输出
视频3