YOLOv8 segment介绍

      1.YOLOv8图像分割支持的数据格式:

      (1).用于训练YOLOv8分割模型的数据集标签格式如下:

      1).每幅图像对应一个文本文件:数据集中的每幅图像都有一个与图像文件同名的对应文本文件,扩展名为".txt";

      2).文本文件中每个目标(object)占一行:文本文件中的每一行对应图像中的一个目标实例;

      3).每行目标信息:如下所示:之间用空格分隔

      A.目标类别索引:整数,例如:0代表person,1代表car,等等;

      B.目标边界坐标:mask区域周围的边界坐标,归一化为[0, 1];

<class-index> <x1> <y1> <x2> <y2> ... <xn> <yn>

      :每行的长度不必相等;每个分隔label必须至少有3对xy点

      (2).数据集YAML格式:Ultralytics框架使用YAML文件格式来定义用于训练分隔模型的数据集和模型配置,如下面测试数据集melon中melon_seg.yaml内容如下: 在网上下载了60多幅包含西瓜和冬瓜的图像组成melon数据集

path: ../datasets/melon_seg # dataset root dir
train: images/train # train images (relative to 'path')
val: images/val  # val images (relative to 'path')
test: # test images (optional)

# Classes
names:
  0: watermelon
  1: wintermelon

      2.使用半自动标注工具 EISeg 对数据集melon进行标注:

      (1).从 PaddleSeg 中下载"通用场景的图像标注"高精度模型static_hrnet18_ocr64_cocolvis.zip;

      (2).标注前先按照下面操作设置好:

      1).选中JSON保存,取消COCO保存;

      2).选中自动保存;

      3).取消灰度保存.

      3.编写Python脚本将EISeg生成的json文件转换成YOLOv8 segment支持的txt文件:

import os
import json
import argparse
import colorama
import random
import shutil
import cv2

# supported image formats
img_formats = (".bmp", ".jpeg", ".jpg", ".png", ".webp")

def parse_args():
	parser = argparse.ArgumentParser(description="json(EISeg) to txt(YOLOv8)")

	parser.add_argument("--dir", required=True, type=str, help="images directory, all json files are in the label directory, and generated txt files are also in the label directory")
	parser.add_argument("--labels", required=True, type=str, help="txt file that hold indexes and labels, one label per line, for example: face 0")
	parser.add_argument("--val_size", default=0.2, type=float, help="the proportion of the validation set to the overall dataset:[0., 0.5]")
	parser.add_argument("--name", required=True, type=str, help="the name of the dataset")

	args = parser.parse_args()
	return args

def get_labels_index(name):
	labels = {} # key,value
	with open(name, "r") as file:
		for line in file:
			# print("line:", line)

			key_value = []
			for v in line.split(" "):
				# print("v:", v)
				key_value.append(v.replace("\n", "")) # remove line breaks(\n) at the end of the line
			if len(key_value) != 2:
				print(colorama.Fore.RED + "Error: each line should have only two values(key value):", len(key_value))
				continue

			labels[key_value[0]] = key_value[1]
		
	with open(name, "r") as file:
		line_num = len(file.readlines())

	if line_num != len(labels):
		print(colorama.Fore.RED + "Error: there may be duplicate lables:", line_num, len(labels))

	return labels

def get_json_files(dir):
	jsons = []
	for x in os.listdir(dir+"/label"):
		if x.endswith(".json"):
			jsons.append(x)

	return jsons

def parse_json(name_json, name_image):
	img = cv2.imread(name_image)
	if img is None:
		print(colorama.Fore.RED + "Error: unable to load image:", name_image)
		raise
	height, width = img.shape[:2]

	with open(name_json, "r") as file:
		data = json.load(file)

		objects=[]
		for i in range(0, len(data)):
			object = []
			object.append(data[i]["name"])
			object.append(data[i]["points"])
			objects.append(object)

	return width, height, objects

def write_to_txt(name_json, width, height, objects, labels):
	name_txt = name_json[:-len(".json")] + ".txt"
	# print("name txt:", name_txt)

	with open(name_txt, "w") as file:
		for obj in objects: # 0: name; 1: points
			if len(obj[1]) < 3:
				print(colorama.Fore.RED + "Error: must be at least 3 pairs:", len(obj[1]), name_json)
				raise
			
			if obj[0] not in labels:
				print(colorama.Fore.RED + "Error: unsupported label:", obj[0], labels)
				raise

			string = ""
			for pt in obj[1]:
				string = string + " " + str(round(pt[0] / width, 6)) + " " + str(round(pt[1] / height, 6))
			
			string = labels[obj[0]] + string + "\r"
			file.write(string)

