AI 实战2 - face -detect
人脸检测
- 环境
- 安装源设置
- conda 环境安装依赖库
- 概述
- 数据集
- wider_face转yolo
- 环境依赖
- 标注信息格式转换
- 图片处理
- 生成 train.txt 文件
- 数据集展示
- 数据集加载和处理
- 参考文章
环境
安装源设置
conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/
conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/
conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/pytorch/
conda config --set show_channel_urls yes
pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
conda 环境安装依赖库
conda create -n facePay python=3.7
conda activate facePay
conda install pytorch-cpu -c pytorch
#使用conda install pytorch-cpu会快很多
pip3 install torchvision -i https://pypi.tuna.tsinghua.edu.cn/simple
pip install opencv-python -i https://pypi.tuna.tsinghua.edu.cn/simple
pip install bcolz
pip install scikit-learn
pip install tqdm
pip install easydict
概述
人脸检测属于目标检测领域,目标检测领域分两大类:通用目标检测(n+1分类),特定类别目标检测(2分类)
人脸检测算法:Faster-RCNN系列,YOLO系列,级联CNN系列
评价指标:召回率,误检率,检测速度
数据集
yolo 通过txt文件标注,标注内容:0 0.15 0.33 0.14 0.22
对应:类别 归一化后中心点坐标 [x,y,w,h]
wider_face转yolo
环境依赖
# PIL 安装
pip install -U Pillow -i https://pypi.tuna.tsinghua.edu.cn/simple
conda install Pillow
# pip 安装会报错,conda 安装正常
标注信息格式转换
import os
from PIL import Imageparent_path = "/home/ai/wider_face_split/"def convert_to_yolo_format(input_file, output_dir, image_dir):with open(input_file, 'r') as f:lines = f.readlines()i = 0while i < len(lines):image_path = lines[i].strip() # Get the relative path of imagenum_boxes = int(lines[i + 1].strip()) # Get the number of boxes# Path of the label filelabel_path = os.path.join(output_dir, os.path.basename(image_path).replace('.jpg', '.txt'))os.makedirs(os.path.dirname(label_path), exist_ok=True)# Get the Absolute Path of the imageimage_abs_path = os.path.join(image_dir, image_path)# Open the image to get the real size of itwith Image.open(image_abs_path) as img:img_width, img_height = img.size# Create the file and write data inwith open(label_path, 'w') as label_file:for j in range(num_boxes):# Fetch the box data (x_min, y_min, width, height)box_data = list(map(int, lines[i + 2 + j].strip().split()))x_min, y_min, width, height = box_data[:4]# Calculate the center coordinate (x_center, y_center)x_center = (x_min + width / 2)y_center = (y_min + height / 2)# Convert to the relative coordinatesx_center /= img_widthy_center /= img_heightwidth /= img_widthheight /= img_height# The class is defaulted by 0label_file.write(f"0 {x_center} {y_center} {width} {height}\n")# Update the index and jump to the next imagei += 2 + (1 if num_boxes == 0 else num_boxes)if __name__ == "__main__":# Modify the additional section by your own pathinput_path = parent_path+"wider_face_split/"output_path = parent_path+"wider_for_yolo/"input_file_pre = "wider_face_"input_file_sub = "_bbx_gt.txt"if not os.path.exists(output_path):os.makedirs(output_path)# Train and Validationdatasetfile = ["train", "val"]for category in datasetfile:convert_to_yolo_format(input_path + input_file_pre + category + input_file_sub,output_path + category + "/labels",parent_path+f"WIDER_{category}/images")
图片处理
wider_face对不同情景的图片做了分类,YOLO要求训练图片在一个文件夹,因此训练前需要将数据集所有图片copy到一个文件夹下
import os
import shutildef copy_images(src_dir, dest_dir):# 确保目标目录存在if not os.path.exists(dest_dir):os.makedirs(dest_dir)# 递归查找所有图片for root, _, files in os.walk(src_dir):for file in files:if file.lower().endswith(('.jpg', '.jpeg', '.png', '.bmp', '.tiff', '.webp')):src_path = os.path.join(root, file)dest_path = os.path.join(dest_dir, file)# 如果目标文件已存在,可以选择覆盖或跳过if not os.path.exists(dest_path):shutil.copy2(src_path, dest_path) # 保留原文件元数据print(f"Copied: {src_path} -> {dest_path}")else:print(f"Skipped (already exists): {dest_path}")# 配置源文件夹和目标文件夹路径
train_source_folder = r"/home/a/wider_face_split/WIDER_train/images"
train_destination_folder = r"/home/a/wider_face_split/WIDER_train/data"
val_source_folder = r"/home/a/wider_face_split/WIDER_val/images"
val_destination_folder = r"/home/a/wider_face_split/WIDER_val/data"# 执行复制
copy_images(train_source_folder, train_destination_folder)
copy_images(val_source_folder, val_destination_folder)
生成 train.txt 文件
ls -al images/ | awk '{print $NF}' > ../train.txt
数据集展示
import cv2
import os
import numpy as npif __name__ == "__main__":# 第一步:指定文件路径root_path ='/home/neucore/develop/code/pre_research/dl/face_ai/study/yoloDataset/train/images/'path = '/home/neucore/develop/code/pre_research/dl/face_ai/study/yoloDataset/train.txt'path_voc_names = '/home/neucore/develop/code/pre_research/dl/face_ai/study/yoloDataset/face.names'# 第二步:获取目标类别with open(path_voc_names ,'r') as f:lable_map = f.readlines()for i in range(len(lable_map)):lable_map[i] = lable_map[i].strip()print(i, lable_map[i])# 第三步:获取图像数据和标注信息with open(path ,'r') as file:img_files = file.readlines()# img_files = os.path.join(root_path, img_files[i][0:])for i in range(len(img_files)):img_files[i] = img_files[i].strip()# 图像的绝对路径, [0:]表示去掉多少个字节,[2:]表示去掉前两个字符img_files[i] = os.path.join(root_path, img_files[i][0:])# print(i, img_files[i])label_files = [x.replace('images','labels').replace ('.jpg','.txt') for x in img_files]# print(label_files)#第四步:将标注信息给制在图像上#读取图像并对标注信息进行绘# for i in range(len(img_files)):for i in range (3):print (img_files[i])# 图像读取,获取宽高img =cv2.imread(img_files[i])if img is None:print("Error: Image not found or path is incorrect.")w = img.shape[1]h = img.shape[0]# 标签文件的绝对路径print(i, label_files[i])if os.path.isfile(label_files[i]):# 获取每一行的标注信息with open(label_files[i], 'r') as file:lines = file.read().splitlines()# 获取每一行的标准信息(class,x,y,w,h)x = np.array([x.split() for x in lines], dtype=np.float32)for k in range(len(x)):anno = x[k]label = int(anno[0])# 获取框的坐标值,左上角坐标和右下角坐标x1 = int((float(anno[1]) - float(anno[3])/2) * w)y1 = int((float(anno[2]) - float(anno[4])/2) * h)x2 = int((float(anno[1]) + float(anno[3])/2) * w)y2 = int((float(anno[2]) + float(anno[4])/2) * h)# 将标注框绘制在图像上cv2.rectangle(img, (x1,y1), (x2,y2), (255,30,30), 2)# 将标注类别绘制在图像上cv2.putText(img, ("%s"%(str(lable_map[label]))), (x1,y1),cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0,255,0), 1)cv2.imshow('img', img)cv2.waitKey()# if cv2.waitKey(1) == 27:# breakcv2.destroyAllWindows()
数据集加载和处理
参考文章
WIDER FACE数据集转YOLO格式
相关文章:
AI 实战2 - face -detect
人脸检测 环境安装源设置conda 环境安装依赖库 概述数据集wider_face转yolo环境依赖标注信息格式转换图片处理生成 train.txt 文件 数据集展示数据集加载和处理 参考文章 环境 安装源设置 conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/f…...
Spring Boot 项目开发流程全解析
目录 引言 一、开发环境准备 二、创建项目 三、项目结构 四、开发业务逻辑 1.创建实体类: 2.创建数据访问层(DAO): 3.创建服务层(Service): 4.创建控制器层(Controller&…...
从Java到MySQL8源码:深入解析PreparedStatement参数绑定与执行机制
引言 在数据库开发中,PreparedStatement(预处理语句)是防止SQL注入、提升性能的重要工具。它通过分离SQL结构与参数值,不仅增强了安全性,还能利用预编译优化执行效率。本文将从Java JDBC驱动和MySQL 8源码的双重视角&…...
mysql的主从同步
1、异步复制:这是MySQL默认的复制模式。在这种模式下,主库在执行完客户端提交的事务后会立即将结果返回给客户端,并不关心从库是否已经接收并处理。这种模式的优点是实现简单,但缺点是如果主库崩溃,已经提交的事务可能…...
工程化与框架系列(10)--微前端架构
微前端架构 🏗️ 微前端是一种将前端应用分解成更小、更易管理的独立部分的架构模式。本文将详细介绍微前端的核心概念、实现方案和最佳实践。 微前端概述 🌟 💡 小知识:微前端的核心理念是将前端应用分解成一系列独立部署、松耦…...
【3天快速入门WPF】11-附加属性
目录 1. 步骤1:定义附加属性2. 示例代码3. 步骤2:在XAML中使用附加属性3.1. 示例代码4. 步骤3:扩展使用场景4.1. 示例代码5. 总结上一篇讲到了依赖属性,本篇主要想说一下附加属性。 在WPF中,附加属性(Attached Property)是一种特殊的依赖属性,允许你在不属于某个类的控…...
MySQL并发知识(面试高频)
mysql并发事务解决 不同隔离级别下,mysql解决并发事务的方式不同。主要由锁机制和MVCC(多版本并发控制)机制来解决并发事务问题。 1. mysql中的锁有哪些? 表级锁: 场景:表级锁适用于需要对整个表进行操作的情况,例如…...
现存脑容知识库
Redis import queue import threading import asyncio 异步:在一个线程内,等待的时候可以切换到其他任务。 多线程:每个线程独立运行,同时处理多个任务。 回调函数 网络请求(JavaScript)在浏览器中&a…...
Mysql-如何理解事务?
一、事务是什么东西 有些场景中,某个操作需要多个sql配合完成: 例如: 李四这个月剩下的前不够交房租了,找张三借1000元急用: (1)给张三的账户余额 减去1000元 updata 账户表 set money money -…...
dify绑定飞书多维表格
dify 绑定飞书和绑定 notion 有差不多的过程,都需要套一层应用的壳子,而没有直接可以访问飞书文档的 API。本文记录如何在dify工具中使用新增多条记录工具。 创建飞书应用 在飞书开放平台创建一个应用,个人用户创建企业自建应用。 自定义应…...
QT播放视频保持视频宽高比消除黑边
QT播放视频保持视频宽高比消除黑边 1、问题 在播放视频的时候,由于框架的大小发生变化,导致视频出现黑边很不好看。 因此需要像一种方法消除黑边 2、处理 1、读取视频的宽高比 2、设置视频的Widget的大小固定,Widget的宽高比和视频宽高比…...
1. IO的基础知识
1.1 流 Java程序通过流执行IO。流是一种抽象,它要么生成信息,要么使用信息。流通过java的IO系统链接到物理设备。所有流的行为方式都是相同的,尽管它们链接的物理设备是不同的。 1.2 字节流和字符流 Java定义了两种类型的流 : 字节流和字符流…...
科普:ROC AUC与PR AUC
在评价二分类模型性能时,有许多评价指标,其中,有一对是用面积AUC(Area Under the Curve)做评价的:ROC AUC与PR AUC 本文我们对ROC AUC与PR AUC进行多维度对比分析: 一、定义与核心原理 维度RO…...
Vue3父组件访问子组件方法与属性完全指南
在Vue3的组件化开发中,父子组件间的通信是核心功能之一。本文将详细介绍五种父组件访问子组件属性/方法的实现方案,包含最新的<script setup>语法糖实践。(综合1579) 一、ref defineExpose(推荐方案࿰…...
AI时代保护自己的隐私
人工智能最重要的就是数据,让我们面对现实,大多数人都不知道他们每天要向人工智能提供多少数据。你输入的每条聊天记录,你发出的每条语音命令,人工智能生成的每张图片、电子邮件和文本。我建设了一个网站(haptool.com),…...
Android APK组成编译打包流程详解
Android APK(Android Package)是 Android 应用的安装包文件,其组成和打包流程涉及多个步骤和文件结构。以下是详细的说明: 一、APK 的组成 APK 是一个 ZIP 格式的压缩包,包含应用运行所需的所有文件。解压后主要包含以…...
TCP长连接与短连接
TCP长连接与短连接 TCP(传输控制协议)中的长连接和短连接是两种不同的连接管理方式,各有优缺点: 短连接 短连接是指客户端与服务器完成一次数据交换后就断开连接。下次需要通信时,再重新建立连接。 特点࿱…...
C#委托(delegate)的常用方式
C# 中委托的常用方式,包括委托的定义、实例化、不同的赋值方式以及匿名委托的使用。 委托的定义 // 委托的核心是跟委托的函数结构一样 public delegate string SayHello(string c);public delegate string SayHello(string c);:定义了一个公共委托类型 …...
C#从入门到精通(35)—如何防止winform程序因为误操作被关闭
前言: 大家好,我是上位机马工,硕士毕业4年年入40万,目前在一家自动化公司担任软件经理,从事C#上位机软件开发8年以上!我们在开发的上位机软件运行起来以后,一般在右上角都有一个关闭按钮,正常情况下点击关闭按钮就能关闭软件,但是不排除我们不想关闭软件,但是因为不…...
docker本地镜像源搭建
最近Deepseek大火后,接到任务就是帮客户装Dify,每次都头大,因为docker源不能用,实在没办法,只好自己搭要给本地源。话不多说具体如下: 1、更改docker的配置文件,添加自己的私库地址,…...
【Axure高保真原型】引导弹窗
今天和大家中分享引导弹窗的原型模板,载入页面后,会显示引导弹窗,适用于引导用户使用页面,点击完成后,会显示下一个引导弹窗,直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...
变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析
一、变量声明设计:let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性,这种设计体现了语言的核心哲学。以下是深度解析: 1.1 设计理念剖析 安全优先原则:默认不可变强制开发者明确声明意图 let x 5; …...
以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:
一、属性动画概述NETX 作用:实现组件通用属性的渐变过渡效果,提升用户体验。支持属性:width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项: 布局类属性(如宽高)变化时&#…...
Java 8 Stream API 入门到实践详解
一、告别 for 循环! 传统痛点: Java 8 之前,集合操作离不开冗长的 for 循环和匿名类。例如,过滤列表中的偶数: List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...
Oracle查询表空间大小
1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...
搭建DNS域名解析服务器(正向解析资源文件)
正向解析资源文件 1)准备工作 服务端及客户端都关闭安全软件 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 2)服务端安装软件:bind 1.配置yum源 [rootlocalhost ~]# cat /etc/yum.repos.d/base.repo [Base…...
三分算法与DeepSeek辅助证明是单峰函数
前置 单峰函数有唯一的最大值,最大值左侧的数值严格单调递增,最大值右侧的数值严格单调递减。 单谷函数有唯一的最小值,最小值左侧的数值严格单调递减,最小值右侧的数值严格单调递增。 三分的本质 三分和二分一样都是通过不断缩…...
Golang——9、反射和文件操作
反射和文件操作 1、反射1.1、reflect.TypeOf()获取任意值的类型对象1.2、reflect.ValueOf()1.3、结构体反射 2、文件操作2.1、os.Open()打开文件2.2、方式一:使用Read()读取文件2.3、方式二:bufio读取文件2.4、方式三:os.ReadFile读取2.5、写…...
Python 实现 Web 静态服务器(HTTP 协议)
目录 一、在本地启动 HTTP 服务器1. Windows 下安装 node.js1)下载安装包2)配置环境变量3)安装镜像4)node.js 的常用命令 2. 安装 http-server 服务3. 使用 http-server 开启服务1)使用 http-server2)详解 …...
Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement
Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement 1. LAB环境2. L2公告策略2.1 部署Death Star2.2 访问服务2.3 部署L2公告策略2.4 服务宣告 3. 可视化 ARP 流量3.1 部署新服务3.2 准备可视化3.3 再次请求 4. 自动IPAM4.1 IPAM Pool4.2 …...
