將 tensorflow keras 訓練數據集轉換為 Yolo 訓練數據集

以?https://www.kaggle.com/datasets/vipoooool/new-plant-diseases-dataset 為例

1.? 圖像分類數據集文件結構 (例如用于 yolov11n-cls.pt 訓練)

import os
import csv
import random
from PIL import Image
from sklearn.model_selection import train_test_split
import shutil# ====================== 配置參數 ======================
# 從 Kaggle Hub 下載植物病害數據集
# https://www.kaggle.com/datasets/vipoooool/new-plant-diseases-dataset
import kagglehub
tf_download_path = kagglehub.dataset_download("vipoooool/new-plant-diseases-dataset")
print("Path to dataset files:", tf_download_path)
# 定義數據集路徑
tf_dataset_path = f"{tf_download_path}/New Plant Diseases Dataset(Augmented)/New Plant Diseases Dataset(Augmented)"INPUT_DATA_DIR = tf_dataset_path  # 輸入數據集路徑(解壓后的根目錄)
OUTPUT_YOLO_DIR = "./runs/traindata/yolo/yolo_plant_diseases_classify"        # 輸出YOLO數據集路徑
if os.path.exists(OUTPUT_YOLO_DIR):shutil.rmtree(OUTPUT_YOLO_DIR)
os.makedirs(OUTPUT_YOLO_DIR, exist_ok=True)TRAIN_SIZE = 0.8                                 # 訓練集比例
IMAGE_EXTENSIONS = [".JPG", ".jpg", ".jpeg", ".png"]     # 支持的圖像擴展名# ====================== 類別映射(需根據實際數據集調整) ======================
# 從原數據集的類別名稱生成映射(示例:假設病害類別為文件夾名)
def get_class_mapping(data_dir):class_names = []for folder in os.listdir(data_dir):folder_path = os.path.join(data_dir, folder)if os.path.isdir(folder_path) and not folder.startswith("."):class_names.append(folder)class_names.sort()  # 按字母序排序,確保類別編號固定return {cls: idx for idx, cls in enumerate(class_names)}# ====================== 劃分數據集并保存 ======================
def save_dataset(annotations, class_map, output_dir, train_size=0.8):# 劃分訓練集和驗證集random.shuffle(annotations)split_idx = int(len(annotations) * train_size)train_data = annotations[:split_idx]val_data = annotations[split_idx:]# 創建目錄結構os.makedirs(os.path.join(output_dir, "train"), exist_ok=True)os.makedirs(os.path.join(output_dir, "val"), exist_ok=True)for cls in class_map.keys():os.makedirs(os.path.join(output_dir, "train", cls), exist_ok=True)os.makedirs(os.path.join(output_dir, "val", cls), exist_ok=True)# 保存訓練集for data in train_data:img_path = data["image_path"]cls = data["class_name"]try:shutil.copy2(img_path, os.path.join(output_dir, "train", cls))print(f"圖像 {img_path} 復制到訓練集 {cls} 類成功")except Exception as e:print(f"圖像 {img_path} 復制到訓練集 {cls} 類失敗,錯誤信息: {e}")# 保存驗證集for data in val_data:img_path = data["image_path"]cls = data["class_name"]try:shutil.copy2(img_path, os.path.join(output_dir, "val", cls))print(f"圖像 {img_path} 復制到驗證集 {cls} 類成功")except Exception as e:print(f"圖像 {img_path} 復制到驗證集 {cls} 類失敗,錯誤信息: {e}")# 生成類別名文件(classes.names)with open(os.path.join(output_dir, "classes.names"), "w") as f:for cls in class_map.keys():f.write(f"{cls}\n")# 生成數據集配置文件(dataset.yaml)yaml_path = os.path.join(output_dir, "dataset.yaml")with open(yaml_path, "w") as f:f.write(f"path: {output_dir}\n")  # 數據集根路徑f.write(f"train: train\n")  # 訓練集路徑(相對于path)f.write(f"val: val\n")      # 驗證集路徑# f.write(f"test: images/test\n")   # 測試集路徑(如果有)f.write(f"nc: {len(class_map)}\n")  # 類別數# 修改 names 字段輸出格式class_names = list(class_map.keys())f.write(f"names: {class_names}\n")return train_data, val_data# ====================== 主函數 ======================
if __name__ == "__main__":# 1. 檢查輸入路徑是否存在if not os.path.exists(INPUT_DATA_DIR):raise FileNotFoundError(f"請先下載數據集并解壓到路徑:{INPUT_DATA_DIR}")# 2. 獲取類別映射(假設圖像按類別存放在子文件夾中)class_map = get_class_mapping(os.path.join(INPUT_DATA_DIR, "train"))  # 假設訓練集圖像在train子文件夾中,每個子文件夾為一個類別# 3. 解析標注(僅按文件夾分類)annotations = []for cls, idx in class_map.items():cls_dir = os.path.join(INPUT_DATA_DIR, "train", cls)  # 假設類別文件夾路徑為train/類別名for img_file in os.listdir(cls_dir):if any(img_file.lower().endswith(ext) for ext in IMAGE_EXTENSIONS):img_path = os.path.join(cls_dir, img_file)annotations.append({"image_path": img_path,"class_name": cls})# 4. 保存為YOLO格式train_data, val_data = save_dataset(annotations, class_map, OUTPUT_YOLO_DIR, train_size=TRAIN_SIZE)print(f"? 轉換完成!YOLO數據集已保存至:{OUTPUT_YOLO_DIR}")print(f"類別數:{len(class_map)},訓練集樣本數:{len(train_data)},驗證集樣本數:{len(val_data)}")