def json_to_txt(dir, jsons, labels):
	for json in jsons:
		name_json = dir + "/label/" + json
		name_image = ""

		for format in img_formats:
			file = dir + "/" + json[:-len(".json")] + format
			if os.path.isfile(file):
				name_image = file
				break

		if not name_image:
			print(colorama.Fore.RED + "Error: required image does not exist:", json[:-len(".json")])
			raise
		# print("name image:", name_image)

		width, height, objects = parse_json(name_json, name_image)
		# print(f"width: {width}; height: {height}; objects: {objects}")

		write_to_txt(name_json, width, height, objects, labels)


def get_random_sequence(length, val_size):
	numbers = list(range(0, length))
	val_sequence = random.sample(numbers, int(length*val_size))
	# print("val_sequence:", val_sequence)

	train_sequence = [x for x in numbers if x not in val_sequence]
	# print("train_sequence:", train_sequence)

	return train_sequence, val_sequence

def get_files_number(dir):
	count = 0
	for file in os.listdir(dir):
		if os.path.isfile(os.path.join(dir, file)):
			count += 1

	return count

def split_train_val(dir, jsons, name, val_size):
	if val_size > 0.5 or val_size < 0.01:
		print(colorama.Fore.RED + "Error: the interval for val_size should be:[0.01, 0.5]:", val_size)
		raise

	dst_dir_images_train = "datasets/" + name + "/images/train"
	dst_dir_images_val = "datasets/" + name + "/images/val"
	dst_dir_labels_train = "datasets/" + name + "/labels/train"
	dst_dir_labels_val = "datasets/" + name + "/labels/val"

	try:
		os.makedirs(dst_dir_images_train) #, exist_ok=True
		os.makedirs(dst_dir_images_val)
		os.makedirs(dst_dir_labels_train)
		os.makedirs(dst_dir_labels_val)
	except OSError as e:
		print(colorama.Fore.RED + "Error: cannot create directory:", e.strerror)
		raise

	# print("jsons:", jsons)
	train_sequence, val_sequence = get_random_sequence(len(jsons), val_size)

	for index in train_sequence:
		for format in img_formats:
			file = dir + "/" + jsons[index][:-len(".json")] + format
			# print("file:", file)
			if os.path.isfile(file):
				shutil.copy(file, dst_dir_images_train)
				break

		file = dir + "/label/" + jsons[index][:-len(".json")] + ".txt"
		if os.path.isfile(file):
			shutil.copy(file, dst_dir_labels_train)

	for index in val_sequence:
		for format in img_formats:
			file = dir + "/" + jsons[index][:-len(".json")] + format
			if os.path.isfile(file):
				shutil.copy(file, dst_dir_images_val)
				break

		file = dir + "/label/" + jsons[index][:-len(".json")] + ".txt"
		if os.path.isfile(file):
			shutil.copy(file, dst_dir_labels_val)

	num_images_train = get_files_number(dst_dir_images_train)
	num_images_val = get_files_number(dst_dir_images_val)
	num_labels_train = get_files_number(dst_dir_labels_train)
	num_labels_val = get_files_number(dst_dir_labels_val)

	if  num_images_train + num_images_val != len(jsons) or num_labels_train + num_labels_val != len(jsons):
		print(colorama.Fore.RED + "Error: the number of files is inconsistent:", num_images_train, num_images_val, num_labels_train, num_labels_val, len(jsons))
		raise


def generate_yaml_file(labels, name):
	path = os.path.join("datasets", name, name+".yaml")
	# print("path:", path)
	with open(path, "w") as file:
		file.write("path: ../datasets/%s # dataset root dir\n" % name)
		file.write("train: images/train # train images (relative to 'path')\n")
		file.write("val: images/val  # val images (relative to 'path')\n")
		file.write("test: # test images (optional)\n\n")

		file.write("# Classes\n")
		file.write("names:\n")
		for key, value in labels.items():
			# print(f"key: {key}; value: {value}")
			file.write("  %d: %s\n" % (int(value), key))


