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

目录

  • 前言
  • 总体设计
    • 系统整体结构图
    • 系统流程图
  • 运行环境
    • 爬虫
    • 模型训练
    • 实际应用
  • 模块实现
    • 1. 数据准备
      • 1)爬虫下载原始图片
      • 2)手动筛选图片
  • 相关其它博客
  • 工程源代码下载
  • 其它资料下载


在这里插入图片描述

前言

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

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

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

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

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

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

总体设计

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

系统整体结构图

系统整体结构如图所示。

在这里插入图片描述

系统流程图

系统流程如图所示。

在这里插入图片描述

运行环境

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

爬虫

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

详见博客。

模型训练

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

详见博客。

实际应用

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

详见博客。

模块实现

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

1. 数据准备

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

1)爬虫下载原始图片

下图为下载人物的部分列表。

在这里插入图片描述

爬虫可根据列表自动下载指定数量的人物图片存放于指定文件夹,相关代码如下:

#phantomjs设置
dcap = dict(DesiredCapabilities.PHANTOMJS)
dcap["phantomjs.page.settings.userAgent"] = ("Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.100"
)
#根据关键词爬取并下载图片 
#下载基本参数设置,更多参数设置在main()函数处
NAME_LIST = "characters_name_list.txt"  #导入需要获取关键字文件,每个关键字一行
MAX_NUM = 60  #每个关键字下载数量
OUTPUT_PATH = "./Raw"  #下载图片书保存目录
TIME_OUT = 20  #设置超时
DELAY = 1  #随机下载延迟0~1秒,同样防止被服务器识别出爬虫
#产生随机的header,防止被服务器识别出爬虫
def get_random_headers():ua = UserAgent().random  #产生随机的User-Agentheaders = {"Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8","Proxy-Connection": "keep-alive","User-Agent": ua,"Accept-Encoding": "gzip, deflate, sdch",}return headersdef get_image_url(keywords, max_number=10000, face_only=False):#获取图像urldef decode_url(url): #解码urlin_table = '0123456789abcdefghijklmnopqrstuvw'out_table = '7dgjmoru140852vsnkheb963wtqplifca'translate_table = str.maketrans(in_table, out_table)mapping = {'_z2C$q': ':', '_z&e3B': '.', 'AzdH3F': '/'}for k, v in mapping.items():url = url.replace(k, v)return url.translate(translate_table)base_url= "https://image.baidu.com/search/acjson?tn=resultjson_com&ipn=rj&ct=201326592"\"&lm=7&fp=result&ie=utf-8&oe=utf-8&st=-1"keywords_str = "&word={}&queryWord={}".format(quote(keywords), quote(keywords))query_url = base_url + keywords_strquery_url += "&face={}".format(1 if face_only else 0)init_url = query_url + "&pn=0&rn=30"res = requests.get(init_url)init_json = json.loads(res.text.replace(r"\'", ""), encoding='utf-8', strict=False)total_num = init_json['listNum']target_num = min(max_number, total_num)crawl_num = min(target_num * 2, total_num)crawled_urls = list()batch_size = 30with futures.ThreadPoolExecutor(max_workers=5) as executor:future_list = list()def process_batch(batch_no, batch_size):  #批处理image_urls = list()url = query_url + \"&pn={}&rn={}".format(batch_no * batch_size, batch_size)try_time = 0while True:try:response = requests.get(url)breakexcept Exception as e:try_time += 1if try_time > 3:print(e)return image_urlsresponse.encoding = 'utf-8'res_json = json.loads(response.text.replace(r"\'", ""), encoding='utf-8', strict=False)for data in res_json['data']:if 'objURL' in data.keys():image_urls.append(decode_url(data['objURL']))elif'replaceUrl'in data.keys() and len(data['replaceUrl'])== 2:image_urls.append(data['replaceUrl'][1]['ObjURL'])return image_urlsfor i in range(0, int((crawl_num + batch_size - 1) / batch_size)):future_list.append(executor.submit(process_batch, i, batch_size))for future in futures.as_completed(future_list):if future.exception() is None:crawled_urls += future.result()else:print(future.exception())return crawled_urls[:min(len(crawled_urls), target_num)]def get_image_url(keywords, max_number=10000, face_only=False):def decode_url(url):  #解码in_table = '0123456789abcdefghijklmnopqrstuvw'out_table = '7dgjmoru140852vsnkheb963wtqplifca'translate_table = str.maketrans(in_table, out_table)mapping = {'_z2C$q': ':', '_z&e3B': '.', 'AzdH3F': '/'}for k, v in mapping.items():url = url.replace(k, v)return url.translate(translate_table)base_url = "https://image.baidu.com/search/acjson?tn=resultjson_com&ipn=rj&ct=201326592"\"&lm=7&fp=result&ie=utf-8&oe=utf-8&st=-1"keywords_str = "&word={}&queryWord={}".format(quote(keywords), quote(keywords))query_url = base_url + keywords_strquery_url += "&face={}".format(1 if face_only else 0)init_url = query_url + "&pn=0&rn=30"res = requests.get(init_url)init_json = json.loads(res.text.replace(r"\'", ""), encoding='utf-8', strict=False)total_num = init_json['listNum']target_num = min(max_number, total_num)crawl_num = min(target_num * 2, total_num)crawled_urls = list()batch_size = 30with futures.ThreadPoolExecutor(max_workers=5) as executor:future_list = list()def process_batch(batch_no, batch_size):image_urls = list()url = query_url + \"&pn={}&rn={}".format(batch_no * batch_size, batch_size)try_time = 0while True:try:response = requests.get(url)breakexcept Exception as e:try_time += 1if try_time > 3:print(e)return image_urlsresponse.encoding = 'utf-8'res_json = json.loads(response.text.replace(r"\'", ""), encoding='utf-8', strict=False)for data in res_json['data']:if 'objURL' in data.keys():image_urls.append(decode_url(data['objURL']))elif'replaceUrl' in data.keys() and len(data['replaceUrl']) == 2:image_urls.append(data['replaceUrl'][1]['ObjURL'])return image_urlsfor i in range(0, int((crawl_num + batch_size - 1) / batch_size)):future_list.append(executor.submit(process_batch, i, batch_size))for future in futures.as_completed(future_list):if future.exception() is None:crawled_urls += future.result()else:print(future.exception())return crawled_urls[:min(len(crawled_urls), target_num)]#main函数
def main(list_file, output="./Raw", max_number=100, threads=50, timeout=20, time_delay=3, face_only=True,browser="phantomjs", quiet=False, file_prefix="img"):with open(list_file, encoding="utf-8") as keywords_list:for keywords in keywords_list:keywords = keywords.rstrip()  #去除换行符if keywords == "":  #跳过空行continueif os.path.exists(os.path.join(output, keywords)):  #查看是否已经下载print("[warn: ] [{}] is already downloaded, downloader will skip [{}]".format(keywords, keywords))continuecrawled_urls = crawler.crawl_image_urls(keywords, max_number=max_number, face_only=face_only,browser=browser, quiet=quiet)download_images(image_urls=crawled_urls, dst_dir=output, keywords=keywords,concurrency=threads, timeout=timeout,time_delay=time_delay, file_prefix=file_prefix)img_count = len(os.listdir(os.path.join(output, keywords)))print("[{}]: get {} image(s)".format(keywords, img_count))def download_image(image_url, dst_dir, file_name, timeout=20, time_delay=1):time.sleep(random.randint(0, time_delay))  #暂停0~time_delay的整数秒response = Nonefile_path = os.path.join(dst_dir, file_name)try_times = 0while True:try:try_times += 1response = requests.get(image_url, headers=get_random_headers(), timeout=timeout)with open(file_path, 'wb') as f:f.write(response.content)response.close()file_type = imghdr.what(file_path)if file_type in ["jpg", "jpeg", "png", "bmp"]:new_file_name = "{}.{}".format(file_name, file_type)new_file_path = os.path.join(dst_dir, new_file_name)shutil.move(file_path, new_file_path)print("[OK:]  {}  {}".format(new_file_name, image_url))else:os.remove(file_path)print("[Err:] file type err or not exists {}".format(image_url))breakexcept Exception as e:if try_times < 3:continueif response:response.close()print("[Fail:]  {}  {}".format(image_url, e.args))breakdef download_images(image_urls, dst_dir, keywords, file_prefix="img", concurrency=50, timeout=20, time_delay=1):with concurrent.futures.ThreadPoolExecutor(max_workers=concurrency) as executor:future_list = list()count = 0dst_dir = os.path.join(dst_dir, keywords)if not os.path.exists(dst_dir):os.makedirs(dst_dir)for image_url in image_urls:file_name = file_prefix + "_" + "%04d" % countfuture_list.append(executor.submit(download_image, image_url, dst_dir, file_name, timeout, time_delay))count += 1concurrent.futures.wait(future_list, timeout=180)

