TensorFlow23: “恶作剧” --人脸检测

2024-05-07 15:38

本文主要是介绍TensorFlow23: “恶作剧” --人脸检测,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前面有一个帖《OpenCV检测场景内是否有移动物体》我用树莓派做了一个简单的Motion Detection,放在卫生间的,它会在我上大号时自动播放音乐。

我一个人租房,几个盆友周末时常会找我玩,他们觉得我做的Motion Detection很垃圾。于是我就想恶搞一下,用TensorFlow做一个“人脸识别”,在我上大号时播放音乐,如果是别人就播放《张震讲鬼故事》(@xingCI说放屁声更搞)。

我的任务的训练一个模型可以区分“我”和“其它人”的脸。注意,上面“人脸识别”我是加引号的,其实并不是真正的人脸识别,充其量就是个图像分类。如果你要使用真正的人脸识别,可以试试现成的库OpenFace+dlib《使用OpenFace进行人脸识别》。

有人已经把TensorFlow移植到了树莓派,项目地址tensorflow-on-raspberry-pi。

准备数据

本帖需要使用到两组数据:一组是包含我脸的图像,另一组包含其它人人脸的图像。

其它人人脸的收集

找一堆图片,只要不包含自己就行,然后使用OpenCV提取图像中的大脸。

提取图像中的人脸,我使用OpenCV,据说使用dlib效果更好。

other_peoples_faces.py:

[python] view plain copy 在CODE上查看代码片 派生到我的代码片
  1. import cv2  
  2. import os  
  3. import sys  
  4.    
  5. IMAGE_DIR = '图片目录路径'  
  6.    
  7. OUTPUT_DIR = './other_people'  
  8. if not os.path.exists(OUTPUT_DIR):  
  9.     os.makedirs(OUTPUT_DIR)  
  10.    
  11. # http://blog.topspeedsnail.com/archives/10511  
  12. # wget https://raw.githubusercontent.com/opencv/opencv/master/data/haarcascades/haarcascade_frontalface_default.xml  
  13. face_haar = cv2.CascadeClassifier("haarcascade_frontalface_default.xml")  
  14.    
  15. for (dirpath, dirnames, filenames) in os.walk(IMAGE_DIR):  
  16.     for filename in filenames:  
  17.         if filename.endswith('.jpg'):  
  18.             image_path = os.path.join(dirpath, filename)  
  19.             print('process: ', image_path)  
  20.             img = cv2.imread(image_path)  
  21.               
  22.             gray_image = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)  
  23.             faces = face_haar.detectMultiScale(gray_image, 1.35)  
  24.             for face_x,face_y,face_w,face_h in faces:  
  25.                 face = img[face_y:face_y+face_h, face_x:face_x+face_w]  
  26.    
  27.                 face = cv2.resize(face, (6464))  
  28.    
  29.                 cv2.imshow("img", face)  
  30.                 cv2.imwrite(os.path.join(OUTPUT_DIR, filename), face)  
  31.    
  32.             key = cv2.waitKey(30) & 0xff  
  33.             if key == 27:  
  34.                 sys.exit(0)  

TensorFlow练习23: '恶作剧'

4万多图片,我只提取了1万张脸,应该够使了。

TensorFlow练习23: '恶作剧'图像大小 64×64

TensorFlow练习23: '恶作剧'

上面是OpenCV做的人脸检测,有了这个数据集又可以反过来训练TensorFlow版本的人脸检测。

斗大熊的脸

给自己拍照1万张,这是我一次拍照最多的一回。

