基于opencv+ImageAI+tensorflow的智能动漫人物识别系统——深度学习算法应用(含python、JS、模型源码)+数据集(三)

目录

  • 前言
  • 总体设计
    • 系统整体结构图
    • 系统流程图
  • 运行环境
    • 爬虫
    • 模型训练
    • 实际应用
  • 模块实现
    • 1. 数据准备
      • 1)爬虫下载原始图片
      • 2)手动筛选图片
    • 2. 数据处理
      • 1)切割得到人物脸部
      • 2)重新命名处理后的图片
      • 3)添加到数据集
    • 3. 模型训练及保存
      • 1)设置基本参数
      • 2)模型保存
      • 3)模块预测
  • 相关其它博客
  • 工程源代码下载
  • 其它资料下载


在这里插入图片描述

前言

本项目通过爬虫技术获取图片,利用OpenCV库对图像进行处理,识别并切割出人物脸部,形成了一个用于训练的数据集。通过ImageAI进行训练,最终实现了对动漫人物的识别模型。同时,本项目还开发了一个线上Web应用,使得用户可以方便地体验和使用该模型。

首先,项目使用爬虫技术从网络上获取图片。这些图片包含各种动漫人物,其中我们只对人物脸部进行训练,所以我们会对图像进行处理,并最终将这些图像将作为训练数据的来源。

其次,利用OpenCV库对这些图像进行处理,包括人脸检测、图像增强等步骤,以便准确识别并切割出人物脸部。这一步是为了构建一个清晰而准确的数据集,用于模型的训练。

接下来,通过ImageAI进行训练。ImageAI是一个简化图像识别任务的库,它可以方便地用于训练模型,这里用于训练动漫人物的识别模型。

最终,通过项目开发的线上Web应用,用户可以上传动漫图像,系统将使用训练好的模型识别图像中的动漫人物,并返回相应的结果。

总的来说,本项目结合了爬虫、图像处理、深度学习和Web开发技术,旨在提供一个便捷的动漫人物识别服务。这对于动漫爱好者、社交媒体平台等有着广泛的应用前景。

总体设计

本部分包括系统整体结构图和系统流程图。

系统整体结构图

系统整体结构如图所示。

在这里插入图片描述

系统流程图

系统流程如图所示。

在这里插入图片描述

运行环境

本部分包括爬虫、模型训练及实际应用运行环境。

爬虫

安装Python3.6以上及Selenium3.0.2版本。

详见博客。

模型训练

本部分包括安装依赖、安装ImageAI。

详见博客。

实际应用

实际应用包括前端开发环境和后端环境的搭建。

详见博客。

模块实现

本项目包括4个模块:数据准备、数据处理、模型训练及保存、模型测试,下面分别介绍各模块的功能及相关代码。

1. 数据准备

本项目的数据来自于百度图片,通过爬虫获取。

1)爬虫下载原始图片

详见博客。

2)手动筛选图片

部分人物的名称、现实事物或人物有重名现象,加上一些图片质量不佳,需要人为剔除,手动筛选。

详见博客。

2. 数据处理

将图片中的人脸裁剪进行模型训练,切割人脸部分由OpenCV通过训练好的动漫人物脸部识别模型lbpcascade_animeface截取人物脸部。GitHub下载地址为https://github.com/nagadomi/lbpcascade_animeface。

1)切割得到人物脸部

相关代码如下:

#基本参数设定
SRC = "Raw"    #待处理的文件路径
DST = "Data"   #处理后的文件路径
TRAIN_PER = 5  #训练的图片比例
TEST_PER = 1   #测试的图片比例
#处理原图片得到人物脸部图片并按比例分配训练和测试用于训练模型
for image_file in files:  #读取所有图片
     image_file = image_file.replace('\\', '/')  #解决Windows下的文件路径问题
      target_path = "/".join(image_file.strip("/").split('/')[1:-1])
      target_path = os.path.join(dst, target_path) + "/"
      if not os.path.exists(target_path):
            os.makedirs(target_path)
