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) {
|