结果如图所示。
在这里插入图片描述

2)手动筛选图片

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

在这里插入图片描述

相关其它博客

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

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

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

工程源代码下载

详见本人博客资源下载页


其它资料下载

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

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何处理git多分支

本篇文章主要处理以下两种多分支问题 如何将自己在本地的修改上传到一个新的Git分支&#xff08;比如用于测试&#xff0c;不合并进main分支&#xff09;&#xff1f;如何在一个新的本地仓库拉取一个项目的非main分支&#xff0c;并处理他们关联关系&#xff1f; 1. 将自己在…

概率论与数理统计中常见的随机变量分布律、数学期望、方差及其介绍

1 离散型随机变量 1.1 0-1分布 设随机变量X的所有可能取值为0与1两个值&#xff0c;其分布律为 若分布律如上所示&#xff0c;则称X服从以P为参数的(0-1)分布或两点分布。记作X~ B(1&#xff0c;p) 0-1分布的分布律利用表格法表示为: X01P1-PP 0-1分布的数学期望E(X) 0 *…

试写一算法将两个递增有序的带头结点的单链表合并为一个递增有序的带头结点的单链表。(利用原表结点空间)

试写一算法将两个递增有序的带头结点的单链表合并为一个递增有序的带头结点的单链表。 &#xff08;利用原表结点空间&#xff09; 比如现在要将下面两个链表合并&#xff0c;这里是要求利用原表空间 我们先创建一个辅助的链表L3&#xff0c;用p和q分别标记L1和L2的数据元素&…

