2023-08-21 01:51:35 -04:00
< script setup lang = "ts" >
import { useCameraSettingsStore } from "@/stores/settings/CameraSettingsStore" ;
2026-05-05 10:24:19 -05:00
import {
type ActivePipelineSettings ,
PipelineType ,
ContourSortMode ,
ContourTargetOrientation ,
ContourGroupingMode ,
ContourIntersection ,
ContourShape
} from "@/types/PipelineTypes" ;
2023-10-17 16:32:59 -04:00
import PvRangeSlider from "@/components/common/pv-range-slider.vue" ;
import PvSelect from "@/components/common/pv-select.vue" ;
import PvSlider from "@/components/common/pv-slider.vue" ;
2025-05-06 18:21:41 -04:00
import { computed } from "vue" ;
2023-08-21 01:51:35 -04:00
import { useStateStore } from "@/stores/StateStore" ;
2025-05-06 18:21:41 -04:00
import { useDisplay } from "vuetify" ;
2023-08-21 01:51:35 -04:00
// 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
2024-01-02 11:03:16 -05:00
const currentPipelineSettings = computed < ActivePipelineSettings > (
( ) => useCameraSettingsStore ( ) . currentPipelineSettings
) ;
2023-08-21 01:51:35 -04:00
2023-10-17 16:32:59 -04:00
// TODO fix pv-range-slider so that store access doesn't need to be deferred
2023-08-21 01:51:35 -04:00
const contourArea = computed < [ number , number ] > ( {
get : ( ) => Object . values ( useCameraSettingsStore ( ) . currentPipelineSettings . contourArea ) as [ number , number ] ,
2023-08-31 16:56:58 -04:00
set : ( v ) => ( useCameraSettingsStore ( ) . currentPipelineSettings . contourArea = v )
2023-08-21 01:51:35 -04:00
} ) ;
const contourRatio = computed < [ number , number ] > ( {
get : ( ) => Object . values ( useCameraSettingsStore ( ) . currentPipelineSettings . contourRatio ) as [ number , number ] ,
2023-08-31 16:56:58 -04:00
set : ( v ) => ( useCameraSettingsStore ( ) . currentPipelineSettings . contourRatio = v )
2023-08-21 01:51:35 -04:00
} ) ;
const contourFullness = computed < [ number , number ] > ( {
get : ( ) => Object . values ( useCameraSettingsStore ( ) . currentPipelineSettings . contourFullness ) as [ number , number ] ,
2023-08-31 16:56:58 -04:00
set : ( v ) => ( useCameraSettingsStore ( ) . currentPipelineSettings . contourFullness = v )
2023-08-21 01:51:35 -04:00
} ) ;
const contourPerimeter = computed < [ number , number ] > ( {
2023-08-31 16:56:58 -04:00
get : ( ) =>
2024-01-02 11:03:16 -05:00
currentPipelineSettings . value . pipelineType === PipelineType . ColoredShape
? ( Object . values ( currentPipelineSettings . value . contourPerimeter ) as [ number , number ] )
2023-08-31 16:56:58 -04:00
: ( [ 0 , 0 ] as [ number , number ] ) ,
set : ( v ) => {
2024-01-02 11:03:16 -05:00
if ( currentPipelineSettings . value . pipelineType === PipelineType . ColoredShape ) {
currentPipelineSettings . value . contourPerimeter = v ;
2023-08-21 01:51:35 -04:00
}
}
} ) ;
const contourRadius = computed < [ number , number ] > ( {
2023-08-31 16:56:58 -04:00
get : ( ) =>
2024-01-02 11:03:16 -05:00
currentPipelineSettings . value . pipelineType === PipelineType . ColoredShape
? ( Object . values ( currentPipelineSettings . value . contourRadius ) as [ number , number ] )
2023-08-31 16:56:58 -04:00
: ( [ 0 , 0 ] as [ number , number ] ) ,
set : ( v ) => {
2024-01-02 11:03:16 -05:00
if ( currentPipelineSettings . value . pipelineType === PipelineType . ColoredShape ) {
currentPipelineSettings . value . contourRadius = v ;
2023-08-21 01:51:35 -04:00
}
}
} ) ;
2025-05-06 18:21:41 -04:00
const { mdAndDown } = useDisplay ( ) ;
2024-01-16 22:23:05 -05:00
const interactiveCols = computed ( ( ) =>
2025-05-06 18:21:41 -04:00
mdAndDown . value && ( ! useStateStore ( ) . sidebarFolded || useCameraSettingsStore ( ) . isDriverMode ) ? 8 : 7
2024-01-16 22:23:05 -05:00
) ;
2023-08-21 01:51:35 -04:00
< / script >
< template >
< div >
2025-01-07 08:45:39 -05:00
< pv-select
v - model = "useCameraSettingsStore().currentPipelineSettings.contourTargetOrientation"
label = "Target Orientation"
tooltip = "Used to determine how to calculate target landmarks, as well as aspect ratio"
2026-05-05 10:24:19 -05:00
: items = " [
{ value : ContourTargetOrientation . Portrait , name : 'Portrait' } ,
{ value : ContourTargetOrientation . Landscape , name : 'Landscape' }
] "
2025-01-07 08:45:39 -05:00
: select - cols = "interactiveCols"
2025-05-06 18:21:41 -04:00
@ update : modelValue = "
2025-01-07 08:45:39 -05:00
( value ) => useCameraSettingsStore ( ) . changeCurrentPipelineSetting ( { contourTargetOrientation : value } , false )
"
/ >
2025-01-08 16:46:31 -05:00
< pv-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"
2026-05-05 10:24:19 -05:00
: items = " [
{ value : ContourSortMode . Largest , name : 'Largest' } ,
{ value : ContourSortMode . Smallest , name : 'Smallest' } ,
{ value : ContourSortMode . Highest , name : 'Highest' } ,
{ value : ContourSortMode . Lowest , name : 'Lowest' } ,
{ value : ContourSortMode . Rightmost , name : 'Rightmost' } ,
{ value : ContourSortMode . Leftmost , name : 'Leftmost' } ,
{ value : ContourSortMode . Centermost , name : 'Centermost' }
] "
2025-05-06 18:21:41 -04:00
@ update : modelValue = "
( value ) => useCameraSettingsStore ( ) . changeCurrentPipelineSetting ( { contourSortMode : value } , false )
"
2025-01-08 16:46:31 -05:00
/ >
2023-10-17 16:32:59 -04:00
< pv-range-slider
2023-08-21 01:51:35 -04:00
v - model = "contourArea"
label = "Area"
: min = "0"
: max = "100"
: slider - cols = "interactiveCols"
: step = "0.01"
2025-05-06 18:21:41 -04:00
@ update : modelValue = "
( value ) => useCameraSettingsStore ( ) . changeCurrentPipelineSetting ( { contourArea : value } , false )
"
2023-08-21 01:51:35 -04:00
/ >
2023-10-17 16:32:59 -04:00
< pv-range-slider
2023-08-21 01:51:35 -04:00
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"
2025-05-06 18:21:41 -04:00
@ update : modelValue = "
( value ) => useCameraSettingsStore ( ) . changeCurrentPipelineSetting ( { contourRatio : value } , false )
"
2023-08-21 01:51:35 -04:00
/ >
2023-10-17 16:32:59 -04:00
< pv-range-slider
2023-08-21 01:51:35 -04:00
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"
2025-05-06 18:21:41 -04:00
@ update : modelValue = "
( value ) => useCameraSettingsStore ( ) . changeCurrentPipelineSetting ( { contourFullness : value } , false )
"
2023-08-21 01:51:35 -04:00
/ >
2023-10-17 16:32:59 -04:00
< pv-range-slider
2023-08-21 01:51:35 -04:00
v - if = "currentPipelineSettings.pipelineType === PipelineType.ColoredShape"
v - model = "contourPerimeter"
label = "Perimeter"
tooltip = "Min and max perimeter of the shape, in pixels"
2024-01-02 11:03:16 -05:00
: min = "0"
: max = "4000"
2023-08-21 01:51:35 -04:00
: slider - cols = "interactiveCols"
2025-05-06 18:21:41 -04:00
@ update : modelValue = "
( value ) => useCameraSettingsStore ( ) . changeCurrentPipelineSetting ( { contourPerimeter : value } , false )
"
2023-08-21 01:51:35 -04:00
/ >
2023-10-17 16:32:59 -04:00
< pv-slider
2023-08-21 01:51:35 -04:00
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"
2025-05-06 18:21:41 -04:00
@ update : modelValue = "
2023-08-31 16:56:58 -04:00
( value ) => useCameraSettingsStore ( ) . changeCurrentPipelineSetting ( { contourSpecklePercentage : value } , false )
"
2023-08-21 01:51:35 -04:00
/ >
< template v-if = "currentPipelineSettings.pipelineType === PipelineType.Reflective" >
2023-10-17 16:32:59 -04:00
< pv-slider
2023-08-21 01:51:35 -04:00
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"
2025-05-06 18:21:41 -04:00
@ update : modelValue = "
( value ) => useCameraSettingsStore ( ) . changeCurrentPipelineSetting ( { contourFilterRangeX : value } , false )
"
2023-08-21 01:51:35 -04:00
/ >
2023-10-17 16:32:59 -04:00
< pv-slider
2023-08-21 01:51:35 -04:00
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"
2025-05-06 18:21:41 -04:00
@ update : modelValue = "
( value ) => useCameraSettingsStore ( ) . changeCurrentPipelineSetting ( { contourFilterRangeY : value } , false )
"
2023-08-21 01:51:35 -04:00
/ >
2023-10-17 16:32:59 -04:00
< pv-select
2023-08-21 01:51:35 -04:00
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"
2026-05-05 10:24:19 -05:00
: items = " [
{ value : ContourGroupingMode . Single , name : 'Single' } ,
{ value : ContourGroupingMode . Dual , name : 'Dual' } ,
{ value : ContourGroupingMode . TwoOrMore , name : 'Two or More' }
] "
2025-05-06 18:21:41 -04:00
@ update : modelValue = "
( value ) => useCameraSettingsStore ( ) . changeCurrentPipelineSetting ( { contourGroupingMode : value } , false )
"
2023-08-21 01:51:35 -04:00
/ >
2023-10-17 16:32:59 -04:00
< pv-select
2023-08-21 01:51:35 -04:00
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"
2026-05-05 10:24:19 -05:00
: items = " [
{ value : ContourIntersection . None , name : 'None' } ,
{ value : ContourIntersection . Up , name : 'Up' } ,
{ value : ContourIntersection . Down , name : 'Down' } ,
{ value : ContourIntersection . Left , name : 'Left' } ,
{ value : ContourIntersection . Right , name : 'Right' }
] "
2023-08-21 01:51:35 -04:00
: disabled = "useCameraSettingsStore().currentPipelineSettings.contourGroupingMode === 0"
2025-05-06 18:21:41 -04:00
@ update : modelValue = "
( value ) => useCameraSettingsStore ( ) . changeCurrentPipelineSetting ( { contourIntersection : value } , false )
"
2023-08-21 01:51:35 -04:00
/ >
< / template >
< template v-else-if = "currentPipelineSettings.pipelineType === PipelineType.ColoredShape" >
2023-10-17 16:32:59 -04:00
< pv-select
2023-08-21 01:51:35 -04:00
v - model = "currentPipelineSettings.contourShape"
label = "Target Shape"
tooltip = "The shape of targets to look for"
: select - cols = "interactiveCols"
2026-05-05 10:24:19 -05:00
: items = " [
{ value : ContourShape . Circle , name : 'Circle' } ,
{ value : ContourShape . Polygon , name : 'Polygon' } ,
{ value : ContourShape . Triangle , name : 'Triangle' } ,
{ value : ContourShape . Quadrilateral , name : 'Quadrilateral' }
] "
2025-05-06 18:21:41 -04:00
@ update : modelValue = "
( value ) => useCameraSettingsStore ( ) . changeCurrentPipelineSetting ( { contourShape : value } , false )
"
2023-08-21 01:51:35 -04:00
/ >
2023-10-17 16:32:59 -04:00
< pv-slider
2025-01-08 16:46:31 -05:00
v - if = "currentPipelineSettings.contourShape >= 1"
2023-08-21 01:51:35 -04:00
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"
2025-05-06 18:21:41 -04:00
@ update : modelValue = "
( value ) => useCameraSettingsStore ( ) . changeCurrentPipelineSetting ( { accuracyPercentage : value } , false )
"
2023-08-21 01:51:35 -04:00
/ >
2023-10-17 16:32:59 -04:00
< pv-slider
2025-01-08 16:46:31 -05:00
v - if = "currentPipelineSettings.contourShape === 0"
2023-08-21 01:51:35 -04:00
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"
2025-05-06 18:21:41 -04:00
@ update : modelValue = "
2023-08-31 16:56:58 -04:00
( value ) => useCameraSettingsStore ( ) . changeCurrentPipelineSetting ( { circleDetectThreshold : value } , false )
"
2023-08-21 01:51:35 -04:00
/ >
2023-10-17 16:32:59 -04:00
< pv-slider
2025-01-08 16:46:31 -05:00
v - if = "currentPipelineSettings.contourShape === 0"
2023-08-21 01:51:35 -04:00
v - model = "currentPipelineSettings.maxCannyThresh"
: disabled = "currentPipelineSettings.contourShape !== 0"
label = "Max Canny Threshold"
: min = "1"
: max = "100"
: slider - cols = "interactiveCols"
2025-05-06 18:21:41 -04:00
@ update : modelValue = "
( value ) => useCameraSettingsStore ( ) . changeCurrentPipelineSetting ( { maxCannyThresh : value } , false )
"
2023-08-21 01:51:35 -04:00
/ >
2023-10-17 16:32:59 -04:00
< pv-slider
2025-01-08 16:46:31 -05:00
v - if = "currentPipelineSettings.contourShape === 0"
2023-08-21 01:51:35 -04:00
v - model = "currentPipelineSettings.circleAccuracy"
: disabled = "currentPipelineSettings.contourShape !== 0"
label = "Circle Accuracy"
: min = "1"
: max = "100"
: slider - cols = "interactiveCols"
2025-05-06 18:21:41 -04:00
@ update : modelValue = "
( value ) => useCameraSettingsStore ( ) . changeCurrentPipelineSetting ( { circleAccuracy : value } , false )
"
2023-08-21 01:51:35 -04:00
/ >
2025-01-07 08:45:39 -05:00
< pv-range-slider
2025-01-08 16:46:31 -05:00
v - if = "currentPipelineSettings.contourShape === 0"
2025-01-07 08:45:39 -05:00
v - model = "contourRadius"
: disabled = "currentPipelineSettings.contourShape !== 0"
label = "Radius"
: min = "0"
: max = "100"
: slider - cols = "interactiveCols"
2025-05-06 18:21:41 -04:00
@ update : modelValue = "
( value ) => useCameraSettingsStore ( ) . changeCurrentPipelineSetting ( { contourRadius : value } , false )
"
2025-01-07 08:45:39 -05:00
/ >
2023-08-21 01:51:35 -04:00
< / template >
< / div >
< / template >