if __name__ == "__main__":
	colorama.init()
	args = parse_args()

	# 1. parse JSON file and write it to a TXT file
	labels = get_labels_index(args.labels)
	# print("labels:", labels)
	jsons = get_json_files(args.dir)
	# print(f"jsons: {jsons}; number: {len(jsons)}")
	json_to_txt(args.dir, jsons, labels)

	# 2. split the dataset
	split_train_val(args.dir, jsons, args.name, args.val_size)

	# 3. generate a YAML file
	generate_yaml_file(labels, args.name)

	print(colorama.Fore.GREEN + "====== execution completed ======")

      以上脚本包含3个功能:

      1).将json文件转换成txt文件;

      2).将数据集随机拆分成训练集和测试集;

      3).产生需要的yaml文件

      4.编写Python脚本进行train:

import argparse
import colorama
from ultralytics import YOLO

def parse_args():
	parser = argparse.ArgumentParser(description="YOLOv8 train")
	parser.add_argument("--yaml", required=True, type=str, help="yaml file")
	parser.add_argument("--epochs", required=True, type=int, help="number of training")
	parser.add_argument("--task", required=True, type=str, choices=["detect", "segment"], help="specify what kind of task")

	args = parser.parse_args()
	return args

def train(task, yaml, epochs):
	if task == "detect":
		model = YOLO("yolov8n.pt") # load a pretrained model
	elif task == "segment":
		model = YOLO("yolov8n-seg.pt") # load a pretrained model
	else:
		print(colorama.Fore.RED + "Error: unsupported task:", task)
		raise

	results = model.train(data=yaml, epochs=epochs, imgsz=640) # train the model

	metrics = model.val() # It'll automatically evaluate the data you trained, no arguments needed, dataset and settings remembered

	model.export(format="onnx") #, dynamic=True) # export the model, cannot specify dynamic=True, opencv does not support
	# model.export(format="onnx", opset=12, simplify=True, dynamic=False, imgsz=640)
	model.export(format="torchscript") # libtorch

if __name__ == "__main__":
	colorama.init()
	args = parse_args()

	train(args.task, args.yaml, args.epochs)

	print(colorama.Fore.GREEN + "====== execution completed ======")

      执行结果如下图所示:会生成best.pt、best.onnx、best.torchscript

      5.生成的best.onnx使用Netron进行可视化,结果如下图所示:

      说明

      1).输入:images: float32[1,3,640,640] :与YOLOv8 detect一致,大小为3通道640*640

      2).输出:包括2层,output0和output1

      A.output0: float32[1,38,8400] :

      a.8400:模型预测的所有box的数量,与YOLOv8 detect一致;

      b.38: 每个框给出38个值:4:xc, yc, width, height;2:class, confidences;32:mask weights

      B.output1: float32[1,32,160,160] :最终mask大小是160*160;output1中的masks实际上只是原型masks,并不代表最终masks。为了得到某个box的最终mask,你可以将每个mask与其对应的mask weight相乘,然后将所有这些乘积相加。此外,你可以在box上应用NMS,以获得具有特定置信度阈值的box子集

      6.编写Python脚本实现predict:

import colorama
import argparse
from ultralytics import YOLO
import os

def parse_args():
	parser = argparse.ArgumentParser(description="YOLOv8 predict")
	parser.add_argument("--model", required=True, type=str, help="model file")
	parser.add_argument("--dir_images", required=True, type=str, help="directory of test images")
	parser.add_argument("--dir_result", required=True, type=str, help="directory where the image results are saved")

	args = parser.parse_args()
	return args

def get_images(dir):
	# supported image formats
	img_formats = (".bmp", ".jpeg", ".jpg", ".png", ".webp")
	images = []

	for file in os.listdir(dir):
		if os.path.isfile(os.path.join(dir, file)):
			# print(file)
			_, extension = os.path.splitext(file)
			for format in img_formats:
				if format == extension.lower():
					images.append(file)
					break

	return images

def predict(model, dir_images, dir_result):
	model = YOLO(model) # load an model
	model.info() # display model information

	images = get_images(dir_images)
	# print("images:", images)

	os.makedirs(dir_result) #, exist_ok=True)

	for image in images:
		results = model.predict(dir_images+"/"+image)
		for result in results:
			# print(result)
			result.save(dir_result+"/"+image)
			