[python] view plain copy 在CODE上查看代码片 派生到我的代码片
  1. import cv2  
  2. import os  
  3. import sys  
  4.    
  5. OUTPUT_DIR = './my_faces'  
  6. if not os.path.exists(OUTPUT_DIR):  
  7.     os.makedirs(OUTPUT_DIR)  
  8.    
  9. face_haar = cv2.CascadeClassifier("haarcascade_frontalface_default.xml")  
  10.    
  11. cam = cv2.VideoCapture(0)  
  12.    
  13. count = 0  
  14. while True:  
  15.     print(count)  
  16.     if count < 10000:  
  17.         _, img = cam.read()  
  18.    
  19.         gray_image = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)  
  20.         faces = face_haar.detectMultiScale(gray_image, 1.35)  
  21.         for face_x,face_y,face_w,face_h in faces:  
  22.             face = img[face_y:face_y+face_h, face_x:face_x+face_w]  
  23.    
  24.             face = cv2.resize(face, (6464))  
  25.             cv2.imshow('img', face)  
  26.             cv2.imwrite(os.path.join(OUTPUT_DIR, str(count)+'.jpg'), face)  
  27.             count += 1  
  28.         key = cv2.waitKey(30) & 0xff  
  29.         if key == 27:  
  30.             break  
  31.     else:  
  32.         break  

在镜头前摇头晃脑、摆pose,戴眼镜、耳机,仰天45,写代码,呲牙咧嘴,玩手机。。。一定要多样化,直到拍1万张大脸。

训练模型

训练数据有了,下面开始训练。