count = len(os.listdir(target_path)) + 1
image = cv2.imdecode(np.fromfile(image_file, dtype=np.uint8), -1)  
#解决中文路径读入图片问题
      gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)  #OpenCV的设置
      gray = cv2.equalizeHist(gray)  #转化为灰度图片
      faces = cascade.detectMultiScale(gray,
          scaleFactor=1.05,  #指定每个图像缩放比例,缩小图像大小的参数
          minNeighbors=4,    #此参数将影响检测到的面孔,值越高,检测结果越少,质量越好
          minSize=(24, 24)   #最小对象大小或者小于此值的对象将被忽略
        for (x, y, w, h) in faces:
            crop_img = image[y:y + h, x:x + w]
            crop_img = cv2.resize(crop_img, (96, 96))  #重置为96*96
            filename = os.path.basename(image_file).split('.')[0]   cv2.imencode('.jpg',crop_img)[1].tofile(os.path.join(target_path, str(count) + ".jpg")) #保存切割的脸部

处理前和处理后的效果如图所示。

在这里插入图片描述

处理前图片

在这里插入图片描述

处理后图片

2)重新命名处理后的图片

对于处理后的图片,需要重新指定文件名称以便于统计和处理。相关代码如下:

def rename_files(dir, prefix='', joiner='_', startNum=0,
                 changeType='', ignoreType='', typeOnly=''):
    '''重命名一个文件夹中的所有文件
    Args:
        dir(string):  重命名文件夹的路径
        prefix(string):  文件名前缀
        joiner(string):  连接文件名前缀和数字的连接符,默认为下划线
        startNum(int):  重命名文件的开始数字,默认为0
        changeType(string):  把文件重命名为指定类型,默认不指定类型
        typeOnly(string):  只处理指定类型的文件,使用空格分割,例如“.jpg .jpeg .png .bmp .webp”
        ignoreType(string):  忽略处理文件的类型,使用空格分割,例如,“.py .docx”
    '''
    for root, _, files in os.walk(dir):
        root = root.replace('\\', '/')
        if prefix == '':
            prefix = root.split('/')[-1]
        count = startNum
        for file in files:
            true_type = os.path.splitext(file)[-1]  #文件真实类型
            type_list = typeOnly.split()
            ignore_list = ignoreType.split()
            if true_type in type_list or len(type_list) == 0:
                if true_type in ignore_list:
                    continue
                if changeType == '':  #是否指定改变类型
                    file_type = true_type
                else:
                    file_type = changeType
                new_name = "{}{}{}{}".format(
                    prefix, joiner, str(count), file_type)
                path = os.path.join(root, new_name)
                old_path = os.path.join(root, file)
                if old_path == path:
                    continue
                if not os.path.exists(path):
                    os.rename(old_path, path)
                    count = count + 1
def main():
    parser = argparse.ArgumentParser(description="重命名指定文件夹下的所有文件")
    parser.add_argument("dir", type=str, help="重命名文件的路径")
    parser.add_argument("--prefix", "-p", type=str,
                        default='', help="前缀,默认为文件名")
    parser.add_argument("--joiner", "-j", type=str, default="_", help="连接符")
    parser.add_argument("--startNum", "-s", type=int, default=0, help="开始数")
    parser.add_argument("--changeType", "-c", type=str,
                        default='', help="重命名文件为指定类型")
    parser.add_argument("--ignoreType", "-i", type=str,
                        default='', help="忽略处理的类型,使用空格分割")
    parser.add_argument("--typeOnly", "-t", type=str,
                        default='', help="指定处理的类型,使用空格分割")
    args = parser.parse_args()
    rename_files(dir=args.dir, joiner="_temp_", ignoreType=args.ignoreType, typeOnly=args.typeOnly)
    rename_files(dir=args.dir, prefix=args.prefix, joiner=args.joiner, startNum=args.startNum,
                 changeType=args.changeType, ignoreType=args.ignoreType, typeOnly=args.typeOnly)
print("Rename files finished")

3)添加到数据集

已经切割得到的脸部经过重新排序命名后,按照一定的比例添加到数据集。相关代码如下:

def divide_train_test(src, train_percentage=5, test_percentage=1):
    if not os.path.exists(src):
        print("folder %s is not exist" % src)
        return
    dirs = os.listdir(src)
    test_dir = os.path.join(src, "test")
    train_dir = os.path.join(src, "train")  #训练数据路径
    if not os.path.exists(test_dir):
        os.mkdir(test_dir)
    if not os.path.exists(train_dir):
        os.mkdir(train_dir)
    for dir_name in dirs:
        if dir_name != "test" and dir_name != "train":
            current_dir = os.path.join(src, dir_name)
            test_dir = os.path.join(src, "test", dir_name)  #测试集路径
            train_dir = os.path.join(src, "train", dir_name)  #训练集路径
            if not os.path.exists(test_dir):
                os.mkdir(test_dir)
            if not os.path.exists(train_dir):
                os.mkdir(train_dir)
            if os.path.isdir(current_dir):
                images = os.listdir(current_dir)
                image_num = len(images)
                for image in images:
                    filename = os.path.basename(image).split('.')[0]
                    if filename.isdigit():
                        percentage = train_percentage + test_percentage
                        test_num = (image_num / percentage) * test_percentage + 1
                        if int(filename) <= test_num:
                            if not os.path.exists(os.path.join(test_dir, image)):
                                shutil.move(os.path.join(current_dir, image), os.path.join(test_dir))
                            else:
                                os.remove(os.path.join(current_dir, image))
                        else:
                            if not os.path.exists(os.path.join(train_dir, image)):
                                shutil.move(os.path.join(current_dir, image), os.path.join(train_dir))
                            else:
                                os.remove(os.path.join(current_dir, image))
            shutil.rmtree(current_dir)
    for dirs in os.listdir(src):
        for name in os.listdir(os.path.join(src, dirs)):
            if os.path.isdir(os.path.join(src, dirs, name)):
                rename_file(os.path.join(src, dirs, name))
    print("Set all cropped images to train and test")

3. 模型训练及保存

本部分包括设置基本参数、模型保存和模块预测。

1)设置基本参数

相关代码如下:

DATA_PATH = "Datas" #数据集路径
TRAIN_NUM = 30       #训练次数
BATCH = 5             #批次
model_trainer = ModelTraining()
model_trainer.setModelTypeAsResNet()        #训练算法
model_trainer.setDataDirectory(data_path)  #训练目录
model_trainer.trainModel(num_objects=num_obj,  
#该参数用于指定图像数据集中对象的数量
num_experiments=train_num,  #该参数用于指定图像训练的次数
enhance_data=True,  #该参数用于指定是否生成训练图像的副本以获得更好的性能
batch_size=batch,  #该参数用于指定批次数量,分批训练,直到所有批次训练集都完成为止
show_network_summary=True #该参数用于指定是否在控制台中显示训练的过程 

2)模型保存

模型每次训练完成都会输出一个.h5文件和对应的.json文件,如图1所示。model_class.json文件中包含人物名称,molde_ex-xxx_acc_xxxxxx.h5中ex后的数字表示训练次数,acc后的数字表示对应的精度。model_class.json文件中的人物名称如图2所示,采用Unicode编码。训练好的模型保存后可重复使用,也可移植到其他环境中使用。

在这里插入图片描述

图1 训练模型后输出结果

在这里插入图片描述

图2 model_class.json文件中的人物名称

3)模块预测

相关代码如下:

#设置基本参数
IMAGE_PATH = "uploader/"  #预测图片路径
MODEL_PATH = "data/models/model_ex-150_acc-0.883871.h5"  #模型路径
JSON_PATH = "data/json/model_class.json"  #json文件路径
RESULT_COUNT = 3  #显示预测结果的数量
prediction = CustomImagePrediction()  #初始化ResNet
prediction.setModelTypeAsResNet()  #设置ResNet模型
#预测函数
def predict(img_path, model_path=MODEL_PATH, json_path=JSON_PATH, result_count=RESULT_COUNT):
    if not os.path.exists(img_path):
        print("Can not found img %s" % img_path)
        return
    with open(json_path) as f:
        num_obj = len(json.load(f))
        print(num_obj)
    prediction.setModelPath(model_path)
    prediction.setJsonPath(json_path)
    prediction.loadModel(num_objects=num_obj)
    predictions, probabilities = prediction.predictImage(img_path, result_count=result_count)
    result = {}
    i = 1
    for eachPrediction, eachProbability in zip(predictions, probabilities):
        result[i]={eachPrediction: str(round(float(eachProbability), 2)) + '%' }
        i = i + 1
    print(result)
    return result

相关其它博客

基于opencv+ImageAI+tensorflow的智能动漫人物识别系统——深度学习算法应用(含python、JS、模型源码)+数据集(一)

基于opencv+ImageAI+tensorflow的智能动漫人物识别系统——深度学习算法应用(含python、JS、模型源码)+数据集(二)