if __name__ == "__main__":
	colorama.init()
	args = parse_args()

	predict(args.model, args.dir_images, args.dir_result)

	print(colorama.Fore.GREEN + "====== execution completed ======")

      执行结果如下图所示:

      其中一幅图像的分割结果如下图所示:以下是epochs设置为100时生成的best.pt的结果

      GitHub:https://github.com/fengbingchun/NN_Test

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

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

相关文章

OCR图片转Excel表格:没结构化的弊端

随着OCR技术的不断发展&#xff0c;将表格图片转为excel已不再是难题&#xff0c;但是&#xff0c;目前市面上的程序还大多处于仅能将图片表格转为普通的excel格式阶段&#xff0c;而不能将其结构化&#xff0c;这样就会产生许多的弊端&#xff0c;具体弊端如下&#xff1a; &l…

6个适合在家做的副业兼职,做得好的月入过万,适合上班族和宝妈

嘿&#xff0c;亲爱的朋友们&#xff01;是不是常常觉得钱包瘪瘪&#xff0c;却又因为种种原因无法外出兼职&#xff1f; 别急&#xff0c;我来为大家揭秘几个在家也能轻松赚钱的靠谱副业&#xff0c;让你足不出户也能月入过万&#xff0c;从此告别财务烦恼&#xff01; 副业一…

xcode删除依赖包package,删除不必要的依赖项

点击项目&#xff0c;然后点击PROJECT项里面的Package DepenDependencies&#xff1a; 选中一个依赖项&#xff0c;然后点击减号&#xff0c;就可以把依赖项删除掉了&#xff0c;左侧项目下面的Package已经没有了这个依赖项 TARGET下面的package也要删除&#xff1a;在这里删除…

OceanBase开发者大会实录-李楠:4条路径+6大方案,关键业务系统数据库的升级之路

本文来自2024 OceanBase开发者大会&#xff0c;OceanBase 金融与政企事业部解决方案总监李楠的演讲实录 ——《关键业务系统分布式数据库升级路线选择和技术演进之路》。完整视频回看&#xff0c;请点击这里&#xff1e;> 大家好&#xff0c;我是 OceanBase 金融与政企事业部…

第一周 数据结构与算法以及复杂度分析

数据结构与算法 算法定义 算法&#xff08;algorithm&#xff09;是在有限时间内解决特定问题的一组指令或操作步骤&#xff0c;它具有以下特性。 1.问题是明确的&#xff0c;包含清晰的输入和输出定义。 2.具有可行性&#xff0c;能够在有限步骤、时间和内存空间下完成。 3.…

利用WMI横向移动

一. WMI介绍和使用 1. WMI介绍 WMI是Windows在Powershell还未发布前&#xff0c;微软用来管理Windows系统的重要数据库工具&#xff0c;WMI本身的组织架构是一个数据库架构&#xff0c;WMI 服务使用 DCOM或 WinRM 协议, 在使用 wmiexec 进行横向移动时&#xff0c;windows 操…

小白跟做江科大32单片机之对射式红外传感器计次

原理部分 1中断示意图&#xff0c;中断会打断主函数的执行&#xff0c;终端执行完成之后再返回主函数继续执行 2.STM32中断 这些灰色的是内核中断 这些白色的是普通中断 3.NVIC统一管理中断&#xff0c;每个中断通道都拥有16个可编程的优先等级&#xff0c;可对优先级进行分组…

超大功率光伏并网逆变器学习(三相)

1.超大功率用的IGBT开关频率通常很低,比如6KHz 2.线电压和相电压的关系 相电压 A AB线电压-CA线电压 相电压 B BC线电压-AB线电压 相电压 C CA线电压-BC线电压 3.坐标变换 ABC三相信号通过Clark坐标变换得到αβ两相静止信号,其中α与A相重合,β与α…

ElasticSearch教程(详解版)

本篇博客将向各位详细介绍elasticsearch&#xff0c;也算是对我最近学完elasticsearch的一个总结&#xff0c;对于如何在Kibana中使用DSL指令&#xff0c;本篇文章不会进行介绍&#xff0c;这里只会介绍在java中如何进行使用&#xff0c;保证你看完之后就会在项目中进行上手&am…

为何选择 MindMapper

MindMapper是一款专业的可视化思维导图软件&#xff0c;通过智能绘图方法&#xff0c;在管理信息和 处理工作流程中&#xff0c;帮助提高组织、审查、合作、分享和交流能力。 企业创造力 在企业界&#xff0c;MindMapper思维导图软件可以提高生产力和沟通效果&#xff0c;以及…

