从零搭建pytorch模型教程(八)实践部分(二)目标检测数据集格式转换
前言
图像目标检测领域有一个非常著名的数据集叫做COCO,基本上现在在目标检测领域发论文,COCO是不可能绕过的Benchmark。因此许多的开源目标检测算法框架都会支持解析COCO数据集格式。通过将其他数据集格式转换成COCO格式可以无痛的使用这些开源框架来训练新的数据集,比如Pascal VOC数据集。
本文首先将介绍COCO和VOC目标检测数据集格式以及VOC转换到COCO格式的核心步骤,最后将自定义一种数据格式利用上述核心步骤将其转换到COCO格式下。只要理解了不同数据集的标注方法,转换数据集其实就是一个非常简单自然的过程,可以拓展到任意方式标注的数据集上。
数据集格式介绍
COCO
其实COCO数据集的标签内容不仅仅涵盖目标检测,还包含了目标关键点、实例Mask以及图片描述等信息。在这里我们着重介绍COCO的目标检测相关内容。我们以COCO2017为例先看看其标签文件结构:
其中红框框出来的就是以Json格式组织的目标检测相关的标注文件,其主要由三个部分构成:
"info"字段:数据集的基本信息描述、版本号、年份等信息。
“images字段” :包含了图片路径、宽高信息、唯一标志ID等信息。
“annotations字段”:包含了图片中的Box位置、类别等信息。
其简单示例如下所示:
{"info": {"description": "COCO 2017 Dataset","url": "http://cocodataset.org","version": "1.0","year": 2017,"contributor": "COCO Consortium","date_created": "2017/09/01"},
"images": [{"license": 4,"file_name": "000000397133.jpg","coco_url": "http://images.cocodataset.org/val2017/000000397133.jpg","height": 427,"width": 640,"date_captured": "2013-11-14 17:02:52","flickr_url": "","id": 397133},{"license": 1,"file_name": "000000037777.jpg","coco_url": "http://images.cocodataset.org/val2017/000000037777.jpg","height": 230,"width": 352,"date_captured": "2013-11-14 20:55:31","flickr_url": "","id": 37777}],"annotations": [{"area": 702.1057499999998, //Box的尺寸"image_id": 289343, //对应的图像ID"bbox": [473.07, //左上角点x坐标395.93, //左上角点y坐标38.65, //Box的宽28.67 //Box的高],"category_id": 18, //对应的类别"id": 1768, //该标签独有ID"iscrowd": 0 //0表示非密集场景,1表示密集场景}]
}
PASCAL VOC
PASCAL VOC数据集有两个相对重要年份的数据集:PASCAL VOC 2007与PASCAL VOC 2012,每年都会在上一年的基础上增加一些额外的数据或标签。PASCAL VOC数据集也涵盖了分类、检测、分割、动作识别等标签。
我们这里着重介绍其检测部分,以PASCAL VOC 2012数据集为例,包含了20个类别1W+数据集,2W+标注Box的目标。其标签格式是每一个图片都有一个对应的XML文件作为其标注信息载体,标注信息主要包含如下几方面内容:
图像基本信息:图像名、图像尺寸等
object字段:目标分类标签、box标签(xmin,ymin,xmax,ymax)等信息
XML主要格式如下:
<annotation><folder>VOC2012</folder><filename>2007_000063.jpg</filename> //标签对应的图片文件<source><database>The VOC2007 Database</database><annotation>PASCAL VOC2007</annotation><image>flickr</image></source><size> //图像尺寸<width>500</width><height>375</height><depth>3</depth></size><segmented>1</segmented><object><name>dog</name> //类别<pose>Unspecified</pose><truncated>0</truncated><difficult>0</difficult> //1表示这个目标是比较难识别的<bndbox> //box信息<xmin>123</xmin> //左上角x坐标<ymin>115</ymin> //左上角y坐标<xmax>379</xmax> //右下角x坐标<ymax>275</ymax> //右下角y坐标</bndbox></object><object><name>chair</name><pose>Frontal</pose><truncated>1</truncated><difficult>0</difficult><bndbox><xmin>75</xmin><ymin>1</ymin><xmax>428</xmax><ymax>375</ymax></bndbox></object>
</annotation>
数据集格式转换
在知道了各个数据集格式的基础上做数据集格式的转换就已经是非常简单的任务了,也有很多优秀的开源框架已经帮我们做好了这些事情比如MMDetection中就已经提供好了现成的工具供我们白嫖(bushi),使用了。
我们抽取其一些核心部分来一起看看,详细代码请参考MMDetection
Github:https://github.com/openmmlab/mmdetection/tree/master/tools/dataset_converters
从不同的数据集转换到COCO下主要也就两个步骤:
解析待转换数据集格式。
用COCO格式重构Json文件。
上述第二步对任意待转换数据集都是一样的,可以抽象为一个函数,输入的是解析好的不同数据集的Box信息等数据。下面我们以几个不同的数据集为例介绍。
From VOC to COCO
从VOC数据集到COCO数据集格式转换主要包含如下两个步骤:
解析VOC数据集数据:遍历图片以及对应XML文件,返回一个数组A,数组中的每一个实例包含了图片路径、Box相关标注信息等。
遍历A将A中的实例信息用COCO的格式表达出来并生成Json文件
其主要由两块核心代码构成,一个是VOC的XML文件解析,一个是Json文件生成。
VOC XML标注文件解析
xml文件解析已经有下面这个非常方便的Python库供大家使用
import xml.etree.ElementTree as ETdef parse_xml(args):xml_path, img_path = argstree = ET.parse(xml_path) # 构建XML文件解析树root = tree.getroot() # 获取XML文件的根节点size = root.find('size') # 获取图像的尺寸w = int(size.find('width').text) # 图像宽高h = int(size.find('height').text)bboxes = []labels = []bboxes_ignore = []labels_ignore = []for obj in root.findall('object'): # 遍历object字段下所有box信息name = obj.find('name').textlabel = label_ids[name]difficult = int(obj.find('difficult').text) #这个difficult对应的是COCO中iscrowdedbnd_box = obj.find('bndbox')bbox = [ # 对应的Box标注信息(x1,y1,x2,y2)int(bnd_box.find('xmin').text),int(bnd_box.find('ymin').text),int(bnd_box.find('xmax').text),int(bnd_box.find('ymax').text)]if difficult: # 将difficult属性的Box放入ignore列表bboxes_ignore.append(bbox) # 最后计算AP时这个GT是被忽略的labels_ignore.append(label)else:bboxes.append(bbox)labels.append(label)if not bboxes:bboxes = np.zeros((0, 4))labels = np.zeros((0, ))else:bboxes = np.array(bboxes, ndmin=2) - 1labels = np.array(labels)if not bboxes_ignore:bboxes_ignore = np.zeros((0, 4))labels_ignore = np.zeros((0, ))else:bboxes_ignore = np.array(bboxes_ignore, ndmin=2) - 1labels_ignore = np.array(labels_ignore)annotation = {'filename': img_path,'width': w,'height': h,'ann': {'bboxes': bboxes.astype(np.float32),'labels': labels.astype(np.int64),'bboxes_ignore': bboxes_ignore.astype(np.float32),'labels_ignore': labels_ignore.astype(np.int64)}}return annotation
用解析好的annotation重构COCO格式的Json文件:
import numpy as npdef voc_classes():return ['aeroplane', 'bicycle', 'bird', 'boat', 'bottle', 'bus', 'car', 'cat','chair', 'cow', 'diningtable', 'dog', 'horse', 'motorbike', 'person','pottedplant', 'sheep', 'sofa', 'train', 'tvmonitor']def cvt_to_coco_json(annotations):image_id = 0annotation_id = 0coco = dict()coco['images'] = []coco['type'] = 'instance'coco['categories'] = []coco['annotations'] = []image_set = set()# coco annotations字段添加标注信息def addAnnItem(annotation_id, image_id, category_id, bbox, difficult_flag):annotation_item = dict()annotation_item['segmentation'] = []# 这里省略了seg部分代码seg = []annotation_item['segmentation'].append(seg)# 转换为COCO对应的x1,y1,w,h格式xywh = np.array([bbox[0], bbox[1], bbox[2] - bbox[0], bbox[3] - bbox[1]])annotation_item['area'] = int(xywh[2] * xywh[3])# 如果difficult标志为1,该目标对应coco中iscrowd字段为1表明为密集目标场景if difficult_flag == 1:annotation_item['ignore'] = 0annotation_item['iscrowd'] = 1else:annotation_item['ignore'] = 0annotation_item['iscrowd'] = 0annotation_item['image_id'] = int(image_id)annotation_item['bbox'] = xywh.astype(int).tolist()annotation_item['category_id'] = int(category_id)annotation_item['id'] = int(annotation_id)coco['annotations'].append(annotation_item)return annotation_id + 1#for category_id, name in enumerate(voc_classes()):category_item = dict()category_item['supercategory'] = str('none')category_item['id'] = int(category_id)category_item['name'] = str(name)coco['categories'].append(category_item)for ann_dict in annotations:file_name = ann_dict['filename']ann = ann_dict['ann']assert file_name not in image_setimage_item = dict()image_item['id'] = int(image_id)image_item['file_name'] = str(file_name)image_item['height'] = int(ann_dict['height'])image_item['width'] = int(ann_dict['width'])coco['images'].append(image_item) # 设置COCO的"images"字段image_set.add(file_name)# 设置COCO的"annotations"字段bboxes = ann['bboxes'][:, :4] # 获取box和label类别信息labels = ann['labels']for bbox_id in range(len(bboxes)):bbox = bboxes[bbox_id]label = labels[bbox_id]annotation_id = addAnnItem(annotation_id, image_id, label, bbox, difficult_flag=0)# ignore的目标表示该GT被忽视bboxes_ignore = ann['bboxes_ignore'][:, :4]labels_ignore = ann['labels_ignore']for bbox_id in range(len(bboxes_ignore)):bbox = bboxes_ignore[bbox_id]label = labels_ignore[bbox_id]annotation_id = addAnnItem(annotation_id, image_id, label, bbox, difficult_flag=1)image_id += 1return coco
拿到返回的coco对象后只需要调用下列方法就可以将对象序列化成Json文件了。
import mmcv
mmcv.dump(coco, out_file) # out_file为输出的json文件名
值得注意的一点是上面提到的iscorwd这个字段,这个字段标注为1时,最后统计AP时,该GT与预测框完成匹配后还可以考虑与其他预测框进行匹配,允许多个预测框与其匹配(因为场景是密集的)。
自定义格式数据集 to COCO
首先我们自定义一种数据标注格式,我们用txt文件作为标注信息的载体,将txt文件与图像文件通过相同的文件名一一对应。分别将标签文件以及对应图像文件放在Annotations以及JPEGImages文件夹下,同时我们生成JPEGImages图像文件的filelist.txt文件,这个文件每一行对应一个图像文件的全路径:
txt文件格式如下:
第一列表示类别,从0开始;第二到第五列表示Box信息依次为中心点x方向坐标,中心点y方向坐标,box的宽以及高(cx,cy,w,h)。
我们同样使用前面介绍过的cvt_to_coco_json将固定格式的annotations转换为COCO格式,那么我们只需要编写解析自定义格式数据集生成annotations的代码即可:
box尺寸小于min_size的作为ignore对象
file_path为图像路径的filelist.txt文件的全路径
def parse_info(file_path, min_size):annotations = []invalid_img = 0small_box = 0with open(file_path, 'r') as f:for l in tqdm(f):img_file = l.rstrip()img = cv2.imread(img_file)if img is None:invalid_img += 1continueh,w,_ = img.shape# 获取对应的标签文件ann_file = img_file.replace("JPEGImages", "Annotations").replace \(".png", ".txt").replace(".jpg", ".txt")annotation = {'filename' : img_file,'height' : h,'width' : w,'ann' : {}}if not osp.exists(ann_file):annotations.append(annotation)continueboxes, labels = [], []boxes_ignore, labels_ignore = [], []with open(ann_file, 'r') as fr:for anno in fr:anno_list = anno.rstrip().split(' ')cls = int(anno_list[0])cx, cy = float(anno_list[1]), float(anno_list[2])w, h = float(anno_list[3]), float(anno_list[4])# 转换为COCO box表示格式x1 = max(0, int(cx-w/2))y1 = max(0, int(cy-h/2))box = [x1, y1, w, h]if w >= min_size and h >= min_size:labels.append(cls)boxes.append(box)else:labels_ignore.append(cls)boxes_ignore.append(box) boxes = np.zeros((0, 4)) if len(boxes) == 0 else np.array(boxes)labels = np.zeros((0, )) if len(labels) == 0 else np.array(labels) boxes_ignore = np.zeros((0, 4)) if len(boxes_ignore) == 0 else np.array(boxes_ignore)labels_ignore = np.zeros((0, )) if len(labels_ignore) == 0 else np.array(labels_ignore) annotation['ann']['bboxes'] = np.array(boxes)annotation['ann']['labels'] = np.array(labels)annotation['ann']['bboxes_ignore'] = np.array(boxes_ignore)annotation['ann']['labels_ignore'] = np.array(labels_ignore)annotations.append(annotation)print('INFO:Invalid IMG:{}'.format(invalid_img))return annotations
写在后面
数据集的转换是非常有必要的,在软件设计中我们希望一套代码尽可能多的为不同情况服务。在这里我们希望训练代码中一套数据集(Dataset)class代码来完成所有目标检测任务训练,而不是针对不同的数据集设计不同的Dataset class代码。而对于目标检测来说,COCO可能就是这个最佳的模板~
最后
感谢你们的阅读和喜欢,我收藏了很多技术干货,可以共享给喜欢我文章的朋友们,如果你肯花时间沉下心去学习,它们一定能帮到你。
因为这个行业不同于其他行业,知识体系实在是过于庞大,知识更新也非常快。作为一个普通人,无法全部学完,所以我们在提升技术的时候,首先需要明确一个目标,然后制定好完整的计划,同时找到好的学习方法,这样才能更快的提升自己。
这份完整版的大模型 AI 学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费
】
一、全套AGI大模型学习路线
AI大模型时代的学习之旅:从基础到前沿,掌握人工智能的核心技能!
二、640套AI大模型报告合集
这套包含640份报告的合集,涵盖了AI大模型的理论研究、技术实现、行业应用等多个方面。无论您是科研人员、工程师,还是对AI大模型感兴趣的爱好者,这套报告合集都将为您提供宝贵的信息和启示。
三、AI大模型经典PDF籍
随着人工智能技术的飞速发展,AI大模型已经成为了当今科技领域的一大热点。这些大型预训练模型,如GPT-3、BERT、XLNet等,以其强大的语言理解和生成能力,正在改变我们对人工智能的认识。 那以下这些PDF籍就是非常不错的学习资源。
四、AI大模型商业化落地方案
五、面试资料
我们学习AI大模型必然是想找到高薪的工作,下面这些面试题都是总结当前最新、最热、最高频的面试题,并且每道题都有详细的答案,面试前刷完这套面试题资料,小小offer,不在话下。
这份完整版的大模型 AI 学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费
】
相关文章:

从零搭建pytorch模型教程(八)实践部分(二)目标检测数据集格式转换
前言 图像目标检测领域有一个非常著名的数据集叫做COCO,基本上现在在目标检测领域发论文,COCO是不可能绕过的Benchmark。因此许多的开源目标检测算法框架都会支持解析COCO数据集格式。通过将其他数据集格式转换成COCO格式可以无痛的使用这些开源框架来训…...

MYSQL(2) 高级查询
文章目录 概述高级查询基础查询条件查询范围查询判空查询模糊查询分页查询查询后排序分组查询 小结 概述 接上篇,上篇写到增删改查。这篇继续。 高级查询 基础查询 -- 全部查询 select * from student; -- 只查询部分字段 select sname, class_id from student;…...

小程序的运营方法:从入门到精通
随着科技的快速发展,小程序已成为我们日常生活和工作中不可或缺的一部分。小程序无需下载安装,即用即走的特点深受用户喜爱。那么,如何运营好一个小程序呢?下面就为大家分享一些小程序的运营方法。 一、明确目标用户 在运营小程序…...

【优秀python算法毕设】基于python时间序列模型分析气温变化趋势的设计与实现
1 绪论 1.1 研究背景与意义 在气候变化日益受到全球关注的背景下,天气气温的变化已经对人们的生活各方面都产生了影响,人们在外出时大多都会在手机上看看天气如何,根据天气的变化来决定衣物的穿着和出行的安排。[1]如今手机能提供的信息已经…...

掌握 Symfony 路由系统:配置与管理
掌握 Symfony 路由系统:配置与管理 Symfony 是一个非常流行的 PHP 框架,而路由系统是 Symfony 框架的核心组件之一。通过理解和掌握 Symfony 的路由系统,开发者可以更高效地配置和管理应用程序的 URL 结构,从而更好地控制应用程序…...

OpenTeleVision复现及机器人迁移
相关信息 标题 Open-TeleVision: Teleoperation with Immersive Active Visual Feedback作者 Xuxin Cheng1 Jialong Li1 Shiqi Yang1 Ge Yang2 Xiaolong Wang1 UC San Diego1 MIT2主页 https://robot-tv.github.io/链接 https://robot-tv.github.io/resources/television.pdf代…...

气膜足球馆:经济高效的室内足球场馆解决方案—轻空间
如果你有一片足球场,想要建一个室内的足球馆,为什么不考虑一下气膜建筑呢?气膜建筑以其独特的优势和高性价比,成为现代体育场馆建设中的一匹黑马。它不仅具有传统建筑无法比拟的经济效益和快速施工优势,还在智能控制、…...

Vue3二次封装axios
官网: https://www.axios-http.cn/docs/interceptors steps1: 安装 npm install axios -ssteps2: /src/api/request.js 文件 >>> 拦截器 import axios from axios // 如果没用element-plus就不引入 import { ElMessage } from element-plusconst service axios.cre…...

【MetaGPT系列】【MetaGPT完全实践宝典——多智能体实践】
目录 前言一、智能体1-1、Agent概述1-2、Agent与ChatGPT的区别 二、多智能体框架MetaGPT2-1、安装&配置2-2、使用已有的Agent(ProductManager)2-3、多智能体系统介绍2-4、多智能体案例分析2-4-1、构建智能体团队2-4-2、动作/行为 定义2-4-3、角色/智…...

C#中GridControl的数据源双向绑定
1. 什么是双向数据绑定? 双向数据绑定是一种允许我们创建持久连接的技术,使模型数据和用户界面(UI)之间的交互能够自动同步。这意味着当模型数据发生变化时,UI会自动更新,反之亦然。这种双向数据绑定极大地简化了UI和模型数据之间…...

sklearn详细基础教程(科普篇)
Scikit-learn(简称sklearn)是Python中一个强大且易于使用的机器学习库,它基于NumPy、SciPy和matplotlib等Python库构建,提供了丰富的工具集,包括数据预处理、特征选择、模型训练、评估和预测等功能。以下是sklearn的详…...

el-table列的显示与隐藏
需求:实现 表字段的显示与隐藏。效果图 代码实现 写在前面 首先 我部分字段有自定义的排序逻辑,和默认值或者 数据的计算 所以是不能简单的使用 v-for 循环column 。然后 我需要默认展示一部分字段,并且 当表无数据时 提示不能 显示隐藏 …...

使用命令快速删除项目中的node_modules
描述 直接调用了系统自带的命令行工具,无需额外安装任何第三方库或工具。 同时,这些命令经过优化,能够快速处理大量文件,从而实现快速删除。 步骤 1、进入项目文件夹; 2、如果是Mac/Linux 环境下,执行&a…...

leetCode15三数之和(双指针)
目录 1、题目 2、思路 3、代码 4、总结 1、题目 给你一个由 n 个整数组成的数组 nums ,和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] (若两个四元组元素一一对应,则认为…...

数据挖掘-数据预处理
来自🥬🐶程序员 Truraly | 田园 的博客,最新文章首发于:田园幻想乡 | 原文链接 | github (欢迎关注) 文章目录 3.3.1 数据的中心趋势平均数和加权平均数众数,中位数和均值描述数据的离散程度 &a…...

【调试笔记-20240723-Linux-gitee 仓库同步 github 仓库,并保持所有访问链接调整为指向 gitee 仓库的 URL】
调试笔记-系列文章目录 调试笔记-20240723-Linux-gitee 仓库同步 github 仓库,并保持所有访问链接调整为指向 gitee 仓库的 URL 文章目录 调试笔记-系列文章目录调试笔记-20240723-Linux-gitee 仓库同步 github 仓库,并保持所有访问链接调整为指向 gite…...

《GPT-4o mini:开启开发与创新的新纪元》
在科技发展的快速进程中,OpenAI 推出的 GPT-4o mini 模型如同一阵春风,给开发者们带来了新的希望和机遇。它以其卓越的性能和极具吸引力的价格,成为了行业内热议的焦点。 当我首次听闻 GPT-4o mini 的消息时,内心充满了好奇与期待…...

生成树协议配置与分析
前言:本博客仅作记录学习使用,部分图片出自网络,如有侵犯您的权益,请联系删除 一、相关知识 1、生成树协议简介 生成树协议(STP)是一种避免数据链路层逻辑环路的机制,它通过信息交互识别环路并…...

Golang | Leetcode Golang题解之第287题寻找重复数
题目: 题解: func findDuplicate(nums []int) int {slow, fast : 0, 0for slow, fast nums[slow], nums[nums[fast]]; slow ! fast; slow, fast nums[slow], nums[nums[fast]] { }slow 0for slow ! fast {slow nums[slow]fast nums[fast]}return s…...

【音视频SDL2入门】创建第一个窗口
文章目录 前言创建窗口的流程需要使用的函数1. 初始化 SDL 库2. 创建 SDL 窗口3. 获取与窗口关联的表面SDL_FillRect 函数介绍4. 更新窗口表面5. 延迟一定时间6. 销毁窗口并退出 SDL 库示例代码总结 前言 SDL2(Simple DirectMedia Layer)是一个跨平台的…...

《置身事内:中国政府与经济发展》生活过得好一点,比大多数宏伟更宏伟
《置身事内:中国政府与经济发展》生活过得好一点,比大多数宏伟更宏伟 兰小欢,复旦大学中国社会主义市场经济研究中心、经济学院副教授,上海国际金融与经济研究院研究员。美国弗吉尼亚大学经济学博士。 上海人民出版社 文章目录 《…...

MongoDB教程(十八):MongoDB MapReduce
💝💝💝首先,欢迎各位来到我的博客,很高兴能够在这里和您见面!希望您在这里不仅可以有所收获,同时也能感受到一份轻松欢乐的氛围,祝你生活愉快! 文章目录 引言一、MapRed…...

HTML前端面试题之<iframe>标签
面试题:iframe 标签的作用是什么?有哪些优缺点 ? 讲真,刷这道面试题之前我根本没有接触过iframe,网课没讲过,项目实战没用过,但却在面试题里出现了!好吧,我只能说:前端路漫漫&…...

Docker-Compose实现MySQL之主从复制
1. 主服务器(IP:192.168.186.77) 1.1 docker-compose.yml services:mysql-master:image: mysql:latest # 使用最新版本的 MySQL 镜像container_name: mysql-master # 容器的名称environment:MYSQL_ROOT_PASSWORD: 123456 # MySQL root 用户的密码MYSQL_DATABASE: masterd…...

jetson显卡没有加速,而是在用cpu推理?
jetson的库,特别是使用显卡的库,大多需要单独安装 大概率是重装了pytorch,可以使用jetson官网的pytorch! 下面是官网的链接 PyTorch for Jetson - Announcements - NVIDIA Developer Forums 安装完成之后先使用命令查看是否安…...

Linux下如何安装配置Fail2ban防护工具
Fail2ban是一款在Linux服务器上用于保护系统免受恶意攻击的防护工具。它通过监视系统日志,检测到多次失败的登录尝试或其他恶意行为后,会自动将攻击源的IP地址加入防火墙的黑名单,从而阻止攻击者进一步访问服务器。本文将介绍如何在Linux系统…...

js的深浅拷贝
深浅拷贝是编程中对数据复制的两种不同方式,它们在处理对象和数组等复合数据结构时尤为重要。下面将详细解释这两种拷贝方式。 浅拷贝(Shallow Copy) 浅拷贝创建了原始对象的一个新实例,但这个新实例的属性只是原始对象属性的引…...

实验八: 彩色图像处理
目录 一、实验目的 二、实验原理 1. 常见彩色图像格式 2. 伪彩色图像 3. 彩色图像滤波 三、实验内容 四、源程序和结果 (1) 主程序(matlab (2) 函数FalseRgbTransf (3) 函数hsi2rgb (4) 函数rgb2hsi (5) 函数GrayscaleFilter (6) 函数RgbFilter 五、结果分析 1. …...

Python酷库之旅-第三方库Pandas(048)
目录 一、用法精讲 171、pandas.Series.nlargest方法 171-1、语法 171-2、参数 171-3、功能 171-4、返回值 171-5、说明 171-6、用法 171-6-1、数据准备 171-6-2、代码示例 171-6-3、结果输出 172、pandas.Series.nsmallest方法 172-1、语法 172-2、参数 172-3、…...

springboot爱宠屋宠物商店管理系统-计算机毕业设计源码52726
目录 摘要 1 绪论 1.1 选题背景与意义 1.2国内外研究现状 1.3论文结构与章节安排 2系统分析 2.1 可行性分析 2.2 系统流程分析 2.2.1系统开发流程 2.2.2 用户登录流程 2.2.3 系统操作流程 2.2.4 添加信息流程 2.2.5 修改信息流程 2.2.6 删除信息流程 2.3 系统功能…...