dataset / index.html
aaurelions's picture
Upload 3 files
22a2915 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>YOLOSet: Data Factory</title>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://unpkg.com/feather-icons"></script>
<link rel="stylesheet" href="style.css">
</head>
<body class="select-none overflow-hidden">
<canvas id="main-canvas" class="absolute top-0 left-0 w-full h-full outline-none z-0"></canvas>
<div id="loader-overlay"
class="absolute inset-0 bg-stone-950 flex flex-col items-center justify-center z-50 transition-opacity duration-500">
<div class="loader-spinner"></div>
<p id="loader-text" class="mt-4 text-xl tracking-wider text-stone-300">Initializing...</p>
</div>
<div id="notification-container"
class="fixed bottom-5 left-1/2 -translate-x-1/2 z-[60] flex flex-col items-center gap-2 w-[90vw] max-w-md">
</div>
<div id="dataset-modal" class="modal-overlay fixed inset-0 z-40 hidden items-center justify-center p-4">
<div class="glass-ui rounded-lg w-full max-w-5xl mx-auto flex flex-col max-h-[90vh]">
<header class="p-5 pb-4 flex-shrink-0 border-b border-white/10">
<h3 class="text-2xl font-bold text-center tracking-wide">Generate Synthetic Dataset</h3>
</header>
<div class="overflow-y-auto px-6 py-5 flex-grow">
<div class="grid grid-cols-1 lg:grid-cols-5 gap-6">
<div class="lg:col-span-2 flex flex-col gap-6">
<div class="bg-stone-900/50 rounded-lg p-4 border border-white/10">
<h4 class="text-lg font-semibold text-stone-300 mb-4 border-b border-white/10 pb-2">Core
Settings</h4>
<div class="space-y-4">
<div>
<label for="dataset-name"
class="block text-sm font-medium text-stone-300 mb-2">Dataset Name</label>
<input type="text" id="dataset-name" value="my_synthetic_dataset"
class="w-full bg-stone-800/70 p-2 rounded-md border-2 border-stone-600 focus:border-blue-500 outline-none transition">
</div>
<div>
<label for="dataset-samples"
class="block text-sm font-medium text-stone-300 mb-2">Total Number of
Samples</label>
<input type="number" id="dataset-samples" value="100" min="10" max="100000"
class="w-full bg-stone-800/70 p-2 rounded-md border-2 border-stone-600 focus:border-blue-500 outline-none transition">
</div>
</div>
</div>
<div class="bg-stone-900/50 rounded-lg p-4 border border-white/10">
<h4 class="text-lg font-semibold text-stone-300 mb-4 border-b border-white/10 pb-2">
Annotation</h4>
<div class="space-y-4">
<div>
<label class="block text-sm font-medium text-stone-300 mb-3">Task Type</label>
<div class="space-y-2">
<div>
<input type="radio" name="dataset-task" value="detection"
id="task-detection" class="sr-only">
<label for="task-detection"
class="task-radio-label p-3 rounded-lg block cursor-pointer text-left flex items-center gap-3">
<i data-feather="box" class="w-5 h-5 text-blue-400"></i>
<div>
<h5 class="font-semibold text-sm leading-tight">Object Detection
</h5>
<p class="text-xs text-stone-400 mt-0.5">Generates bounding boxes
(YOLO).</p>
</div>
</label>
</div>
<div>
<input type="radio" name="dataset-task" value="segmentation"
id="task-segmentation" class="sr-only" checked>
<label for="task-segmentation"
class="task-radio-label p-3 rounded-lg block cursor-pointer text-left flex items-center gap-3">
<i data-feather="pen-tool" class="w-5 h-5 text-blue-400"></i>
<div>
<h5 class="font-semibold text-sm leading-tight">Instance
Segmentation</h5>
<p class="text-xs text-stone-400 mt-0.5">Generates polygon masks
(YOLO).</p>
</div>
</label>
</div>
<div>
<input type="radio" name="dataset-task" value="classification"
id="task-classification" class="sr-only">
<label for="task-classification"
class="task-radio-label p-3 rounded-lg block cursor-pointer text-left flex items-center gap-3">
<i data-feather="tag" class="w-5 h-5 text-blue-400"></i>
<div>
<h5 class="font-semibold text-sm leading-tight">Image Classification
</h5>
<p class="text-xs text-stone-400 mt-0.5">Organizes images into class
folders.</p>
</div>
</label>
</div>
</div>
</div>
<div id="segmentation-method-group" class="space-y-2 pt-2">
<label class="block text-sm font-medium text-stone-300">Segmentation Method</label>
<div class="grid grid-cols-1 sm:grid-cols-3 gap-3">
<div>
<input type="radio" name="segmentation-method" value="convex"
id="method-convex" class="sr-only">
<label for="method-convex"
class="method-radio-label p-3 rounded-lg block cursor-pointer text-center">
<h5 class="font-semibold text-sm">Convex Hull</h5>
<p class="text-xs text-stone-400 mt-1">Fastest</p>
</label>
</div>
<div>
<input type="radio" name="segmentation-method" value="concave"
id="method-concave" class="sr-only">
<label for="method-concave"
class="method-radio-label p-3 rounded-lg block cursor-pointer text-center">
<h5 class="font-semibold text-sm">Concave Hull</h5>
<p class="text-xs text-stone-400 mt-1">Accurate</p>
</label>
</div>
<div>
<input type="radio" name="segmentation-method" value="render"
id="method-render" class="sr-only" checked>
<label for="method-render"
class="method-radio-label p-3 rounded-lg block cursor-pointer text-center">
<h5 class="font-semibold text-sm">Render Mask</h5>
<p class="text-xs text-stone-400 mt-1">Slowest</p>
</label>
</div>
</div>
<div id="concave-hull-options" style="max-height: 0; opacity: 0; overflow: hidden;">
<div class="pt-3 space-y-2">
<label for="concave-hull-concavity"
class="text-sm font-medium text-stone-300 flex justify-between">Concavity
<span id="concave-hull-concavity-value">2</span>
<span class="tooltip-trigger">
<i data-feather="help-circle" class="w-4 h-4 text-stone-400"></i>
<span class="tooltip-content">Lower values create more detailed
shapes but can be slower. Higher values are faster and
simpler.</span>
</span>
</label>
<input type="range" id="concave-hull-concavity" min="1" max="10" value="2">
</div>
</div>
<div id="render-mask-options" style="max-height: 0; opacity: 0; overflow: hidden;">
<div class="pt-3 space-y-2">
<label for="mask-simplification-slider"
class="text-sm font-medium text-stone-300 flex justify-between">Mask
Simplification
<span id="mask-simplification-value">0.1</span>
<span class="tooltip-trigger">
<i data-feather="help-circle" class="w-4 h-4 text-stone-400"></i>
<span class="tooltip-content">Controls mask accuracy. Lower values
create more detailed masks (more vertices). Higher values create
simpler masks (fewer vertices).</span>
</span>
</label>
<input type="range" id="mask-simplification-slider" min="0.1" max="3"
step="0.1" value="0.1">
</div>
</div>
</div>
</div>
</div>
</div>
<div class="lg:col-span-3 flex flex-col gap-6">
<div class="bg-stone-900/50 rounded-lg p-4 border border-white/10">
<h4 class="text-lg font-semibold text-stone-300 mb-4 border-b border-white/10 pb-2">Dataset
Splits</h4>
<div class="grid grid-cols-2 gap-x-6 gap-y-4">
<div class="flex items-center justify-between">
<label for="include-val-set"
class="font-medium text-stone-300 select-none cursor-pointer">Include Validation
Set</label>
<label class="relative inline-flex items-center cursor-pointer">
<input type="checkbox" id="include-val-set" class="sr-only peer" checked>
<div
class="w-11 h-6 bg-stone-700 rounded-full peer-checked:bg-blue-600 toggle-bg">
</div>
</label>
</div>
<div class="flex items-center justify-between">
<label for="include-test-set"
class="font-medium text-stone-300 select-none cursor-pointer">Include Test
Set</label>
<label class="relative inline-flex items-center cursor-pointer">
<input type="checkbox" id="include-test-set" class="sr-only peer" checked>
<div
class="w-11 h-6 bg-stone-700 rounded-full peer-checked:bg-blue-600 toggle-bg">
</div>
</label>
</div>
<div class="col-span-2 space-y-3 pt-2">
<label class="block text-sm font-medium text-stone-300">Split Ratios (<span
id="split-ratio-sum">100</span>%)</label>
<div class="grid grid-cols-3 gap-2 text-center text-sm">
<div>Train</div>
<div>Val</div>
<div>Test</div>
</div>
<div class="relative h-2 flex items-center my-2">
<div id="split-bg-train" class="absolute h-2 rounded-l-lg bg-blue-600"></div>
<div id="split-bg-val" class="absolute h-2 bg-green-500"></div>
<div id="split-bg-test" class="absolute h-2 rounded-r-lg bg-yellow-500"></div>
<input type="range" id="split-train-ratio" min="0" max="100" value="70"
class="split-slider w-full cursor-pointer" style="z-index: 10;">
<input type="range" id="split-val-ratio" min="0" max="100" value="90"
class="split-slider w-full cursor-pointer" style="z-index: 20;">
</div>
<div class="grid grid-cols-3 gap-2 text-center text-xs text-stone-400">
<div id="split-train-display">70%</div>
<div id="split-val-display">20%</div>
<div id="split-test-display">10%</div>
</div>
</div>
</div>
</div>
<div class="bg-stone-900/50 rounded-lg p-4 border border-white/10">
<h4 class="text-lg font-semibold text-stone-300 mb-4 border-b border-white/10 pb-2">Sample
Augmentation</h4>
<div class="space-y-3">
<div class="flex items-center justify-between">
<label for="include-background-toggle"
class="font-medium text-stone-300 select-none cursor-pointer flex items-center gap-2">Include
Background Samples
<span class="tooltip-trigger">
<i data-feather="help-circle" class="w-4 h-4 text-stone-400"></i>
<span class="tooltip-content">Generate some images with no objects (negative
samples). This helps reduce false positives in detection models.</span>
</span>
</label>
<label class="relative inline-flex items-center cursor-pointer">
<input type="checkbox" id="include-background-toggle" class="sr-only peer"
checked>
<div
class="w-11 h-6 bg-stone-700 rounded-full peer-checked:bg-blue-600 toggle-bg">
</div>
</label>
</div>
<div id="background-ratio-container" class="sliders-container pl-1 space-y-3">
<div>
<label for="background-ratio-slider" class="text-sm flex justify-between">Ratio
of Backgrounds
<span id="background-ratio-value">15%</span>
</label>
<input type="range" id="background-ratio-slider" min="0" max="50" value="20">
</div>
</div>
</div>
</div>
<div class="bg-stone-900/50 rounded-lg p-4 border border-white/10">
<h4 class="text-lg font-semibold text-stone-300 mb-4 border-b border-white/10 pb-2">Scene &
Randomization</h4>
<div class="grid grid-cols-1 md:grid-cols-2 gap-x-6 gap-y-4">
<div class="space-y-4">
<div>
<label class="font-medium text-stone-200 block mb-2">3D Model Source</label>
<div class="flex flex-col gap-2">
<label
class="flex items-center gap-2 p-2 rounded-md bg-stone-800/50 hover:bg-stone-700/50 cursor-pointer flex-1"><input
type="radio" name="model-source" value="current" checked
class="h-4 w-4 rounded-full text-blue-500 bg-stone-700 border-stone-500 focus:ring-blue-600">
Use Current Model</label>
<label
class="flex items-center gap-2 p-2 rounded-md bg-stone-800/50 hover:bg-stone-700/50 cursor-pointer flex-1"><input
type="radio" name="model-source" value="random"
class="h-4 w-4 rounded-full text-blue-500 bg-stone-700 border-stone-500 focus:ring-blue-600">
Randomize Library</label>
</div>
<div id="model-source-current-info"
class="text-sm text-blue-400 pl-2 hidden mt-2"></div>
</div>
<div>
<label class="font-medium text-stone-200 block mb-2">Background Source</label>
<div class="flex flex-col gap-2">
<label
class="flex items-center gap-2 p-2 rounded-md bg-stone-800/50 hover:bg-stone-700/50 cursor-pointer flex-1"><input
type="radio" name="pano-source" value="current" checked
class="h-4 w-4 rounded-full text-blue-500 bg-stone-700 border-stone-500 focus:ring-blue-600">
Use Current Panorama</label>
<label
class="flex items-center gap-2 p-2 rounded-md bg-stone-800/50 hover:bg-stone-700/50 cursor-pointer flex-1"><input
type="radio" name="pano-source" value="random"
class="h-4 w-4 rounded-full text-blue-500 bg-stone-700 border-stone-500 focus:ring-blue-600">
Randomize Library</label>
</div>
<div id="pano-source-current-info"
class="text-sm text-blue-400 pl-2 hidden mt-2"></div>
</div>
</div>
<div class="space-y-4">
<div class="control-section space-y-3">
<div class="flex items-center justify-between">
<label for="randomize-model-toggle"
class="font-medium text-stone-300 select-none cursor-pointer flex items-center gap-2">Model
Transform
<span class="tooltip-trigger"><i data-feather="help-circle"
class="w-4 h-4 text-stone-400"></i><span
class="tooltip-content">Applies random position, rotation, and
scale. If 'Use Current Model' is selected, randomization is
relative to its current state.</span></span>
</label>
<label class="relative inline-flex items-center cursor-pointer">
<input type="checkbox" id="randomize-model-toggle" class="sr-only peer"
checked>
<div
class="w-11 h-6 bg-stone-700 rounded-full peer-checked:bg-blue-600 toggle-bg">
</div>
</label>
</div>
<div id="model-sliders" class="sliders-container pl-1 space-y-3"
style="max-height: 0; opacity: 0; overflow: hidden;">
<div><label for="position-variance"
class="text-sm flex justify-between">Position Var. <span
id="position-variance-value">90%</span></label><input
type="range" id="position-variance" min="0" max="100" value="90">
</div>
<div><label for="rotation-variance"
class="text-sm flex justify-between">Rotation Var. <span
id="rotation-variance-value">100%</span></label><input
type="range" id="rotation-variance" min="0" max="100" value="100">
</div>
<div><label for="scale-variance" class="text-sm flex justify-between">Scale
Var. <span id="scale-variance-value">10%</span></label><input
type="range" id="scale-variance" min="0" max="100" value="10"></div>
</div>
</div>
<div id="camera-randomization-section"
class="control-section space-y-3 transition-opacity duration-300">
<div class="flex items-center justify-between">
<label for="randomize-camera-toggle"
class="font-medium text-stone-300 select-none cursor-pointer flex items-center gap-2">Camera
Viewpoint
<span class="tooltip-trigger"><i data-feather="help-circle"
class="w-4 h-4 text-stone-400"></i><span
class="tooltip-content">Generate images from viewpoints similar
to the current camera angle. Only available when using the
current panorama.</span></span>
</label>
<label class="relative inline-flex items-center cursor-pointer">
<input type="checkbox" id="randomize-camera-toggle" class="sr-only peer"
checked>
<div
class="w-11 h-6 bg-stone-700 rounded-full peer-checked:bg-blue-600 toggle-bg">
</div>
</label>
</div>
<div id="camera-sliders" class="sliders-container pl-1 space-y-3"
style="max-height: 0; opacity: 0; overflow: hidden;">
<div><label for="horizontal-variance"
class="text-sm flex justify-between">Horizontal Var. <span
id="horizontal-variance-value">180°</span></label><input
type="range" id="horizontal-variance" min="0" max="180" value="180">
</div>
<div><label for="vertical-variance"
class="text-sm flex justify-between">Vertical Var. <span
id="vertical-variance-value">20°</span></label><input
type="range" id="vertical-variance" min="0" max="90" value="20">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="flex-shrink-0 flex justify-end gap-3 p-4 border-t border-white/10 bg-stone-900/30">
<button id="cancel-dataset"
class="bg-stone-600 px-5 py-2.5 rounded-md font-semibold hover:bg-stone-700 transition-colors disabled:opacity-50">Cancel</button>
<button id="start-dataset"
class="bg-blue-600 px-5 py-2.5 rounded-md font-semibold hover:bg-blue-700 min-w-[120px] flex justify-center items-center transition-colors disabled:bg-blue-800 disabled:cursor-not-allowed">
<span class="btn-text">Generate</span>
<div class="btn-spinner hidden"></div>
</button>
</div>
</div>
</div>
<div id="progress-container" class="modal-overlay fixed inset-0 z-40 hidden items-center justify-center p-4">
<div class="glass-ui w-full max-w-sm p-6 rounded-lg">
<h3 id="progress-title" class="text-lg font-bold mb-4">Generating Dataset</h3>
<div class="flex justify-between items-baseline mb-2">
<div id="progress-label" class="text-sm text-stone-300">Processing...</div>
<div id="progress-count" class="text-xs text-stone-400"></div>
</div>
<div class="w-full bg-stone-700 rounded-full h-2.5">
<div id="progress-bar" class="bg-blue-600 h-2.5 rounded-full transition-all" style="width: 0%"></div>
</div>
</div>
</div>
<div id="upload-modal" class="modal-overlay fixed inset-0 z-40 hidden items-center justify-center p-4">
<div class="glass-ui p-6 rounded-lg w-full max-w-md mx-auto flex flex-col gap-4">
<h3 id="upload-title" class="text-2xl font-bold text-center">Upload New Asset</h3>
<div id="upload-drop-zone" class="drop-zone p-6 rounded-lg text-center cursor-pointer">
<p class="text-stone-300 pointer-events-none">Drag & Drop File</p>
<p class="text-stone-400 text-sm pointer-events-none">or click to browse</p>
<input type="file" id="upload-file-input" class="hidden">
</div>
<div class="flex items-center text-stone-400">
<hr class="flex-grow border-white/10"><span class="mx-2 text-sm">OR</span>
<hr class="flex-grow border-white/10">
</div>
<input type="text" id="upload-url-input"
class="w-full bg-stone-900/50 p-2 rounded-md border-2 border-stone-600 focus:border-blue-500 outline-none"
placeholder="Enter Asset URL">
<div class="flex justify-end gap-3 mt-2">
<button id="upload-cancel-btn"
class="bg-stone-600 px-4 py-2 rounded-md font-semibold hover:bg-stone-700 transition-colors">Cancel</button>
<button id="upload-load-btn"
class="bg-blue-600 px-4 py-2 rounded-md font-semibold hover:bg-blue-700 min-w-[80px] flex justify-center items-center transition-colors disabled:bg-blue-800">
<span class="btn-text">Load</span>
<div class="btn-spinner hidden"></div>
</button>
</div>
</div>
</div>
<div id="controls-bar"
class="glass-ui fixed top-4 left-1/2 -translate-x-1/2 z-20 p-2 rounded-lg flex items-center gap-2">
<button id="translate-btn" class="control-btn p-2 rounded hover:bg-white/10" data-mode="translate"
title="Translate (W)"><i data-feather="move"></i></button>
<button id="rotate-btn" class="control-btn p-2 rounded hover:bg-white/10" data-mode="rotate"
title="Rotate (E)"><i data-feather="rotate-cw"></i></button>
<button id="scale-btn" class="control-btn p-2 rounded hover:bg-white/10" data-mode="scale" title="Scale (R)"><i
data-feather="maximize"></i></button>
<div class="w-px h-6 bg-white/10 mx-1"></div>
<div class="flex items-center gap-2 px-2" title="Toggle Day/Night">
<i data-feather="sun" class="w-5 h-5 text-stone-400"></i>
<label class="relative inline-flex items-center cursor-pointer">
<input type="checkbox" id="day-night-toggle" class="sr-only peer">
<div class="w-11 h-6 bg-stone-700 rounded-full peer-checked:bg-blue-600 toggle-bg"></div>
</label>
<i data-feather="moon" class="w-5 h-5 text-stone-400"></i>
</div>
<div class="w-px h-6 bg-white/10 mx-1"></div>
<button id="generate-dataset-btn" class="p-2 rounded hover:bg-blue-600/50" title="Generate Dataset (G)"><i
data-feather="database"></i></button>
</div>
<button id="model-panel-trigger"
class="panel-trigger glass-ui absolute top-1/2 -translate-y-1/2 left-0 z-20 rounded-r-lg p-3"><i
data-feather="box"></i></button>
<button id="panorama-panel-trigger"
class="panel-trigger glass-ui absolute top-1/2 -translate-y-1/2 right-0 z-20 rounded-l-lg p-3"><i
data-feather="image"></i></button>
<aside id="model-panel"
class="side-panel left glass-ui fixed top-0 left-0 h-full w-[80vw] sm:w-80 z-30 flex flex-col">
<header class="flex-shrink-0 flex justify-between items-center p-4 border-b border-white/10">
<h2 class="text-xl font-bold">Models</h2>
<div>
<button id="add-model-btn" class="p-2 rounded-full hover:bg-blue-600/50" title="Add new model"><i
data-feather="plus"></i></button>
<button id="close-model-panel" class="p-2 rounded-full hover:bg-stone-700"><i
data-feather="x"></i></button>
</div>
</header>
<div id="model-selector"
class="panel-content flex-grow overflow-y-auto p-4 grid grid-cols-1 md:grid-cols-2 gap-4"></div>
</aside>
<aside id="panorama-panel"
class="side-panel right glass-ui fixed top-0 right-0 h-full w-[80vw] sm:w-80 z-30 flex flex-col">
<header class="flex-shrink-0 flex justify-between items-center p-4 border-b border-white/10">
<h2 class="text-xl font-bold">Panoramas</h2>
<div>
<button id="add-panorama-btn" class="p-2 rounded-full hover:bg-blue-600/50" title="Add new panorama"><i
data-feather="plus"></i></button>
<button id="close-panorama-panel" class="p-2 rounded-full hover:bg-stone-700"><i
data-feather="x"></i></button>
</div>
</header>
<div id="panorama-gallery"
class="panel-content flex-grow overflow-y-auto p-4 grid grid-cols-1 md:grid-cols-2 gap-4"></div>
</aside>
<script type="importmap">
{
"imports": {
"three": "https://unpkg.com/three@0.160.0/build/three.module.js",
"three/addons/": "https://unpkg.com/three@0.160.0/examples/jsm/",
"concaveman": "https://cdn.skypack.dev/concaveman",
"gsap": "https://cdn.jsdelivr.net/npm/gsap@3.12.5/+esm",
"jszip": "https://cdn.jsdelivr.net/npm/jszip@3.10.1/+esm"
}
}
</script>
<script type="module" src="core.js"></script>
</body>
</html>