复试不考机试,初试300分以上,上岸稳了?东北林业大学计算机考研考情分析!

东北林业大学&#xff08;Northeast Forestry University&#xff09;&#xff0c;简称东北林大&#xff08;NEFU&#xff09;&#xff0c;位于黑龙江省哈尔滨市&#xff0c;是一所以林科为优势、林业工程为特色的中华人民共和国教育部直属高校&#xff0c;由教育部、国家林业局…

LIO-EKF: 运行数据UrbanNav与mid360设备详细教程

一、代码连接 代码下载连接&#xff1a; YibinWu/LIO-EKF: Maybe the simplest LiDAR-inertial odometry that one can have. (github.com) 编译步骤&#xff1a; cd srcgit clone gitgithub.com:YibinWu/LIO-EKF.gitcatkin_makesource devel/setup.bash 运行步骤&#xff1a; …

2024年6月1日 (周六) 叶子游戏新闻

Embracer探讨单机游戏大作涨价超过70美元的可能性在Embracer集团等待公布新公司名称的同时&#xff0c;他们对游戏大作的价格上涨做出了评论。几年来&#xff0c;游戏大作的价格已经达到了70美元的门槛。Embracer集团的CEO Lars Wingefors在采访中表示&#xff0c;电子游戏行业…

STM32 定时器与PWM的LED控制

学习目标&#xff1a; 1. 使用定时器的某一个通道控制LED周期性亮灭&#xff1b; 2. 采用定时器PWM模式&#xff0c;让 LED 以呼吸灯方式渐亮渐灭。 一、定时器 1、STM32定时器介绍 STMicroelectronics是STM32微控制器中的重要块&#xff0c;具有丰富的外设和功能&#xff0…

纯Java实现Google地图的KMZ和KML文件的解析

目录 前言 一、关于KMZ和KML 1、KMZ是什么 2、KML是什么 二、Java解析实例 1、POM.xml引用 2、KML 基类定义 3、空间对象的定义 4、Kml解析工具类 三、KML文件的解析 1、KML解析测试 2、KMZ解析测试 四、总结 前言 今天是六.一儿童节&#xff0c;在这里祝各位大朋友…

网络运维的重要性

一、介绍 网络运维&#xff0c;英文名为Network Operations (NetOps)&#xff0c;指的是负责维护和管理企业或组织内部网络设备和系统的团队或个人。网络运维的主要目标是确保网络的稳定运行和高效性能&#xff0c;以满足企业或组织的需求。 网络运维工作涵盖了多个方面&…

5.算法讲解之-二分查找(简单易懂)

1.简介 1.二分查找的思路简单易懂&#xff0c;较难的是如何处理查找过程中的边界条件&#xff0c;当较长时间没写二分查找的时候就容易忘记如何处理边界条件。 2.只有多写代码&#xff0c;多做笔记就不易忘记边界条件 2.算法思路 正常查找都是从头到尾查找一个数字是否在数组中…

WIFI 万[néng]钥匙 v5.0.10/v4.9.80 SVIP版!

WiFi Master Key v5.0.10/v4.9.80 WIFI万[Nng]钥匙APP是一款专业的网络连接工具&#xff0c;设计宗旨在于为用户提供方便快捷的WiFi接入方案。本应用集成了覆盖全国的大量免费WiFi热点信息&#xff0c;确保用户能够在不同地区快速而稳定地连接到互联网。此外&#xff0c;该应用…

UMLChina为什么叒要翻译《分析模式》?

UMLChina受机械工业出版社委托&#xff0c;重新翻译《分析模式》。 Martin Fowler的“Analysis Patterns&#xff0c;Reusable Object Models”&#xff0c;原书出版于1997年&#xff0c;至今为止未出第2版。 2004年&#xff0c;机械工业出版社出版该书中译本《分析模式》。 …

Llama 3-V: 比GPT4-V小100倍的SOTA

大模型技术论文不断&#xff0c;每个月总会新增上千篇。本专栏精选论文重点解读&#xff0c;主题还是围绕着行业实践和工程量产。若在某个环节出现卡点&#xff0c;可以回到大模型必备腔调重新阅读。而最新科技&#xff08;Mamba&#xff0c;xLSTM,KAN&#xff09;则提供了大模…