mirror of
https://github.com/PhotonVision/photonvision
synced 2026-06-24 01:31:44 +00:00
[PhotonClient] Vite and Typescript complete refactor (#884)
This commit is contained in:
213
photon-client/src/components/dashboard/tabs/ContoursTab.vue
Normal file
213
photon-client/src/components/dashboard/tabs/ContoursTab.vue
Normal file
@@ -0,0 +1,213 @@
|
||||
<script setup lang="ts">
|
||||
import { useCameraSettingsStore } from "@/stores/settings/CameraSettingsStore";
|
||||
import { PipelineType } from "@/types/PipelineTypes";
|
||||
import CvRangeSlider from "@/components/common/cv-range-slider.vue";
|
||||
import CvSelect from "@/components/common/cv-select.vue";
|
||||
import CvSlider from "@/components/common/cv-slider.vue";
|
||||
import { computed, getCurrentInstance } from "vue";
|
||||
import { useStateStore } from "@/stores/StateStore";
|
||||
|
||||
// TODO fix pipeline typing in order to fix this, the store settings call should be able to infer that only valid pipeline type settings are exposed based on pre-checks for the entire config section
|
||||
// Defer reference to store access method
|
||||
const currentPipelineSettings = useCameraSettingsStore().currentPipelineSettings;
|
||||
|
||||
// TODO fix cv-range-slider so that store access doesn't need to be deferred
|
||||
const contourArea = computed<[number, number]>({
|
||||
get: () => Object.values(useCameraSettingsStore().currentPipelineSettings.contourArea) as [number, number],
|
||||
set: v => useCameraSettingsStore().currentPipelineSettings.contourArea = v
|
||||
});
|
||||
const contourRatio = computed<[number, number]>({
|
||||
get: () => Object.values(useCameraSettingsStore().currentPipelineSettings.contourRatio) as [number, number],
|
||||
set: v => useCameraSettingsStore().currentPipelineSettings.contourRatio = v
|
||||
});
|
||||
const contourFullness = computed<[number, number]>({
|
||||
get: () => Object.values(useCameraSettingsStore().currentPipelineSettings.contourFullness) as [number, number],
|
||||
set: v => useCameraSettingsStore().currentPipelineSettings.contourFullness = v
|
||||
});
|
||||
const contourPerimeter = computed<[number, number]>({
|
||||
get: () => currentPipelineSettings.pipelineType === PipelineType.ColoredShape ? Object.values(currentPipelineSettings.contourPerimeter) as [number, number] : [0, 0] as [number, number],
|
||||
set: v => {
|
||||
if(currentPipelineSettings.pipelineType === PipelineType.ColoredShape) {
|
||||
currentPipelineSettings.contourPerimeter = v;
|
||||
}
|
||||
}
|
||||
});
|
||||
const contourRadius = computed<[number, number]>({
|
||||
get: () => currentPipelineSettings.pipelineType === PipelineType.ColoredShape ? Object.values(currentPipelineSettings.contourRadius) as [number, number] : [0, 0] as [number, number],
|
||||
set: v => {
|
||||
if(currentPipelineSettings.pipelineType === PipelineType.ColoredShape) {
|
||||
currentPipelineSettings.contourRadius = v;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const interactiveCols = computed(() => (getCurrentInstance()?.proxy.$vuetify.breakpoint.mdAndDown || false) && (!useStateStore().sidebarFolded || useCameraSettingsStore().isDriverMode)) ? 9 : 8;
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<cv-range-slider
|
||||
v-model="contourArea"
|
||||
label="Area"
|
||||
:min="0"
|
||||
:max="100"
|
||||
:slider-cols="interactiveCols"
|
||||
:step="0.01"
|
||||
@input="value => useCameraSettingsStore().changeCurrentPipelineSetting({contourArea: value}, false)"
|
||||
/>
|
||||
<cv-range-slider
|
||||
v-if="useCameraSettingsStore().currentPipelineType !== PipelineType.ColoredShape"
|
||||
v-model="contourRatio"
|
||||
label="Ratio (W/H)"
|
||||
tooltip="Min and max ratio between the width and height of a contour's bounding rectangle"
|
||||
:min="0"
|
||||
:max="100"
|
||||
:slider-cols="interactiveCols"
|
||||
:step="0.1"
|
||||
@input="value => useCameraSettingsStore().changeCurrentPipelineSetting({contourRatio: value}, false)"
|
||||
/>
|
||||
<cv-select
|
||||
v-model="useCameraSettingsStore().currentPipelineSettings.contourTargetOrientation"
|
||||
label="Target Orientation"
|
||||
tooltip="Used to determine how to calculate target landmarks, as well as aspect ratio"
|
||||
:items="['Portrait', 'Landscape']"
|
||||
:select-cols="interactiveCols"
|
||||
@input="value => useCameraSettingsStore().changeCurrentPipelineSetting({contourTargetOrientation: value}, false)"
|
||||
/>
|
||||
<cv-range-slider
|
||||
v-if="useCameraSettingsStore().currentPipelineType === PipelineType.ColoredShape"
|
||||
v-model="contourFullness"
|
||||
label="Fullness"
|
||||
tooltip="Min and max ratio between a contour's area and its bounding rectangle"
|
||||
:min="0"
|
||||
:max="100"
|
||||
:slider-cols="interactiveCols"
|
||||
@input="value => useCameraSettingsStore().changeCurrentPipelineSetting({contourFullness: value}, false)"
|
||||
/>
|
||||
<cv-range-slider
|
||||
v-if="currentPipelineSettings.pipelineType === PipelineType.ColoredShape"
|
||||
v-model="contourPerimeter"
|
||||
label="Perimeter"
|
||||
tooltip="Min and max perimeter of the shape, in pixels"
|
||||
min="0"
|
||||
max="4000"
|
||||
:slider-cols="interactiveCols"
|
||||
@input="value => useCameraSettingsStore().changeCurrentPipelineSetting({contourPerimeter: value}, false)"
|
||||
/>
|
||||
<cv-slider
|
||||
v-model="useCameraSettingsStore().currentPipelineSettings.contourSpecklePercentage"
|
||||
label="Speckle Rejection"
|
||||
tooltip="Rejects contours whose average area is less than the given percentage of the average area of all the other contours"
|
||||
:min="0"
|
||||
:max="100"
|
||||
:slider-cols="interactiveCols"
|
||||
@input="value => useCameraSettingsStore().changeCurrentPipelineSetting({contourSpecklePercentage: value}, false)"
|
||||
/>
|
||||
<template v-if="currentPipelineSettings.pipelineType === PipelineType.Reflective">
|
||||
<cv-slider
|
||||
v-model="currentPipelineSettings.contourFilterRangeX"
|
||||
label="X Filter Tightness"
|
||||
tooltip="Rejects contours whose center X is further than X standard deviations left/right of the mean X location"
|
||||
:min="0.1"
|
||||
:max="4"
|
||||
:step="0.1"
|
||||
:slider-cols="interactiveCols"
|
||||
@input="value => useCameraSettingsStore().changeCurrentPipelineSetting({contourFilterRangeX: value}, false)"
|
||||
/>
|
||||
<cv-slider
|
||||
v-model="currentPipelineSettings.contourFilterRangeY"
|
||||
label="Y Filter Tightness"
|
||||
tooltip="Rejects contours whose center Y is further than X standard deviations above/below the mean Y location"
|
||||
:min="0.1"
|
||||
:max="4"
|
||||
:step="0.1"
|
||||
:slider-cols="interactiveCols"
|
||||
@input="value => useCameraSettingsStore().changeCurrentPipelineSetting({contourFilterRangeY: value}, false)"
|
||||
/>
|
||||
<cv-select
|
||||
v-model="useCameraSettingsStore().currentPipelineSettings.contourGroupingMode"
|
||||
label="Target Grouping"
|
||||
tooltip="Whether or not every two targets are paired with each other (good for e.g. 2019 targets)"
|
||||
:select-cols="interactiveCols"
|
||||
:items="['Single','Dual','Two or More']"
|
||||
@input="value => useCameraSettingsStore().changeCurrentPipelineSetting({contourGroupingMode: value}, false)"
|
||||
/>
|
||||
<cv-select
|
||||
v-model="useCameraSettingsStore().currentPipelineSettings.contourIntersection"
|
||||
label="Target Intersection"
|
||||
tooltip="If target grouping is in dual mode it will use this dropdown to decide how targets are grouped with adjacent targets"
|
||||
:select-cols="interactiveCols"
|
||||
:items="['None','Up','Down','Left','Right']"
|
||||
:disabled="useCameraSettingsStore().currentPipelineSettings.contourGroupingMode === 0"
|
||||
@input="value => useCameraSettingsStore().changeCurrentPipelineSetting({contourIntersection: value}, false)"
|
||||
/>
|
||||
</template>
|
||||
<template v-else-if="currentPipelineSettings.pipelineType === PipelineType.ColoredShape">
|
||||
<v-divider class="mt-3" />
|
||||
<cv-select
|
||||
v-model="currentPipelineSettings.contourShape"
|
||||
label="Target Shape"
|
||||
tooltip="The shape of targets to look for"
|
||||
:select-cols="interactiveCols"
|
||||
:items="['Circle', 'Polygon', 'Triangle', 'Quadrilateral']"
|
||||
@input="value => useCameraSettingsStore().changeCurrentPipelineSetting({contourShape: value}, false)"
|
||||
/>
|
||||
<cv-slider
|
||||
v-model="currentPipelineSettings.accuracyPercentage"
|
||||
:disabled="currentPipelineSettings.contourShape < 1"
|
||||
label="Shape Simplification"
|
||||
tooltip="How much we should simply the input contour before checking how many sides it has"
|
||||
:min="0"
|
||||
:max="100"
|
||||
:slider-cols="interactiveCols"
|
||||
@input="value => useCameraSettingsStore().changeCurrentPipelineSetting({accuracyPercentage: value}, false)"
|
||||
/>
|
||||
<cv-slider
|
||||
v-model="currentPipelineSettings.circleDetectThreshold"
|
||||
:disabled="currentPipelineSettings.contourShape !== 0"
|
||||
label="Circle match distance"
|
||||
tooltip="How close the centroid of a contour must be to the center of a circle in order for them to be matched"
|
||||
:min="1"
|
||||
:max="100"
|
||||
:slider-cols="interactiveCols"
|
||||
@input="value => useCameraSettingsStore().changeCurrentPipelineSetting({circleDetectThreshold: value}, false)"
|
||||
/>
|
||||
<cv-range-slider
|
||||
v-model="contourRadius"
|
||||
:disabled="currentPipelineSettings.contourShape !== 0"
|
||||
label="Radius"
|
||||
:min="0"
|
||||
:max="100"
|
||||
:slider-cols="interactiveCols"
|
||||
@input="value => useCameraSettingsStore().changeCurrentPipelineSetting({contourRadius: value}, false)"
|
||||
/>
|
||||
<cv-slider
|
||||
v-model="currentPipelineSettings.maxCannyThresh"
|
||||
:disabled="currentPipelineSettings.contourShape !== 0"
|
||||
label="Max Canny Threshold"
|
||||
:min="1"
|
||||
:max="100"
|
||||
:slider-cols="interactiveCols"
|
||||
@input="value => useCameraSettingsStore().changeCurrentPipelineSetting({maxCannyThresh: value}, false)"
|
||||
/>
|
||||
<cv-slider
|
||||
v-model="currentPipelineSettings.circleAccuracy"
|
||||
:disabled="currentPipelineSettings.contourShape !== 0"
|
||||
label="Circle Accuracy"
|
||||
:min="1"
|
||||
:max="100"
|
||||
:slider-cols="interactiveCols"
|
||||
@input="value => useCameraSettingsStore().changeCurrentPipelineSetting({circleAccuracy: value}, false)"
|
||||
/>
|
||||
<v-divider class="mt-3" />
|
||||
</template>
|
||||
<cv-select
|
||||
v-model="useCameraSettingsStore().currentPipelineSettings.contourSortMode"
|
||||
label="Target Sort"
|
||||
tooltip="Chooses the sorting mode used to determine the 'best' targets to provide to user code"
|
||||
:select-cols="interactiveCols"
|
||||
:items="['Largest','Smallest','Highest','Lowest','Rightmost','Leftmost','Centermost']"
|
||||
@input="value => useCameraSettingsStore().changeCurrentPipelineSetting({contourSortMode: value}, false)"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
Reference in New Issue
Block a user