1 yolov8模型简介
YOLOv8(You Only Look Once version 8)是YOLO(You Only Look Once)系列模型的最新版本,延续了YOLO系列的实时目标检测方法。YOLOv8在架构、训练过程和性能方面做了多项改进,旨在提升检测精度和速度。以下是YOLOv8的主要特点和改进:
1. 改进的网络架构:
- YOLOv8采用了更新的架构设计,相比于之前的版本,它使用了更深层次的卷积神经网络,并结合了新的特征提取模块,如Focus、CSP(Cross Stage Partial Network)等,以提高模型的表达能力和特征提取能力。
2. 自适应锚框生成:
- YOLOv8引入了自适应锚框生成策略,这使得模型可以根据数据集自动调整锚框的大小和形状,从而提升了检测精度,特别是在处理多尺度目标时。
3. 改进的损失函数:
- YOLOv8采用了改进的损失函数,结合了分类损失、边界框回归损失和IoU(Intersection over Union)损失,进一步优化了模型的训练过程和收敛速度。
4. 混合数据增强:
- 为了增强模型的鲁棒性,YOLOv8引入了多种数据增强技术,如Mosaic增强、MixUp增强等,这些技术可以有效增加训练数据的多样性,减少过拟合风险。
5. 多任务学习:
- YOLOv8支持多任务学习,可以同时进行目标检测、实例分割和姿态估计等任务,这使得模型在多种计算机视觉任务中具有更广泛的应用。
6. 轻量化和高效推理:
- YOLOv8注重轻量化设计,在保持高精度的同时,减少了模型的参数量和计算量,适用于资源有限的设备,如嵌入式设备和移动设备。
7. 简化的部署:
- YOLOv8提供了更易于部署的模型格式和工具,支持多种硬件加速器(如GPU、TPU等)以及多种框架(如TensorFlow、PyTorch等),方便在不同平台上快速集成和应用。
YOLOv8的这些改进使其在多个目标检测任务中表现出色,广泛应用于自动驾驶、智能监控、机器人视觉、智慧城市等领域。
2 步骤
2.1 获取照片
方法一:浏览器爬取
我用的是Bing爬取
import os
import requests
from bs4 import BeautifulSoup
from PIL import Image
from io import BytesIO
import time
# 请求头部
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'
}
# 搜索URL
search_url = "https://www.bing.com/images/async?q={0}&first={1}&count={2}&scenario=ImageBasicHover&datsrc=N_I&layout=ColumnBased&mmasync=1"
def get_image_urls(search_term, num_images):
'''从Bing中获取图片URL'''
search_term_encoded = requests.utils.quote(search_term) # URL编码
urls = []
first = 1
count = 35 # 每页的图片数量
while len(urls) < num_images:
url = search_url.format(search_term_encoded, first, count)
response = requests.get(url, headers=headers)
soup = BeautifulSoup(response.text, 'html.parser')
# 查找图片URL
img_tags = soup.find_all("img")
for img_tag in img_tags:
img_url = img_tag.get('src')
if img_url and img_url.startswith('http'):
urls.append(img_url)
if len(urls) >= num_images:
break
first += count # 更新为下一页
time.sleep(1) # 防止过于频繁的请求
return urls
def download_images(image_urls, save_dir):
'''下载图片并保存到指定目录'''
if not os.path.exists(save_dir):
os.makedirs(save_dir)
for i, url in enumerate(image_urls):
try:
response = requests.get(url)
response.raise_for_status()
image = Image.open(BytesIO(response.content))
file_path = os.path.join(save_dir, f"Pi{i+1}.png")
image.save(file_path, format='PNG')
print(f"Downloaded {i+1}/{len(image_urls)}: {url}")
except requests.exceptions.HTTPError as e:
print(f"HTTP error occurred for {url}: {e}")
except Exception as e:
print(f"Could not download {url}: {e}")
# 主程序
if __name__ == '__main__':
search_term = # 搜索关键词
num_images = # 设置要下载的图片数量
save_dir = # 设置保存图片的目录
# 获取图片URL并下载图片
image_urls = get_image_urls(search_term, num_images)
if image_urls:
download_images(image_urls, save_dir)
else:
print("No images found or there was an error retrieving images.")
方法二:自己拍摄照片
这里注意自己拍摄的照片可能过大,需要进行压缩处理,否则后续程序会跑的很慢
压缩图片代码:
import os
import cv2
def resize_images(input_dir, output_dir, target_size):
# 如果输出目录不存在,则创建它
if not os.path.exists(output_dir):
os.makedirs(output_dir)
# 遍历输入目录中的所有文件
for img_name in os.listdir(input_dir):
img_path = os.path.join(input_dir, img_name)
# 读取图像
img = cv2.imread(img_path)
if img is not None:
# 调整图像大小
resized_img = cv2.resize(img, target_size)
# 保存调整后的图像到输出目录
output_path = os.path.join(output_dir, img_name)
cv2.imwrite(output_path, resized_img)
print(f"Resized and saved {img_name} to {output_dir}")
# 定义输入目录、输出目录和目标图像大小
input_dir = r
output_dir = r
target_size = (416, 416) # 目标分辨率
# 调整图像大小
resize_images(input_dir, output_dir, target_size)
当然,如果原图片是png等其他格式,可以转换成jpg格式
转换格式代码:
import os
import cv2
def convert_png_to_jpg(input_dir, output_dir):
# 如果输出目录不存在,则创建它
if not os.path.exists(output_dir):
os.makedirs(output_dir)
# 遍历输入目录中的所有文件
for img_name in os.listdir(input_dir):
if img_name.lower().endswith(".png"): # 检查是否为.png文件
img_path = os.path.join(input_dir, img_name)
# 读取图像
img = cv2.imread(img_path)
if img is not None:
# 修改文件扩展名为.jpg
base_name = os.path.splitext(img_name)[0]
output_name = base_name + ".jpg"
output_path = os.path.join(output_dir, output_name)
# 保存图像为JPEG格式
cv2.imwrite(output_path, img, [int(cv2.IMWRITE_JPEG_QUALITY), 95])
print(f"Converted {img_name} to {output_name} and saved to {output_dir}")
# 定义输入目录和输出目录
input_dir = r
output_dir = r
# 转换图像格式
convert_png_to_jpg(input_dir, output_dir)
2.2 圈画图片
这里建议采用labelimg软件进行圈画图片,若遇到打不开图片(无法打开jpg等格式的图片),那么可以考虑在命令行中输入labelimg后面加图片路径的形式
这一步能够生成.xml文件,这便是圈画的结果,这个.xml文件是用来跑Mx-yolov3软件内的yolov2模型的,就是借助这个操作获取分割好的数据集
原图片放置在JPEGImages文件夹内,.xml文件放置在Annotations文件夹内
然后再把.xml文件转为.txt文件,这个.txt文件是下面需要用到的
格式转换代码:
import xml.etree.ElementTree as ET
import os
def convert(size, box):
"""
Convert bounding box to YOLO format.
Arguments:
- size: (width, height) of the image
- box: (xmin, xmax, ymin, ymax) bounding box coordinates
Returns:
- (x_center, y_center, width, height) in YOLO format
"""
dw = 1.0 / size[0]
dh = 1.0 / size[1]
x_center = (box[0] + box[1]) / 2.0
y_center = (box[2] + box[3]) / 2.0
w = box[1] - box[0]
h = box[3] - box[2]
x_center = x_center * dw
w = w * dw
y_center = y_center * dh
h = h * dh
return (x_center, y_center, w, h)
def convert_annotation(xml_file, save_txt_file, classes):
"""
Convert VOC XML annotation to YOLO format and save as a .txt file.
Arguments:
- xml_file: path to the XML file
- save_txt_file: path to save the converted .txt file
- classes: list of class names
"""
tree = ET.parse(xml_file)
root = tree.getroot()
size = root.find('size')
w = int(size.find('width').text)
h = int(size.find('height').text)
with open(save_txt_file, 'w') as out_txt_f:
for obj in root.iter('object'):
difficult = obj.find('difficult').text
cls = obj.find('name').text
if cls not in classes or int(difficult) == 1:
continue
cls_id = classes.index(cls)
xmlbox = obj.find('bndbox')
b = (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text),
float(xmlbox.find('ymin').text), float(xmlbox.find('ymax').text))
bb = convert((w, h), b)
out_txt_f.write(f"{cls_id} " + " ".join([str(a) for a in bb]) + '\n')
def process_annotations(xml_files_path, save_txt_files_path, classes):
"""
Process all XML files in a directory and convert them to YOLO format.
Arguments:
- xml_files_path: directory containing XML files
- save_txt_files_path: directory to save the converted .txt files
- classes: list of class names
"""
if not os.path.exists(save_txt_files_path):
os.makedirs(save_txt_files_path)
xml_files = [f for f in os.listdir(xml_files_path) if f.endswith('.xml')]
for xml_name in xml_files:
xml_file = os.path.join(xml_files_path, xml_name)
save_txt_file = os.path.join(save_txt_files_path, xml_name.replace('.xml', '.txt'))
convert_annotation(xml_file, save_txt_file, classes)
print(f"Converted {xml_file} to {save_txt_file}")
if __name__ == "__main__":
# List of classes to be considered for conversion
classes1 = []#填写标签名称,按顺序
# Path to the directory containing XML files
xml_files1 = r#输入路径
# Path to the directory where YOLO format .txt files will be saved
save_txt_files1 = r#输出路径
process_annotations(xml_files1, save_txt_files1, classes1)
2.3 配置数据集
我采用的是Mx-yolov3软件(3.0版本不用配置环境,建议下这个),然后能够自动并且较为科学地分割出训练集和测试集,当然在这个之前建议把文件按顺序编号(两个格式,原图片和.txt),便于查找
分配编号代码:
import os
def rename_files_with_sequence(folder_path):
"""
Renames all files in the given folder with a sequence number.
Arguments:
- folder_path: the path to the folder containing the files to be renamed.
"""
# 获取文件夹中的所有文件(不包括文件夹)
files = [f for f in os.listdir(folder_path) if os.path.isfile(os.path.join(folder_path, f))]
# 对文件名进行自然排序
files.sort()
# 按顺序重命名文件
for index, filename in enumerate(files, start=1):
# 提取文件的扩展名
file_extension = os.path.splitext(filename)[1]
# 生成新的文件名(没有前缀)
new_name = f"{index}{file_extension}"
# 获取旧文件的完整路径
old_file = os.path.join(folder_path, filename)
# 获取新文件的完整路径
new_file = os.path.join(folder_path, new_name)
# 重命名文件
os.rename(old_file, new_file)
print(f"Renamed: {filename} -> {new_name}")
if __name__ == "__main__":
# 文件夹路径
folder_path = r # 请替换为你要处理的文件夹路径
# 调用重命名函数
rename_files_with_sequence(folder_path)
然后按照Mx-yolov3帮我们分割好的数据集代码,就可以挑选出.txt文件和原图片的数据集了
2.4 修改yolov8模型源代码的参数
这一部分可以参考他人的教程,最后跑完的结果就在runs文件里了
标签:txt,name,img,步骤,yolov8,path,识别,os,dir From: https://blog.csdn.net/m0_71934846/article/details/141093558