train的時候,使用的文件夾

2. 目標檢測數據集文件結構 (例如用于 yolo11n.pt 訓練)

import os
import csv
import random
from PIL import Image
from sklearn.model_selection import train_test_split
import shutil# ====================== 配置參數 ======================
# 從 Kaggle Hub 下載植物病害數據集
# https://www.kaggle.com/datasets/vipoooool/new-plant-diseases-dataset
import kagglehub
tf_download_path = kagglehub.dataset_download("vipoooool/new-plant-diseases-dataset")
print("Path to dataset files:", tf_download_path)
# 定義數據集路徑
tf_dataset_path = f"{tf_download_path}/New Plant Diseases Dataset(Augmented)/New Plant Diseases Dataset(Augmented)"INPUT_DATA_DIR = tf_dataset_path  # 輸入數據集路徑(解壓后的根目錄)
OUTPUT_YOLO_DIR = "./traindata/yolo/yolo_plant_diseases"        # 輸出YOLO數據集路徑
if os.path.exists(OUTPUT_YOLO_DIR):shutil.rmtree(OUTPUT_YOLO_DIR)
os.makedirs(OUTPUT_YOLO_DIR, exist_ok=True)TRAIN_SIZE = 0.8                                 # 訓練集比例
IMAGE_EXTENSIONS = [".JPG", ".jpg", ".jpeg", ".png"]     # 支持的圖像擴展名# ====================== 類別映射(需根據實際數據集調整) ======================
# 從原數據集的類別名稱生成映射(示例:假設病害類別為文件夾名)
def get_class_mapping(data_dir):class_names = []for folder in os.listdir(data_dir):folder_path = os.path.join(data_dir, folder)if os.path.isdir(folder_path) and not folder.startswith("."):class_names.append(folder)class_names.sort()  # 按字母序排序,確保類別編號固定return {cls: idx for idx, cls in enumerate(class_names)}# ====================== 解析CSV標注(假設標注在CSV中) ======================
def parse_csv_annotations(csv_path, class_map, image_dir):annotations = []with open(csv_path, "r", encoding="utf-8") as f:reader = csv.DictReader(f)for row in reader:image_name = row["image_path"]class_name = row["disease_class"]  # 需與CSV中的類別列名一致x_min = float(row["x_min"])y_min = float(row["y_min"])x_max = float(row["x_max"])y_max = float(row["y_max"])# 檢查圖像是否存在image_path = os.path.join(image_dir, image_name)if not os.path.exists(image_path):continue# 獲取圖像尺寸with Image.open(image_path) as img:img_width, img_height = img.size# 轉換為YOLO坐標center_x = (x_min + x_max) / 2 / img_widthcenter_y = (y_min + y_max) / 2 / img_heightwidth = (x_max - x_min) / img_widthheight = (y_max - y_min) / img_heightannotations.append({"image_path": image_path,"class_id": class_map[class_name],"bbox": (center_x, center_y, width, height)})return annotations# ====================== 劃分數據集并保存 ======================
def save_dataset(annotations, class_map, output_dir, train_size=0.8):# 劃分訓練集和驗證集random.shuffle(annotations)split_idx = int(len(annotations) * train_size)train_data = annotations[:split_idx]val_data = annotations[split_idx:]# 創建目錄結構os.makedirs(os.path.join(output_dir, "images/train"), exist_ok=True)os.makedirs(os.path.join(output_dir, "images/val"), exist_ok=True)os.makedirs(os.path.join(output_dir, "labels/train"), exist_ok=True)os.makedirs(os.path.join(output_dir, "labels/val"), exist_ok=True)# 保存訓練集for data in train_data:img_path = data["image_path"]lbl_path = os.path.join(output_dir, "labels/train",os.path.splitext(os.path.basename(img_path))[0] + ".txt")# 復制圖像try:shutil.copy2(img_path, os.path.join(output_dir, 'images/train'))print(f"圖像 {img_path} 復制到訓練集成功")except Exception as e:print(f"圖像 {img_path} 復制到訓練集失敗,錯誤信息: {e}")# 保存標注with open(lbl_path, "w") as f:f.write(f"{data['class_id']} {' '.join(map(str, data['bbox']))}\n")# 保存驗證集for data in val_data:img_path = data["image_path"]lbl_path = os.path.join(output_dir, "labels/val",os.path.splitext(os.path.basename(img_path))[0] + ".txt")# 復制圖像try:shutil.copy2(img_path, os.path.join(output_dir, 'images/val'))print(f"圖像 {img_path} 復制到驗證集成功")except Exception as e:print(f"圖像 {img_path} 復制到驗證集失敗,錯誤信息: {e}")# 保存標注with open(lbl_path, "w") as f:f.write(f"{data['class_id']} {' '.join(map(str, data['bbox']))}\n")# 生成類別名文件(classes.names)with open(os.path.join(output_dir, "classes.names"), "w") as f:for cls in class_map.keys():f.write(f"{cls}\n")# 生成數據集配置文件(dataset.yaml)yaml_path = os.path.join(output_dir, "dataset.yaml")with open(yaml_path, "w") as f:f.write(f"path: {output_dir}\n")  # 數據集根路徑f.write(f"train: images/train\n")  # 訓練集路徑(相對于path)f.write(f"val: images/val\n")      # 驗證集路徑# f.write(f"test: images/test\n")   # 測試集路徑(如果有)f.write(f"nc: {len(class_map)}\n")  # 類別數f.write("names:\n")for idx, cls in enumerate(class_map.keys()):f.write(f"  {idx}: {cls}\n")return train_data, val_data# ====================== 主函數 ======================
if __name__ == "__main__":# 1. 檢查輸入路徑是否存在if not os.path.exists(INPUT_DATA_DIR):raise FileNotFoundError(f"請先下載數據集并解壓到路徑:{INPUT_DATA_DIR}")# 2. 獲取類別映射(假設圖像按類別存放在子文件夾中,無CSV標注時使用此方法)# 若有CSV標注,需手動指定CSV路徑和列名,注釋掉下方代碼并取消注釋parse_csv_annotations部分class_map = get_class_mapping(os.path.join(INPUT_DATA_DIR, "train"))  # 假設訓練集圖像在train子文件夾中,每個子文件夾為一個類別# 3. 解析標注(根據實際情況選擇CSV或文件夾分類)# 情況A:無標注,僅按文件夾分類(弱監督,邊界框為圖像全尺寸)annotations = []for cls, idx in class_map.items():cls_dir = os.path.join(INPUT_DATA_DIR, "train", cls)  # 假設類別文件夾路徑為train/類別名for img_file in os.listdir(cls_dir):if any(img_file.lower().endswith(ext) for ext in IMAGE_EXTENSIONS):img_path = os.path.join(cls_dir, img_file)with Image.open(img_path) as img:img_width, img_height = img.size# 邊界框為全圖(弱監督場景,僅用于分類任務,非檢測)annotations.append({"image_path": img_path,"class_id": idx,"bbox": (0.5, 0.5, 1.0, 1.0)  # 全圖邊界框})# # 情況B:有CSV標注(需取消注釋以下代碼并調整參數)# CSV_PATH = os.path.join(INPUT_DATA_DIR, "labels.csv")  # CSV標注文件路徑# IMAGE_DIR = os.path.join(INPUT_DATA_DIR, "images")     # 圖像根目錄# class_map = {"Apple Scab": 0, "Black Rot": 1, ...}    # 手動定義類別映射# annotations = parse_csv_annotations(CSV_PATH, class_map, IMAGE_DIR)# 4. 保存為YOLO格式train_data, val_data = save_dataset(annotations, class_map, OUTPUT_YOLO_DIR, train_size=TRAIN_SIZE)print(f"? 轉換完成!YOLO數據集已保存至:{OUTPUT_YOLO_DIR}")print(f"類別數:{len(class_map)},訓練集樣本數:{len(train_data)},驗證集樣本數:{len(val_data)}")