基于opencv+ImageAI+tensorflow的智能动漫人物识别系统——深度学习算法应用(含python、JS、模型源码)+数据集(四)

工程源代码下载

详见本人博客资源下载页


其它资料下载

如果大家想继续了解人工智能相关学习路线和知识体系,欢迎大家翻阅我的另外一篇博客《重磅 | 完备的人工智能AI 学习——基础知识学习路线,所有资料免关注免套路直接网盘下载》
这篇博客参考了Github知名开源平台,AI技术平台以及相关领域专家:Datawhale,ApacheCN,AI有道和黄海广博士等约有近100G相关资料,希望能帮助到所有小伙伴们。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/201812.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

阿里云国际短信业务网络超时排障指南

选取一台或多台线上的应用服务器或选取相同网络环境下的机器&#xff0c;执行以下操作。 获取公网出口IP。 curl ifconfig.me 测试连通性。 &#xff08;推荐&#xff09;执行MTR命令&#xff08;可能需要sudo权限&#xff09;&#xff0c;检测连通性&#xff0c;执行30秒。 m…

MySQL 插入数据报错 Incorrect string value

当在sys_dict_data表中执行插入语句&#xff1b; insert into sys_dict_data values(1, 1, 男, 0, sys_user_sex, , , Y, 0, admin, sysdate(), , null, 性别男);报错信息如下&#xff1a; insert into sys_dict_data values(1, 1, 男, …

小航助学题库蓝桥杯题库c++选拔赛(22年3月)(含题库教师学生账号)

需要在线模拟训练的题库账号请点击 小航助学编程在线模拟试卷系统&#xff08;含题库答题软件账号&#xff09; 需要在线模拟训练的题库账号请点击 小航助学编程在线模拟试卷系统&#xff08;含题库答题软件账号&#xff09;

解决:IDEA的debug模式只有第一次能拦截请求进行debug,后续所有请求全部失效

解决&#xff1a;IDEA的debug模式只有第一次能拦截请求进行debug&#xff0c;后续所有请求全部失效 一问题描述&#xff1a;IDEA的debug模式只有第一次能拦截请求进行debug&#xff0c;后续所有请求全部失效二问题原因&#xff1a;对IDEA的debug功能不熟悉或者理解有偏差三解决…

k8s-daemonset、job、cronjob控制器 6

Daemonset控制器&#xff08;一个节点部署一个&#xff09; 、 创建Daemonset控制器 控制节点上不能进行部署&#xff0c;有污点 解决方式&#xff1a; 扩容节点&#xff0c;token值过期的解决方法&#xff1a; 回收pod job控制器 需要使用perl镜像&#xff0c;仓库没有&…

hadoop操作

文件操作 注意当前所在的路径&#xff0c;创建一个mytest文件夹 创建一个1.txt文件 将1.txt文件移动到mytest中&#xff0c;通过mv改名字&#xff0c;然后查看mytest文件夹的txt文件变成了test.txt 删除文件 上传下载文件 新建1.txt 然后编辑它 随便输入什么 上传 然后看看网…

java学习part23异常try catch

124-异常处理-异常的概述与常见异常的举例_哔哩哔哩_bilibili 1.异常 2.try catch 3.finally 类似golang的defer 一定执行的语句

视图层与模板层

视图层 1 视图函数 一个视图函数&#xff0c;简称视图&#xff0c;是一个简单的Python 函数&#xff0c;它接受Web请求并且返回Web响应。响应可以是一张网页的HTML内容&#xff0c;一个重定向&#xff0c;一个404错误&#xff0c;一个XML文档&#xff0c;或者一张图片. . . 是…

day31_servlet

今日内容 零、 复习昨日 一、请求转发 二、重定向 三、Session 四、Filter 零、 复习昨日 一、请求转发 1.1 现有问题 响应的代码与接收请求代码在一起查询全部的代码与登录的代码在一起,考虑一下后续删除完,更新完要查全部怎么办?这也没有遵循单一职责,不便于后期维护ps: 开…

前端编码规范

文章目录 一、背景二、内容1、注释规范&#xff08;1&#xff09;文件注释&#xff08;2&#xff09;函数注释&#xff08;3&#xff09;单行注释&#xff08;3&#xff09;多行注释 2、命名规范&#xff08;1&#xff09;项目命名&#xff08;2&#xff09;目录命名&#xff0…