动手学深度学习(四)---多层感知机

文章目录 一、理论知识1.感知机2.XOR问题3.多层感知机4.多层感知机的从零开始实现 【相关总结】1.torch.randn()2.torch.zeros_like() 一、理论知识 1.感知机 给定输入x,权重w&#xff0c;和偏移b,感知机输出&#xff1a; 2.XOR问题 感知机不能拟合XOR问题&#xff0c;他…

Java学习路径:入门学习、深入学习、核心技术,操作案例和实际代码示例

学习路径&#xff1a;入门学习、深入学习、核心技术&#xff0c; 每个主题都包括很多的操作案例和实际代码示例。 a. 入门学习&#xff1a; 1. 基础语法&#xff1a; 变量和数据类型&#xff1a; // 定义和初始化变量 int age 25;// 不同数据类型的声明 double price 19.99…

[AutoSAR 存储] 汽车智能座舱的存储需求

公知及经验整理&#xff0c;原创保护&#xff0c;禁止转载。 专栏 《AutoSAR 存储》 <<<< 返回总目录 <<<< 1 智能座舱的发展&#xff1a; 1.1 发展历史 车辆信息娱乐系统的发展可以分为三个阶段。 机械化阶段 在上世纪90年代&#xff0c;车辆仪表盘…

Pix2Pix 使用指南:从原理到项目应用

Pix2Pix Pix2Pix 介绍&#xff1a;使用条件 GAN 进行图像到图像的转换Pix2Pix 原理Pix2Pix 模型结构生成器&#xff1a;Unet结构判别器&#xff1a;PatchGAN目标函数目标函数总结 Pix2Pix 项目使用 Pix2Pix 介绍&#xff1a;使用条件 GAN 进行图像到图像的转换 Pix2Pix 论文&a…

吉他初学者学习网站搭建系列(1)——目录

文章目录 背景文章目录功能网站地址网站展示展望 背景 这个系列是对我最近周末搭建的吉他工具类平台YUERGS的总结。我个人业余爱好是自学吉他&#xff0c;我会在这个平台中动手集成我认为很有帮助的一些工具&#xff0c;来提升我的吉他水平和音乐素养&#xff0c;希望也可以帮…

C++初阶(十二)string的模拟实现

&#x1f4d8;北尘_&#xff1a;个人主页 &#x1f30e;个人专栏:《Linux操作系统》《经典算法试题 》《C》 《数据结构与算法》 ☀️走在路上&#xff0c;不忘来时的初心 文章目录 一、string类的模拟实现1、构造、拷贝构造、赋值运算符重载以及析构函数2、迭代器类3、增删查…

LeetCode.203移除链表元素(原链表操作、虚拟头结点)

LeetCode.203移除链表元素 1.问题描述2.解题思路3.代码 1.问题描述 给你一个链表的头节点 head 和一个整数 val &#xff0c;请你删除链表中所有满足 Node.val val 的节点&#xff0c;并返回 新的头节点 。 示例 1&#xff1a; 输入&#xff1a;head [1,2,6,3,4,5,6], val …

【linux】基本指令(中篇)

echo指令 将引号内容打印到显示屏上 输出的重定向 追加的重定向 输出的重定向 我们学习c语言的时候当以写的方式创建一个文件&#xff0c;就会覆盖掉该文件之前的内容 当我们以追加的方式打开文件的时候&#xff0c;原文件内容不会被覆盖而是追加 more指令 10.more指令…

VUE限制文件上传大小和上传格式

<el-form-item label"图片&#xff1a;" prop"tempImagePath"><el-uploadclass"upload"accept"image/jpeg":show-file-list"false"list-type"picture-card":headers"{ token: token}":action&…