[python] view plain copy 在CODE上查看代码片 派生到我的代码片
  1. import tensorflow as tf  
  2. import cv2  
  3. import numpy as np  
  4. import os  
  5. from sklearn.model_selection import train_test_split  
  6. import random  
  7. import sys  
  8.    
  9. my_image_path = 'my_faces'  
  10. others_image_path = 'other_people'  
  11.    
  12. image_data = []  
  13. label_data = []  
  14.    
  15. def get_padding_size(image):  
  16.     h, w, _ = image.shape  
  17.     longest_edge = max(h, w)  
  18.     top, bottom, left, right = (0000)  
  19.     if h < longest_edge:  
  20.         dh = longest_edge - h  
  21.         top = dh // 2  
  22.         bottom = dh - top  
  23.     elif w < longest_edge:  
  24.         dw = longest_edge - w  
  25.         left = dw // 2  
  26.         right = dw - left  
  27.     else:  
  28.         pass  
  29.     return top, bottom, left, right  
  30.    
  31. def read_data(img_path, image_h=64, image_w=64):  
  32.     for filename in os.listdir(img_path):  
  33.         if filename.endswith('.jpg'):  
  34.             filepath = os.path.join(img_path, filename)  
  35.             image = cv2.imread(filepath)  
  36.    
  37.             top, bottom, left, right = get_padding_size(image)  
  38.             image_pad = cv2.copyMakeBorder(image, top , bottom, left, right, cv2.BORDER_CONSTANT, value=[000])  
  39.             image = cv2.resize(image_pad, (image_h, image_w))  
  40.    
  41.             image_data.append(image)  
  42.             label_data.append(img_path)  
  43.    
  44. read_data(others_image_path)  
  45. read_data(my_image_path)  
  46.    
  47. image_data = np.array(image_data)  
  48. label_data = np.array([[0,1if label == 'my_faces' else [1,0for label in label_data])  
  49.    
  50. train_x, test_x, train_y, test_y = train_test_split(image_data, label_data, test_size=0.05, random_state=random.randint(0100))  
  51.    
  52. # image (height=64 width=64 channel=3)  
  53. train_x = train_x.reshape(train_x.shape[0], 64643)  
  54. test_x = test_x.reshape(test_x.shape[0], 64643)  
  55.    
  56. # nomalize  
  57. train_x = train_x.astype('float32') / 255.0  
  58. test_x = test_x.astype('float32') / 255.0  
  59.    
  60. print(len(train_x), len(train_y))  
  61. print(len(test_x), len(test_y))  
  62.    
  63. #############################################################  
  64. batch_size = 128  
  65. num_batch = len(train_x) // batch_size  
  66.    
  67. X = tf.placeholder(tf.float32, [None64643])  # 图片大小64x64 channel=3  
  68. Y = tf.placeholder(tf.float32, [None2])  
  69.    
  70. keep_prob_5 = tf.placeholder(tf.float32)  
  71. keep_prob_75 = tf.placeholder(tf.float32)  
  72.    
  73. def panda_joke_cnn():  
  74.    
  75.     W_c1 = tf.Variable(tf.random_normal([33332], stddev=0.01))  
  76.     b_c1 = tf.Variable(tf.random_normal([32]))  
  77.     conv1 = tf.nn.relu(tf.nn.bias_add(tf.nn.conv2d(X, W_c1, strides=[1111], padding='SAME'), b_c1))  
  78.     conv1 = tf.nn.max_pool(conv1, ksize=[1221], strides=[1221], padding='SAME')  
  79.     conv1 = tf.nn.dropout(conv1, keep_prob_5)  
  80.    
  81.     W_c2 = tf.Variable(tf.random_normal([333264], stddev=0.01))  
  82.     b_c2 = tf.Variable(tf.random_normal([64]))  
  83.     conv2 = tf.nn.relu(tf.nn.bias_add(tf.nn.conv2d(conv1, W_c2, strides=[1111], padding='SAME'), b_c2))  
  84.     conv2 = tf.nn.max_pool(conv2, ksize=[1221], strides=[1221], padding='SAME')  
  85.     conv2 = tf.nn.dropout(conv2, keep_prob_5)  
  86.    
  87.     W_c3 = tf.Variable(tf.random_normal([336464], stddev=0.01))  
  88.     b_c3 = tf.Variable(tf.random_normal([64]))  
  89.     conv3 = tf.nn.relu(tf.nn.bias_add(tf.nn.conv2d(conv2, W_c3, strides=[1111], padding='SAME'), b_c3))  
  90.     conv3 = tf.nn.max_pool(conv3, ksize=[1221], strides=[1221], padding='SAME')  
  91.     conv3 = tf.nn.dropout(conv3, keep_prob_5)  
  92.    
  93.     # Fully connected layer  
  94.     W_d = tf.Variable(tf.random_normal([8*16*32512], stddev=0.01))  
  95.     b_d = tf.Variable(tf.random_normal([512]))  
  96.     dense = tf.reshape(conv3, [-1, W_d.get_shape().as_list()[0]])  
  97.     dense = tf.nn.relu(tf.add(tf.matmul(dense, W_d), b_d))  
  98.     dense = tf.nn.dropout(dense, keep_prob_75)  
  99.    
  100.     W_out = tf.Variable(tf.random_normal([5122], stddev=0.01))  
  101.     b_out = tf.Variable(tf.random_normal([2]))  
  102.     out = tf.add(tf.matmul(dense, W_out), b_out)  
  103.     return out  
  104.    
  105. def train_cnn():  
  106.     output = panda_joke_cnn()  
  107.    
  108.     loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(output, Y))  
  109.     optimizer = tf.train.AdamOptimizer(learning_rate=0.001).minimize(loss)  
  110.    
  111.     accuracy = tf.reduce_mean(tf.cast(tf.equal(tf.argmax(output, 1), tf.argmax(Y, 1)), tf.float32))  
  112.    
  113.     tf.summary.scalar("loss", loss)  
  114.     tf.summary.scalar("accuracy", accuracy)  
  115.     merged_summary_op = tf.summary.merge_all()  
  116.    
  117.     saver = tf.train.Saver()  
  118.     with tf.Session() as sess:  
  119.         sess.run(tf.global_variables_initializer())  
  120.    
  121.         summary_writer = tf.summary.FileWriter('./log', graph=tf.get_default_graph())  
  122.    
  123.         for e in range(50):  
  124.             for i in range(num_batch):  
  125.                 batch_x = train_x[i*batch_size : (i+1)*batch_size]  
  126.                 batch_y = train_y[i*batch_size : (i+1)*batch_size]  
  127.                 _, loss_, summary = sess.run([optimizer, loss, merged_summary_op], feed_dict={X: batch_x, Y: batch_y, keep_prob_5:0.5, keep_prob_75: 0.75})  
  128.    
  129.                 summary_writer.add_summary(summary, e*num_batch+i)  
  130.                 print(e*num_batch+i, loss_)  
  131.    
  132.                 if (e*num_batch+i) % 100 == 0:  
  133.                     acc = accuracy.eval({X: test_x, Y: test_y, keep_prob_5:1.0, keep_prob_75: 1.0})  
  134.                     print(e*num_batch+i, acc)  
  135.                     # save model  
  136.                     if acc > 0.98:  
  137.                         saver.save(sess, "i_am_a_joke.model", global_step=e*num_batch+i)  
  138.                         sys.exit(0)  
  139.    
  140. train_cnn()  

准确率曲线:

TensorFlow练习23: '恶作剧'

下面要做的就是在树莓派上使用模型,代码示例:

[python] view plain copy 在CODE上查看代码片 派生到我的代码片
  1. output = panda_joke_cnn()  
  2. predict = tf.argmax(output, 1)  
  3.    
  4. saver = tf.train.Saver()  
  5. sess = tf.Session()  
  6. saver.restore(sess, tf.train.latest_checkpoint('.'))  
  7.    
  8. def is_my_face(image):  
  9.     res = sess.run(predict, feed_dict={X: [image/255.0], keep_prob_5:1.0, keep_prob_75: 1.0})  
  10.     if res[0] == 1:  
  11.         return True  
  12.     else:  
  13.         return False  
  14.    
  15. face_haar = cv2.CascadeClassifier("haarcascade_frontalface_default.xml")  
  16. cam = cv2.VideoCapture(0)  
  17.    
  18. while True:  
  19.     _, img = cam.read()  
  20.     gray_image = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)  
  21.     faces = face_haar.detectMultiScale(gray_image, 1.35)  
  22.     for face_x,face_y,face_w,face_h in faces:  
  23.         face = img[face_y:face_y+face_h, face_x:face_x+face_w]  
  24.    
  25.         face = cv2.resize(face, (6464))  
  26.    
  27.         print(is_my_face(face))  
  28.    
  29.         cv2.imshow('img', face)  
  30.         key = cv2.waitKey(30) & 0xff  
  31.         if key == 27:  
  32.             sys.exit(0)  
  33.    
  34. sess.close()  