train的時候,使用的yaml文件路徑

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/86172.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/86172.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/86172.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

排序算法-歸并排序與快速排序

歸并排序與快速排序 快速排序是利用的遞歸思想:選取一個基準數,把小于基準數的放左邊 大于的放右邊直到整個序列有序 。快排分割函數 O(lognn), 空間 :沒有額外開辟新的數組但是遞歸樹調用函數會占用棧內存 O(logn) 。 歸并排序:在遞歸返回的…

北大開源音頻編輯模型PlayDiffusion,可實現音頻局部編輯,比傳統 AR 模型的效率高出 50 倍!

北大開源了一個音頻編輯模型PlayDiffusion,可以實現類似圖片修復(inpaint)的局部編輯功能 - 只需修改音頻中的特定片段,而無需重新生成整段音頻。此外,它還是一個高性能的 TTS 系統,比傳統 AR 模型的效率高出 50 倍。 自回歸 Tra…

MyBatis————入門

1,配置相關 我們上一期詳細講了一下使用注解來實現操作數據庫的方式,我們今天使用xml來實現,有同學可能有疑問,使用注解挺方便呀,為啥還要注解呀,先來說一下注解我感覺挺麻煩的,但是我們后面要…

【推薦算法】推薦算法演進史:從協同過濾到深度強化學習