C# 使用 Fody 监控方法执行时间

写在前面 在做性能调优的时候&#xff0c;经常需要跟踪具体方法的执行时间&#xff1b;通过插入Stopwatch的方案对代码的侵入性太高了&#xff0c;所以引入了 MethodTimer.Fody 类库&#xff0c;采用编译时注入的方式给方法动态加上Stopwatch 跟踪代码&#xff0c;只需要在目标…

re:Invent 构建未来:云计算生成式 AI 诞生科技新局面

文章目录 前言什么是云计算云计算类型亚马逊云科技云计算最多的功能最大的客户和合作伙伴社区最安全最快的创新速度最成熟的运营专业能力 什么是生成式 AI如何使用生成式 AI后记 前言 在科技发展的滚滚浪潮中&#xff0c;我们见证了云计算的崛起和生成式 AI 的突破&#xff0c…

Python - Real-ESRGAN 提升图像、视频清晰度 - 最高可达 4 K

目录 一.引言 二.Real-ESRGAN 理论 1.模型简介 2.经典退化模型 ◆ 退化过程全览 ◆ K - 高斯滤波 ◆ N - 噪声 ◆ ↓r - Resize ◆ jpeg - 压缩 3.高阶退化模型 4.环形和超调伪影 5.网络结构 ◆ ESRGAN 生成器 ◆ U-Net 鉴别器 三.Real-ESRGAN 实战 1.快速体验…

YashanDB入选2023年世界互联网大会领先科技奖成果集《科技之魅》

近日&#xff0c;由深圳计算科学研究院自主研发的“崖山数据库系统YashanDB”入编2023年世界互联网大会领先科技奖成果集《科技之魅》。此次入选&#xff0c;充分彰显了YashanDB在数据库技术领域的突破性创新成果。 《科技之魅》是世界互联网大会领先科技奖的重要成果&#xff…

安网AC智能路由系统actpt_5g.data敏感信息泄露漏洞复现 [附POC]

文章目录 安网AC智能路由系统actpt_5g.data敏感信息泄露漏洞复现 [附POC]0x01 前言0x02 漏洞描述0x03 影响版本0x04 漏洞环境0x05 漏洞复现1.访问漏洞环境2.构造POC3.复现 安网AC智能路由系统actpt_5g.data敏感信息泄露漏洞复现 [附POC] 0x01 前言 免责声明&#xff1a;请勿利…

【python+Excel】读取和存储测试数据完成接口自动化测试

http_request2.py用于发起http请求 #读取多条测试用例 #1、导入requests模块 import requests #从 class_12_19.do_excel1导入read_data函数 from do_excel2 import read_data from do_excel2 import write_data from do_excel2 import count_case #定义http请求函数COOKIENon…

国密加密工业路由器 数据安全升级

国密加密工业路由器&#xff0c;简称国密加密路由器&#xff0c;是指遵循“商用密码管理规范”中规定的国家商用密码算法&#xff0c;采用国密加密芯片和密码算法的专业路由器。相比-般路由器&#xff0c;国密加密路由器具有更高级别的加密保护&#xff0c;可以有效提高数据传输…

昨日一题 1670. 设计前中后队列(中等,列表)

维护左右两个队列&#xff0c;控制左队列的长度比右队列长&#xff0c;且不超过1pushFront 往左队列的左边添加元素pushMiddle 往左队列的右边或者右队列的左边添加元素其余同理&#xff0c;可以参照代码 class FrontMiddleBackQueue:def __init__(self):self.llist, self.rli…

如何保证缓存和数据库的双写一致性?

一、什么是数据库和缓存双写一致性&#xff1f; 在分布式系统中&#xff0c;数据库和缓存会搭配一起使用&#xff0c;以此来保证程序的整体查询性能。也就说&#xff0c;分布式系统为了缓解数据库查询的压力&#xff0c;会将查出来的数据保存在缓存中&#xff0c;下次再查询时…

代码随想录算法训练营第五十九天| 503.下一个更大元素II 42. 接雨水

文档讲解&#xff1a;代码随想录 视频讲解&#xff1a;代码随想录B站账号 状态&#xff1a;看了视频题解和文章解析后做出来了 503.下一个更大元素II class Solution:def nextGreaterElements(self, nums: List[int]) -> List[int]:res [-1] * len(nums)stack []for i in…