Spaces:
Running
Running
Update index.html
Browse files- index.html +62 -14
index.html
CHANGED
|
@@ -54,7 +54,7 @@
|
|
| 54 |
.notification { transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1); transform: translateY(150%) scale(0.9); opacity: 0; }
|
| 55 |
.notification.show { transform: translateY(0) scale(1); opacity: 1; }
|
| 56 |
.control-section { transition: opacity 0.3s ease; }
|
| 57 |
-
.sliders-container, .accordion-content, #concave-hull-options { transition: max-height 0.4s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.4s, padding-top 0.4s, margin-top 0.4s, padding-bottom 0.4s; overflow: hidden; }
|
| 58 |
/* Enhanced Range Sliders */
|
| 59 |
input[type="range"] { -webkit-appearance: none; appearance: none; width: 100%; height: 6px; background: #44403c; border-radius: 5px; outline: none; transition: background 0.3s; padding: 0; margin: 0; }
|
| 60 |
input[type="range"]::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 20px; height: 20px; background: #e7e5e4; border-radius: 50%; cursor: pointer; border: 4px solid #3b82f6; transition: all 0.2s ease-in-out; margin-top: -7px; }
|
|
@@ -175,7 +175,6 @@
|
|
| 175 |
</label>
|
| 176 |
</div>
|
| 177 |
</div>
|
| 178 |
-
<!-- START: IMPROVEMENT - Added Concavity slider -->
|
| 179 |
<div id="concave-hull-options" style="max-height: 0; opacity: 0; overflow: hidden;">
|
| 180 |
<div class="pt-3 space-y-2">
|
| 181 |
<label for="concave-hull-concavity" class="text-sm font-medium text-stone-300 flex justify-between">Concavity
|
|
@@ -188,7 +187,6 @@
|
|
| 188 |
<input type="range" id="concave-hull-concavity" min="1" max="10" value="2">
|
| 189 |
</div>
|
| 190 |
</div>
|
| 191 |
-
<!-- END: IMPROVEMENT -->
|
| 192 |
</div>
|
| 193 |
</div>
|
| 194 |
</div>
|
|
@@ -219,7 +217,6 @@
|
|
| 219 |
<div class="grid grid-cols-3 gap-2 text-center text-sm">
|
| 220 |
<div>Train</div><div>Val</div><div>Test</div>
|
| 221 |
</div>
|
| 222 |
-
<!-- START: IMPROVEMENT - z-index is now controlled via JS for better interaction -->
|
| 223 |
<div class="relative h-2 flex items-center my-2">
|
| 224 |
<div id="split-bg-train" class="absolute h-2 rounded-l-lg bg-blue-600"></div>
|
| 225 |
<div id="split-bg-val" class="absolute h-2 bg-green-500"></div>
|
|
@@ -227,7 +224,6 @@
|
|
| 227 |
<input type="range" id="split-train-ratio" min="0" max="100" value="70" class="split-slider w-full cursor-pointer" style="z-index: 10;">
|
| 228 |
<input type="range" id="split-val-ratio" min="0" max="100" value="90" class="split-slider w-full cursor-pointer" style="z-index: 20;">
|
| 229 |
</div>
|
| 230 |
-
<!-- END: IMPROVEMENT -->
|
| 231 |
<div class="grid grid-cols-3 gap-2 text-center text-xs text-stone-400">
|
| 232 |
<div id="split-train-display">70%</div>
|
| 233 |
<div id="split-val-display">20%</div>
|
|
@@ -237,6 +233,34 @@
|
|
| 237 |
</div>
|
| 238 |
</div>
|
| 239 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 240 |
<!-- Scene Composition & Randomization -->
|
| 241 |
<div class="bg-stone-900/50 rounded-lg p-4 border border-white/10">
|
| 242 |
<h4 class="text-lg font-semibold text-stone-300 mb-4 border-b border-white/10 pb-2">Scene & Randomization</h4>
|
|
@@ -747,8 +771,9 @@
|
|
| 747 |
const slider = document.getElementById(sliderId);
|
| 748 |
const display = document.getElementById(displayId);
|
| 749 |
if (slider && display) {
|
| 750 |
-
display.textContent = slider.value + unit;
|
| 751 |
-
|
|
|
|
| 752 |
}
|
| 753 |
};
|
| 754 |
setupSlider('position-variance', 'position-variance-value', '%');
|
|
@@ -757,8 +782,9 @@
|
|
| 757 |
setupSlider('horizontal-variance', 'horizontal-variance-value', '°');
|
| 758 |
setupSlider('vertical-variance', 'vertical-variance-value', '°');
|
| 759 |
setupSlider('concave-hull-concavity', 'concave-hull-concavity-value', '');
|
|
|
|
| 760 |
|
| 761 |
-
//
|
| 762 |
const trainSlider = document.getElementById('split-train-ratio');
|
| 763 |
const valSlider = document.getElementById('split-val-ratio');
|
| 764 |
|
|
@@ -774,7 +800,6 @@
|
|
| 774 |
trainSlider.addEventListener('touchstart', () => bringToFront(trainSlider, 25, 20));
|
| 775 |
valSlider.addEventListener('mousedown', () => bringToFront(valSlider, 25, 20));
|
| 776 |
valSlider.addEventListener('touchstart', () => bringToFront(valSlider, 25, 20));
|
| 777 |
-
// --- END: IMPROVEMENT ---
|
| 778 |
}
|
| 779 |
|
| 780 |
function updateDatasetModalUI() {
|
|
@@ -821,7 +846,6 @@
|
|
| 821 |
duration: 0.4
|
| 822 |
});
|
| 823 |
|
| 824 |
-
// --- START: IMPROVEMENT - Show/hide concavity slider ---
|
| 825 |
const showConcaveOptions = showSegGroup && segMethod === 'concave';
|
| 826 |
gsap.to(concaveOptions, {
|
| 827 |
maxHeight: showConcaveOptions ? 100 : 0,
|
|
@@ -829,7 +853,16 @@
|
|
| 829 |
paddingTop: showConcaveOptions ? '0.75rem' : 0,
|
| 830 |
duration: 0.4
|
| 831 |
});
|
| 832 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 833 |
|
| 834 |
// Dataset Splits UI
|
| 835 |
updateSplitRatios();
|
|
@@ -904,9 +937,13 @@
|
|
| 904 |
const options = {
|
| 905 |
task: document.querySelector('input[name="dataset-task"]:checked').value,
|
| 906 |
segmentationMethod: document.querySelector('input[name="segmentation-method"]:checked').value,
|
| 907 |
-
concavity: parseFloat(document.getElementById('concave-hull-concavity').value),
|
| 908 |
samples: parseInt(document.getElementById('dataset-samples').value),
|
| 909 |
name: document.getElementById('dataset-name').value.trim(),
|
|
|
|
|
|
|
|
|
|
|
|
|
| 910 |
useCurrentModel: document.querySelector('input[name="model-source"]:checked').value === 'current',
|
| 911 |
randomizeModel: document.getElementById('randomize-model-toggle').checked,
|
| 912 |
posVar: parseInt(document.getElementById('position-variance').value) / 100,
|
|
@@ -1036,9 +1073,20 @@
|
|
| 1036 |
|
| 1037 |
if (!currentModelAsset || !selectedObject) return null;
|
| 1038 |
|
| 1039 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1040 |
|
| 1041 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1042 |
if (!selectedObject.visible) return null;
|
| 1043 |
|
| 1044 |
if (options.randomizeModel) {
|
|
|
|
| 54 |
.notification { transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1); transform: translateY(150%) scale(0.9); opacity: 0; }
|
| 55 |
.notification.show { transform: translateY(0) scale(1); opacity: 1; }
|
| 56 |
.control-section { transition: opacity 0.3s ease; }
|
| 57 |
+
.sliders-container, .accordion-content, #concave-hull-options, #background-ratio-container { transition: max-height 0.4s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.4s, padding-top 0.4s, margin-top 0.4s, padding-bottom 0.4s; overflow: hidden; }
|
| 58 |
/* Enhanced Range Sliders */
|
| 59 |
input[type="range"] { -webkit-appearance: none; appearance: none; width: 100%; height: 6px; background: #44403c; border-radius: 5px; outline: none; transition: background 0.3s; padding: 0; margin: 0; }
|
| 60 |
input[type="range"]::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 20px; height: 20px; background: #e7e5e4; border-radius: 50%; cursor: pointer; border: 4px solid #3b82f6; transition: all 0.2s ease-in-out; margin-top: -7px; }
|
|
|
|
| 175 |
</label>
|
| 176 |
</div>
|
| 177 |
</div>
|
|
|
|
| 178 |
<div id="concave-hull-options" style="max-height: 0; opacity: 0; overflow: hidden;">
|
| 179 |
<div class="pt-3 space-y-2">
|
| 180 |
<label for="concave-hull-concavity" class="text-sm font-medium text-stone-300 flex justify-between">Concavity
|
|
|
|
| 187 |
<input type="range" id="concave-hull-concavity" min="1" max="10" value="2">
|
| 188 |
</div>
|
| 189 |
</div>
|
|
|
|
| 190 |
</div>
|
| 191 |
</div>
|
| 192 |
</div>
|
|
|
|
| 217 |
<div class="grid grid-cols-3 gap-2 text-center text-sm">
|
| 218 |
<div>Train</div><div>Val</div><div>Test</div>
|
| 219 |
</div>
|
|
|
|
| 220 |
<div class="relative h-2 flex items-center my-2">
|
| 221 |
<div id="split-bg-train" class="absolute h-2 rounded-l-lg bg-blue-600"></div>
|
| 222 |
<div id="split-bg-val" class="absolute h-2 bg-green-500"></div>
|
|
|
|
| 224 |
<input type="range" id="split-train-ratio" min="0" max="100" value="70" class="split-slider w-full cursor-pointer" style="z-index: 10;">
|
| 225 |
<input type="range" id="split-val-ratio" min="0" max="100" value="90" class="split-slider w-full cursor-pointer" style="z-index: 20;">
|
| 226 |
</div>
|
|
|
|
| 227 |
<div class="grid grid-cols-3 gap-2 text-center text-xs text-stone-400">
|
| 228 |
<div id="split-train-display">70%</div>
|
| 229 |
<div id="split-val-display">20%</div>
|
|
|
|
| 233 |
</div>
|
| 234 |
</div>
|
| 235 |
|
| 236 |
+
<!-- START: IMPLEMENTATION of Negative Samples -->
|
| 237 |
+
<div class="bg-stone-900/50 rounded-lg p-4 border border-white/10">
|
| 238 |
+
<h4 class="text-lg font-semibold text-stone-300 mb-4 border-b border-white/10 pb-2">Sample Augmentation</h4>
|
| 239 |
+
<div class="space-y-3">
|
| 240 |
+
<div class="flex items-center justify-between">
|
| 241 |
+
<label for="include-background-toggle" class="font-medium text-stone-300 select-none cursor-pointer flex items-center gap-2">Include Background Samples
|
| 242 |
+
<span class="tooltip-trigger">
|
| 243 |
+
<i data-feather="help-circle" class="w-4 h-4 text-stone-400"></i>
|
| 244 |
+
<span class="tooltip-content">Generate some images with no objects (negative samples). This helps reduce false positives in detection models.</span>
|
| 245 |
+
</span>
|
| 246 |
+
</label>
|
| 247 |
+
<label class="relative inline-flex items-center cursor-pointer">
|
| 248 |
+
<input type="checkbox" id="include-background-toggle" class="sr-only peer" checked>
|
| 249 |
+
<div class="w-11 h-6 bg-stone-700 rounded-full peer-checked:bg-blue-600 toggle-bg"></div>
|
| 250 |
+
</label>
|
| 251 |
+
</div>
|
| 252 |
+
<div id="background-ratio-container" class="sliders-container pl-1 space-y-3">
|
| 253 |
+
<div>
|
| 254 |
+
<label for="background-ratio-slider" class="text-sm flex justify-between">Ratio of Backgrounds
|
| 255 |
+
<span id="background-ratio-value">15%</span>
|
| 256 |
+
</label>
|
| 257 |
+
<input type="range" id="background-ratio-slider" min="0" max="50" value="20">
|
| 258 |
+
</div>
|
| 259 |
+
</div>
|
| 260 |
+
</div>
|
| 261 |
+
</div>
|
| 262 |
+
<!-- END: IMPLEMENTATION -->
|
| 263 |
+
|
| 264 |
<!-- Scene Composition & Randomization -->
|
| 265 |
<div class="bg-stone-900/50 rounded-lg p-4 border border-white/10">
|
| 266 |
<h4 class="text-lg font-semibold text-stone-300 mb-4 border-b border-white/10 pb-2">Scene & Randomization</h4>
|
|
|
|
| 771 |
const slider = document.getElementById(sliderId);
|
| 772 |
const display = document.getElementById(displayId);
|
| 773 |
if (slider && display) {
|
| 774 |
+
const update = () => { display.textContent = slider.value + unit; };
|
| 775 |
+
update();
|
| 776 |
+
slider.addEventListener('input', update);
|
| 777 |
}
|
| 778 |
};
|
| 779 |
setupSlider('position-variance', 'position-variance-value', '%');
|
|
|
|
| 782 |
setupSlider('horizontal-variance', 'horizontal-variance-value', '°');
|
| 783 |
setupSlider('vertical-variance', 'vertical-variance-value', '°');
|
| 784 |
setupSlider('concave-hull-concavity', 'concave-hull-concavity-value', '');
|
| 785 |
+
setupSlider('background-ratio-slider', 'background-ratio-value', '%'); // New slider
|
| 786 |
|
| 787 |
+
// Setup listeners for split ratio sliders
|
| 788 |
const trainSlider = document.getElementById('split-train-ratio');
|
| 789 |
const valSlider = document.getElementById('split-val-ratio');
|
| 790 |
|
|
|
|
| 800 |
trainSlider.addEventListener('touchstart', () => bringToFront(trainSlider, 25, 20));
|
| 801 |
valSlider.addEventListener('mousedown', () => bringToFront(valSlider, 25, 20));
|
| 802 |
valSlider.addEventListener('touchstart', () => bringToFront(valSlider, 25, 20));
|
|
|
|
| 803 |
}
|
| 804 |
|
| 805 |
function updateDatasetModalUI() {
|
|
|
|
| 846 |
duration: 0.4
|
| 847 |
});
|
| 848 |
|
|
|
|
| 849 |
const showConcaveOptions = showSegGroup && segMethod === 'concave';
|
| 850 |
gsap.to(concaveOptions, {
|
| 851 |
maxHeight: showConcaveOptions ? 100 : 0,
|
|
|
|
| 853 |
paddingTop: showConcaveOptions ? '0.75rem' : 0,
|
| 854 |
duration: 0.4
|
| 855 |
});
|
| 856 |
+
|
| 857 |
+
// START: IMPLEMENTATION - Show/hide background ratio slider
|
| 858 |
+
const includeBackgrounds = document.getElementById('include-background-toggle').checked;
|
| 859 |
+
gsap.to("#background-ratio-container", {
|
| 860 |
+
maxHeight: includeBackgrounds ? 100 : 0,
|
| 861 |
+
opacity: includeBackgrounds ? 1 : 0,
|
| 862 |
+
paddingTop: includeBackgrounds ? '0.5rem' : 0,
|
| 863 |
+
duration: 0.4
|
| 864 |
+
});
|
| 865 |
+
// END: IMPLEMENTATION
|
| 866 |
|
| 867 |
// Dataset Splits UI
|
| 868 |
updateSplitRatios();
|
|
|
|
| 937 |
const options = {
|
| 938 |
task: document.querySelector('input[name="dataset-task"]:checked').value,
|
| 939 |
segmentationMethod: document.querySelector('input[name="segmentation-method"]:checked').value,
|
| 940 |
+
concavity: parseFloat(document.getElementById('concave-hull-concavity').value),
|
| 941 |
samples: parseInt(document.getElementById('dataset-samples').value),
|
| 942 |
name: document.getElementById('dataset-name').value.trim(),
|
| 943 |
+
// START: IMPLEMENTATION - Read new options
|
| 944 |
+
includeBackgrounds: document.getElementById('include-background-toggle').checked,
|
| 945 |
+
backgroundRatio: parseInt(document.getElementById('background-ratio-slider').value) / 100,
|
| 946 |
+
// END: IMPLEMENTATION
|
| 947 |
useCurrentModel: document.querySelector('input[name="model-source"]:checked').value === 'current',
|
| 948 |
randomizeModel: document.getElementById('randomize-model-toggle').checked,
|
| 949 |
posVar: parseInt(document.getElementById('position-variance').value) / 100,
|
|
|
|
| 1073 |
|
| 1074 |
if (!currentModelAsset || !selectedObject) return null;
|
| 1075 |
|
| 1076 |
+
// START: IMPLEMENTATION - Unified negative sample logic
|
| 1077 |
+
// This replaces the old classification-only logic.
|
| 1078 |
+
if (options.includeBackgrounds && Math.random() < options.backgroundRatio) {
|
| 1079 |
+
selectedObject.visible = false;
|
| 1080 |
+
} else {
|
| 1081 |
+
selectedObject.visible = true;
|
| 1082 |
+
}
|
| 1083 |
|
| 1084 |
+
// If the object is visible, add its class to the list for the YAML file.
|
| 1085 |
+
if (selectedObject.visible) {
|
| 1086 |
+
usedClasses.add(currentModelAsset.name);
|
| 1087 |
+
}
|
| 1088 |
+
// END: IMPLEMENTATION
|
| 1089 |
+
|
| 1090 |
if (!selectedObject.visible) return null;
|
| 1091 |
|
| 1092 |
if (options.randomizeModel) {
|