连载:一步步实现人脸数据的提取【原创】
本帖最后由 keer_zu 于 2019-1-24 10:00 编辑要识别人脸,先要录入人脸图片。
录入需要考虑的是怎么能从摄像头得到的数据中得到你需要录入的人脸。
首先,你要从摄像头的流数据(比如rtsp)中得到一个image,
然后从中得到人脸,这个过程还需要排除旁边其他人的人脸。
从rtsp读取的数据如果一直不处理,就会让缓冲崩溃。
所以打算采用每隔若干张image(比如20张),选一张去处理。其余的都交给显示程序播放视频。
被处理的那张虽然是好多张中才选取一张,但是如果要和播放串行处理,仍然会造成播放不畅,缓冲崩掉。所以必须采用并发,先实现并发:
(第一步,让python并发起来)
import cv2
import dlib
import os
import sys
#import random
import time
from multiprocessing import Process, JoinableQueue, Queue
from random import random
import time
#tasks_queue = JoinableQueue()
results_queue = Queue()
name = "abc"#input('please input your name:')
window_name = "face picture entry"
output_dir = './' + name + '_faces'
size = 64
if not os.path.exists(output_dir):
os.makedirs(output_dir)
# 改变图片的亮度与对比度
def relight(img, light=1, bias=0):
w = img.shape
h = img.shape
#image = []
for i in range(0,w):
for j in range(0,h):
for c in range(3):
tmp = int(img*light + bias)
if tmp > 255:
tmp = 255
elif tmp < 0:
tmp = 0
img = tmp
return img
#使用dlib自带的frontal_face_detector作为我们的特征提取器
detector = dlib.get_frontal_face_detector()
#videoName = './' + name + '.avi'
videoName = "rtsp://admin:ABC_123456@172.17.208.150:554/Streaming/Channels/101?transportmode=unicast"
# 打开摄像头 参数为输入流,可以为摄像头或视频文件
def CatchUsbVideo(out_queue):
process_flag = False
cv2.namedWindow(window_name)
#视频来源,可以来自一段已存好的视频,也可以直接来自USB摄像头
cap = cv2.VideoCapture(videoName)
n = 1
while cap.isOpened():
ok, frame = cap.read() #读取一帧数据
if not ok:
break
#显示图像并等待10毫秒按键输入,输入‘q’退出程序
cv2.namedWindow(window_name, cv2.WINDOW_NORMAL) #cv2.WND_PROP_FULLSCREEN)
#cv2.moveWindow(window_name, screen.x - 1, screen.y - 1)
cv2.setWindowProperty(window_name, cv2.WND_PROP_FULLSCREEN,
cv2.WINDOW_FULLSCREEN)
n = n + 1
if n == 20:
if process_flag == True:
out_queue.put(frame)
n = 1
else:
frameresize = cv2.resize(frame,(1280,800))
cv2.imshow(window_name, frameresize)
c = cv2.waitKey(10)
if c & 0xFF == ord('q'):
break
if c & 0xFF == ord('d'):
process_flag = True
#释放摄像头并销毁所有窗口
cap.release()
cv2.destroyAllWindows()
def FaceDectection(in_queue):
while 1:
img = in_queue.get()
if img is None:
break
else:
print("====== recv pic")
#if __name__ == '__main__':
# CatchUsbVideo()
processes = []
p = Process(target=CatchUsbVideo, args=(results_queue,))
p.start()
processes.append(p)
p = Process(target=FaceDectection, args=(results_queue,))
p.start()
processes.append(p)
for p in processes:
p.join()
while 1:
time.sleep(1)
@21ic小管家 @sherwin @海中水 @tyw @yyy71cj @gaoyang9992006
2019年1月15号,增加探测并获取人脸代码:
def FaceDectection(in_queue):
index = 0
while 1:
img = in_queue.get()
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 使用detector进行人脸检测
dets = detector(gray_img, 1)
for i, d in enumerate(dets):
x1 = d.top() if d.top() > 0 else 0
y1 = d.bottom() if d.bottom() > 0 else 0
x2 = d.left() if d.left() > 0 else 0
y2 = d.right() if d.right() > 0 else 0
face = img
# 调整图片的对比度与亮度, 对比度与亮度值都取随机数,这样能增加样本的多样性
#face = relight(face, random.uniform(0.5, 1.5), random.randint(-50, 50))
face = cv2.resize(face, (size,size))
#cv2.imshow('image', face)
cv2.imwrite(output_dir+'/'+str(index)+'.jpg', face)
index += 1
if index == 5:
break
2019-1-16 10:35继续修改FaceDectection(),可以获取镜头中主要人物的人脸,用于人脸采集和识别。
这里,我只是简单做了一下尺寸的筛选。
def FaceDectection(in_queue):
index = 0
while 1:
img = in_queue.get()
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 使用detector进行人脸检测
dets = detector(gray_img, 1)
for i, d in enumerate(dets):
print("----- i:%d\n" % i)
x1 = d.top() if d.top() > 0 else 0
y1 = d.bottom() if d.bottom() > 0 else 0
x2 = d.left() if d.left() > 0 else 0
y2 = d.right() if d.right() > 0 else 0
face = img
if face.shape > 400 :# check picture size
cv2.imwrite(output_dir+'/'+str(index)+'.jpg', face)
index += 1
if index == 5:
break
2019.01.23
def ConvertUseTensorflowMtcnn(in_queue,msg_q):
margin = 32
index_num = 0
target_dir = os.path.join(img_dir,"images_data_%d" % target_img_size)
output_user_dir = os.path.join(target_dir, name)
if not os.path.exists(output_user_dir):
os.makedirs(output_user_dir)
minsize = 30 # minimum size of face
threshold = [ 0.6, 0.7, 0.7 ]# three steps's threshold
factor = 0.709 # scale factor
with tf.Graph().as_default():
gpu_options = tf.GPUOptions(per_process_gpu_memory_fraction=0.25)
sess = tf.Session(config=tf.ConfigProto(gpu_options=gpu_options, log_device_placement=False))
with sess.as_default():
pnet, rnet, onet = detect_face.create_mtcnn(sess, None)
while 1:
file_name = in_queue.get()
print("====== file: %s" % file_name)
img = cv2.imread(file_name)
bounding_boxes, _ = detect_face.detect_face(img, minsize, pnet, rnet, onet, threshold, factor)
print(bounding_boxes)
nrof_faces = bounding_boxes.shape
print(nrof_faces)
if nrof_faces>0:
det = bounding_boxes[:,0:4]
det_arr = []
img_size = np.asarray(img.shape)
print("====nrof_face: %dimg size:"% nrof_faces)
print(img_size)
if nrof_faces == 1:
bounding_box_size = (det[:,2]-det[:,0])*(det[:,3]-det[:,1])
img_center = img_size / 2
offsets = np.vstack([ (det[:,0]+det[:,2])/2-img_center, (det[:,1]+det[:,3])/2-img_center ])
offset_dist_squared = np.sum(np.power(offsets,2.0),0)
index = np.argmax(bounding_box_size-offset_dist_squared*2.0) # some extra weight on the centering
det_arr.append(det)
for i, det in enumerate(det_arr):
det = np.squeeze(det)
bb = np.zeros(4, dtype=np.int32)
bb = np.maximum(det-margin/2, 0)
bb = np.maximum(det-margin/2, 0)
bb = np.minimum(det+margin/2, img_size)
bb = np.minimum(det+margin/2, img_size)
cropped = img:bb,bb:bb,:]
scaled = misc.imresize(cropped, (target_img_size, target_img_size), interp='bilinear')
output_filename = os.path.join(output_user_dir, ("%d" % index_num) +'.png')
filename_base, file_extension = os.path.splitext(output_filename)
output_filename_n = "{}{}".format(filename_base, file_extension)
misc.imsave(output_filename_n, scaled)
index_num += 1
#if os.path.exists(file_name):
#os.remove(file_name)
if index_num >= 5:
msg_q.put("complate_msg")
msg_q.put("complate_msg")
break
对opencv筛选的人脸图片使用tensorflow实现的mtcnn进行再次确认和校正:
本帖最后由 keer_zu 于 2019-1-15 18:19 编辑
github同步更新中。。。。 本帖最后由 keer_zu 于 2019-1-15 18:38 编辑
刚刚更新代码,为第二个进程增加人脸获取代码:
import cv2
import dlib
import os
import sys
#import random
import time
from multiprocessing import Process, JoinableQueue, Queue
from random import random
import time
#tasks_queue = JoinableQueue()
results_queue = Queue()
name = input('please input your name:')
window_name = "face picture entry"
output_dir = './' + name + '_t'
size = 64
if not os.path.exists(output_dir):
os.makedirs(output_dir)
# 改变图片的亮度与对比度
def relight(img, light=1, bias=0):
w = img.shape
h = img.shape
#image = []
for i in range(0,w):
for j in range(0,h):
for c in range(3):
tmp = int(img*light + bias)
if tmp > 255:
tmp = 255
elif tmp < 0:
tmp = 0
img = tmp
return img
#使用dlib自带的frontal_face_detector作为我们的特征提取器
detector = dlib.get_frontal_face_detector()
#videoName = './' + name + '.avi'
videoName = "rtsp://admin:ABC_123456@172.17.208.150:554/Streaming/Channels/101?transportmode=unicast"
# 打开摄像头 参数为输入流,可以为摄像头或视频文件
def CatchUsbVideo(out_queue):
process_flag = False
cv2.namedWindow(window_name)
#视频来源,可以来自一段已存好的视频,也可以直接来自USB摄像头
cap = cv2.VideoCapture(videoName)
n = 1
while cap.isOpened():
ok, frame = cap.read() #读取一帧数据
if not ok:
break
#显示图像并等待10毫秒按键输入,输入‘q’退出程序
cv2.namedWindow(window_name, cv2.WINDOW_NORMAL) #cv2.WND_PROP_FULLSCREEN)
#cv2.moveWindow(window_name, screen.x - 1, screen.y - 1)
cv2.setWindowProperty(window_name, cv2.WND_PROP_FULLSCREEN,
cv2.WINDOW_FULLSCREEN)
n = n + 1
if n == 20:
if process_flag == True:
out_queue.put(frame)
n = 1
else:
frameresize = cv2.resize(frame,(1280,800))
cv2.imshow(window_name, frameresize)
c = cv2.waitKey(10)
if c & 0xFF == ord('q'):
break
if c & 0xFF == ord('d'):
process_flag = True
#释放摄像头并销毁所有窗口
cap.release()
cv2.destroyAllWindows()
def FaceDectection(in_queue):
index = 0
while 1:
img = in_queue.get()
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 使用detector进行人脸检测
dets = detector(gray_img, 1)
for i, d in enumerate(dets):
x1 = d.top() if d.top() > 0 else 0
y1 = d.bottom() if d.bottom() > 0 else 0
x2 = d.left() if d.left() > 0 else 0
y2 = d.right() if d.right() > 0 else 0
face = img
# 调整图片的对比度与亮度, 对比度与亮度值都取随机数,这样能增加样本的多样性
#face = relight(face, random.uniform(0.5, 1.5), random.randint(-50, 50))
face = cv2.resize(face, (size,size))
#cv2.imshow('image', face)
cv2.imwrite(output_dir+'/'+str(index)+'.jpg', face)
index += 1
if index == 5:
break
#if __name__ == '__main__':
# CatchUsbVideo()
processes = []
p = Process(target=CatchUsbVideo, args=(results_queue,))
p.start()
processes.append(p)
p = Process(target=FaceDectection, args=(results_queue,))
p.start()
processes.append(p)
for p in processes:
p.join()
while 1:
time.sleep(1)
这样可以获取到视频中出现的人脸,接下来要根据大小做筛选,每一张image只选一个占据主要位置的人脸。
这一步完成后,在用mtcnn做一次筛选,淘汰掉不被认可的图片。
非常棒! 本帖最后由 keer_zu 于 2019-1-16 10:38 编辑
可以获取占主要位置的人脸了:
def FaceDectection(in_queue):
index = 0
while 1:
img = in_queue.get()
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 使用detector进行人脸检测
dets = detector(gray_img, 1)
for i, d in enumerate(dets):
print("----- i:%d\n" % i)
x1 = d.top() if d.top() > 0 else 0
y1 = d.bottom() if d.bottom() > 0 else 0
x2 = d.left() if d.left() > 0 else 0
y2 = d.right() if d.right() > 0 else 0
face = img
if face.shape > 400 :# check picture size
cv2.imwrite(output_dir+'/'+str(index)+'.jpg', face)
index += 1
if index == 5:
break
这样无论在人脸的录入和识别过程中,这一步是必须的,后续再对数据做些处理。继续。。。。。
其中 i 表示在一个画面中得到几个人脸,因为对录入人脸尺寸的限制,录入画面检测到几张脸最终也只会保留不大于一张人脸。
在检测的设备里面,需要适当放宽对尺寸的要求,这就要对不同尺寸做对比了,只处理距离最近的那张,所以人脸的录入和探测还是有些微不同的。
这是工控机传数据到后台服务器,服务器人脸识别吗,表示没学过python,真的是一个行业吗 740071911 发表于 2019-1-17 08:44
这是工控机传数据到后台服务器,服务器人脸识别吗,表示没学过python,真的是一个行业吗 ...
和硬件相关就是一个行业
请问一堆bmp或者jpeg的数据,你怎么提取这堆数据里面的需要的数据?比如一张合照的数据,提取某一个人的数据。 本帖最后由 keer_zu 于 2019-1-17 17:28 编辑
muxb 发表于 2019-1-17 16:58
请问一堆bmp或者jpeg的数据,你怎么提取这堆数据里面的需要的数据?比如一张合照的数据,提取某一个人的数 ...
先检测人脸,就是把人脸部分全部提取出来,然后识别,识别有很多方式,上面提到的facenet采用的是计算欧氏距离来判断是否是同一个人。
def ConvertUseTensorflowMtcnn(in_queue,msg_q):
margin = 32
index_num = 0
target_dir = os.path.join(img_dir,"images_data_%d" % target_img_size)
output_user_dir = os.path.join(target_dir, name)
if not os.path.exists(output_user_dir):
os.makedirs(output_user_dir)
minsize = 30 # minimum size of face
threshold = [ 0.6, 0.7, 0.7 ]# three steps's threshold
factor = 0.709 # scale factor
with tf.Graph().as_default():
gpu_options = tf.GPUOptions(per_process_gpu_memory_fraction=0.25)
sess = tf.Session(config=tf.ConfigProto(gpu_options=gpu_options, log_device_placement=False))
with sess.as_default():
pnet, rnet, onet = detect_face.create_mtcnn(sess, None)
while 1:
file_name = in_queue.get()
print("====== file: %s" % file_name)
img = cv2.imread(file_name)
bounding_boxes, _ = detect_face.detect_face(img, minsize, pnet, rnet, onet, threshold, factor)
print(bounding_boxes)
nrof_faces = bounding_boxes.shape
print(nrof_faces)
if nrof_faces>0:
det = bounding_boxes[:,0:4]
det_arr = []
img_size = np.asarray(img.shape)
print("====nrof_face: %dimg size:"% nrof_faces)
print(img_size)
if nrof_faces == 1:
bounding_box_size = (det[:,2]-det[:,0])*(det[:,3]-det[:,1])
img_center = img_size / 2
offsets = np.vstack([ (det[:,0]+det[:,2])/2-img_center, (det[:,1]+det[:,3])/2-img_center ])
offset_dist_squared = np.sum(np.power(offsets,2.0),0)
index = np.argmax(bounding_box_size-offset_dist_squared*2.0) # some extra weight on the centering
det_arr.append(det)
for i, det in enumerate(det_arr):
det = np.squeeze(det)
bb = np.zeros(4, dtype=np.int32)
bb = np.maximum(det-margin/2, 0)
bb = np.maximum(det-margin/2, 0)
bb = np.minimum(det+margin/2, img_size)
bb = np.minimum(det+margin/2, img_size)
cropped = img:bb,bb:bb,:]
scaled = misc.imresize(cropped, (target_img_size, target_img_size), interp='bilinear')
output_filename = os.path.join(output_user_dir, ("%d" % index_num) +'.png')
filename_base, file_extension = os.path.splitext(output_filename)
output_filename_n = "{}{}".format(filename_base, file_extension)
misc.imsave(output_filename_n, scaled)
index_num += 1
#if os.path.exists(file_name):
#os.remove(file_name)
if index_num >= 5:
msg_q.put("complate_msg")
msg_q.put("complate_msg")
break
给力呀 谢谢分享,很不错的内容 好久没有碰tensorflow了,好久没有碰python了@yyy71cj
页:
[1]