推薦算法演進史:從協同過濾到深度強化學習 一、傳統推薦時代:協同過濾的奠基(1990s-2006)1.1 算法背景:信息爆炸的挑戰1.2 核心算法:協同過濾1.3 局限性 二、深度學習黎明:神經網絡初探&#xf…

Java基于SpringBoot的校園閑置物品交易系統,附源碼+文檔說明

博主介紹:?Java老徐、7年大廠程序員經歷。全網粉絲12w、csdn博客專家、掘金/華為云/阿里云/InfoQ等平臺優質作者、專注于Java技術領域和畢業項目實戰? 🍅文末獲取源碼聯系🍅 👇🏻 精彩專欄推薦訂閱👇&…

Ajax Systems公司的核心產品有哪些?

Ajax Systems 是一家專注于家庭安全和智能系統的公司,其核心產品如下3: 入侵保護設備:如 MotionCam Outdoor 無線室外運動探測器,配備內置攝像頭和兩個紅外傳感器,可通過預裝電池運行長達三年,能在 15 米距…

64、js 中require和import有何區別?

在 JavaScript 中,require 和 import 都是用于模塊導入的語法,但它們屬于不同的模塊系統,具有顯著的區別: 1. 模塊系統不同 require 屬于 CommonJS 模塊系統(Node.js 默認使用)。 語法:const…

Java+Access綜合測評系統源碼分享:含論文、開題報告、任務書全套資料

JAVAaccess綜合測評系統畢業設計 一、系統概述 本系統采用Java Swing開發前端界面,結合Access數據庫實現數據存儲,專為教育機構打造的綜合測評解決方案。系統包含學生管理、題庫管理、在線測評、成績分析四大核心模塊,實現了測評流程的全自…

【python】RGB to YUV and YUV to RGB