总结:占用内存100多M,准确率还凑合,先用着。


这篇关于TensorFlow23: “恶作剧” --人脸检测的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/967764

相关文章

综合安防管理平台LntonAIServer视频监控汇聚抖动检测算法优势

LntonAIServer视频质量诊断功能中的抖动检测是一个专门针对视频稳定性进行分析的功能。抖动通常是指视频帧之间的不必要运动,这种运动可能是由于摄像机的移动、传输中的错误或编解码问题导致的。抖动检测对于确保视频内容的平滑性和观看体验至关重要。 优势 1. 提高图像质量 - 清晰度提升:减少抖动,提高图像的清晰度和细节表现力,使得监控画面更加真实可信。 - 细节增强:在低光条件下,抖

烟火目标检测数据集 7800张 烟火检测 带标注 voc yolo

一个包含7800张带标注图像的数据集,专门用于烟火目标检测,是一个非常有价值的资源,尤其对于那些致力于公共安全、事件管理和烟花表演监控等领域的人士而言。下面是对此数据集的一个详细介绍: 数据集名称:烟火目标检测数据集 数据集规模: 图片数量:7800张类别:主要包含烟火类目标,可能还包括其他相关类别,如烟火发射装置、背景等。格式:图像文件通常为JPEG或PNG格式;标注文件可能为X

基于 YOLOv5 的积水检测系统:打造高效智能的智慧城市应用

在城市发展中,积水问题日益严重,特别是在大雨过后,积水往往会影响交通甚至威胁人们的安全。通过现代计算机视觉技术,我们能够智能化地检测和识别积水区域,减少潜在危险。本文将介绍如何使用 YOLOv5 和 PyQt5 搭建一个积水检测系统,结合深度学习和直观的图形界面,为用户提供高效的解决方案。 源码地址: PyQt5+YoloV5 实现积水检测系统 预览: 项目背景

JavaFX应用更新检测功能(在线自动更新方案)

JavaFX开发的桌面应用属于C端,一般来说需要版本检测和自动更新功能,这里记录一下一种版本检测和自动更新的方法。 1. 整体方案 JavaFX.应用版本检测、自动更新主要涉及一下步骤: 读取本地应用版本拉取远程版本并比较两个版本如果需要升级,那么拉取更新历史弹出升级控制窗口用户选择升级时,拉取升级包解压,重启应用用户选择忽略时,本地版本标志为忽略版本用户选择取消时,隐藏升级控制窗口 2.

[数据集][目标检测]血细胞检测数据集VOC+YOLO格式2757张4类别

数据集格式:Pascal VOC格式+YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数):2757 标注数量(xml文件个数):2757 标注数量(txt文件个数):2757 标注类别数:4 标注类别名称:["Platelets","RBC","WBC","sickle cell"] 每个类别标注的框数:

Temu官方宣导务必将所有的点位材料进行检测-RSL资质检测

关于饰品类产品合规问题宣导: 产品法规RSL要求 RSL测试是根据REACH法规及附录17的要求进行测试。REACH法规是欧洲一项重要的法规,其中包含许多对化学物质进行限制的规定和高度关注物质。 为了确保珠宝首饰的安全性,欧盟REACH法规规定,珠宝首饰上架各大电商平台前必须进行RSLReport(欧盟禁限用化学物质检测报告)资质认证,以确保产品不含对人体有害的化学物质。 RSL-铅,

YOLOv8/v10+DeepSORT多目标车辆跟踪(车辆检测/跟踪/车辆计数/测速/禁停区域/绘制进出线/绘制禁停区域/车道车辆统计)

01:YOLOv8 + DeepSort 车辆跟踪 该项目利用YOLOv8作为目标检测模型,DeepSort用于多目标跟踪。YOLOv8负责从视频帧中检测出车辆的位置,而DeepSort则负责关联这些检测结果,从而实现车辆的持续跟踪。这种组合使得系统能够在视频流中准确地识别并跟随特定车辆。 02:YOLOv8 + DeepSort 车辆跟踪 + 任意绘制进出线 在此基础上增加了用户

独立按键单击检测(延时消抖+定时器扫描)

目录 独立按键简介 按键抖动 模块接线 延时消抖 Key.h Key.c 定时器扫描按键代码 Key.h Key.c main.c 思考  MultiButton按键驱动 独立按键简介 ​ 轻触按键相当于一种电子开关,按下时开关接通,松开时开关断开,实现原理是通过轻触按键内部的金属弹片受力弹动来实现接通与断开。  ​ 按键抖动 由于按键内部使用的是机

基于stm32的河流检测系统-单片机毕业设计

文章目录 前言资料获取设计介绍功能介绍具体实现截图参考文献设计获取 前言 💗博主介绍:✌全网粉丝10W+,CSDN特邀作者、博客专家、CSDN新星计划导师,一名热衷于单片机技术探索与分享的博主、专注于 精通51/STM32/MSP430/AVR等单片机设计 主要对象是咱们电子相关专业的大学生,希望您们都共创辉煌!✌💗 👇🏻 精彩专栏 推荐订阅👇🏻 单片机设计精品

Android模拟器的检测

Android模拟器的检测 需求:最近有一个需求,要检测出模拟器,防止恶意刷流量刷注册。 1.基于特征属性来检测模拟器,比如IMSI,IDS,特殊文件等等。 这个方案局限性太大,貌似现在大部分模拟器默认就是修改了的,还不需要人为的去修改。 经过测试,发现如下图所示。 如果是模拟器的话,这些特殊值应该返回true,比如DeviceIDS,Build。可是居然返回了false,说明特殊值