文章目錄 1、YUV2、YUV vs RGB3、RGB to YUV4、YUV to RGB附錄——YUV NV12 vs YUV NV21參考1、YUV YUV 顏色空間,又常被稱作 YCbCr 顏色空間,是用于數字電視的顏色空間,在 ITU-R BT.601、BT.709、BT.2020 標準中被明確定義,這三種標準分別針對標清、高清、超高清數字電視…

運行示例程序和一些基本操作

歡迎 ----> 示例 --> 選擇sample CTRL B 編譯代碼 CTRL R 運行exe 項目 中 Shadow build 表示是否 編譯生成文件和 源碼是否放一塊 勾上不在同一個地方 已有項目情況下怎么打開項目 方法一: 左鍵雙擊 xxx.pro 方法二: 文件菜單里面 選擇打開項目

計算機網絡第2章(下):物理層傳輸介質與核心設備全面解析

目錄 一、傳輸介質1.1 傳輸介質的分類1.2 導向型傳輸介質1.2.1 雙絞線(Twisted Pair)1.2.2 同軸電纜(Coaxial Cable)1.2.3 光纖(Optical Fiber)1.2.4 以太網對有線傳輸介質的命名規則 1.3 非導向型傳輸介質…

PHP文件包含漏洞詳解:原理、利用與防御

PHP文件包含漏洞詳解:原理、利用與防御 什么是文件包含漏洞? 文件包含漏洞是PHP應用程序中常見的安全問題,當開發者使用包含函數引入文件時,如果傳入的文件名參數未經嚴格校驗,攻擊者就可能利用這個漏洞讀取敏感文件…

5.4.2 Spring Boot整合Redis

本次實戰主要圍繞Spring Boot與Redis的整合展開,首先創建了一個Spring Boot項目,并配置了Redis的相關屬性。接著,定義了三個實體類:Address、Family和Person,分別表示地址、家庭成員和個人信息,并使用Index…

java內存模型JMM

Java 內存模型(Java Memory Model,JMM)定義了 Java 程序中的變量、線程如何和本地內存以及主內存進行交互的規則。它主要涉及到多線程環境下的共享變量可見性、指令重排等問題,是理解并發編程中的關鍵概念。 核心概念&#xff1a…

配置git命令縮寫

以下是 Git 命令縮寫的配置方法及常用方案,適用于 Linux/macOS/Windows 系統: 🔧 一、配置方法 1. 命令行設置(推薦) # 基礎命令縮寫 git config --global alias.st status git config --global alias.co che…

準確--k8s cgroup問題排查

k8s cgroup問題排查 6月 06 17:20:39 k8s-node01 containerd[1515]: time"2025-06-06T17:20:39.42902033408:00" levelerror msg"StartContainer fo r \"46ae0ef9618b96447a1f28fd2229647fe671e8acbcec02c8c46b37051130c8c4\" failed" error&qu…

Go 中 map 的雙值檢測寫法詳解

Go 中 map 的雙值檢測寫法詳解 在 Go 中,if char, exists : pairs[s[i]]; exists { 是一種利用 Go 語言特性編寫的優雅條件語句,用于檢測 map 中是否存在某個鍵。讓我們分解解釋這種寫法: 語法結構解析 if value, ok : mapVariable[key]; …

C# Wkhtmltopdf HTML轉PDF碰到的問題

最近碰到一個Html轉PDF的需求,看了一下基本上都是需要依賴Wkhtmltopdf,需要在Windows或者linux安裝這個可以后使用。找了一下選擇了HtmlToPDFCore,這個庫是對Wkhtmltopdf.NetCore簡單二次封裝,這個庫的好處就是通過NuGet安裝HtmlT…

grafana 批量視圖備份及恢復(含數據源)

一、grafana 批量視圖備份 import requests import json import urllib3 import osfrom requests.auth import HTTPBasicAuthfilename_folders_map "folders_map.json" type_folder "dash-folder" type_dashboard "dash-db"# Grafana服務器地…

.Net Framework 4/C# 關鍵字(非常用,持續更新...)

一、is 關鍵字 is 關鍵字用于檢查對象是否于給定類型兼容,如果兼容將返回 true,如果不兼容則返回 false,在進行類型轉換前,可以先使用 is 關鍵字判斷對象是否與指定類型兼容,如果兼容才進行轉換,這樣的轉換是安全的。 例如有:首先創建一個字符串對象,然后將字符串對象隱…