2024-01-03 14:32:04 -07:00
< script setup lang = "ts" >
2024-02-01 21:42:54 -05:00
import type { CameraCalibrationResult , VideoFormat } from "@/types/SettingTypes" ;
2024-01-03 14:32:04 -07:00
import { useCameraSettingsStore } from "@/stores/settings/CameraSettingsStore" ;
import { useStateStore } from "@/stores/StateStore" ;
2024-02-01 21:42:54 -05:00
import { computed , inject , ref } from "vue" ;
2024-01-03 14:32:04 -07:00
import { getResolutionString , parseJsonFile } from "@/lib/PhotonUtils" ;
const props = defineProps < {
videoFormat : VideoFormat ;
} > ( ) ;
2024-02-01 21:42:54 -05:00
const exportCalibration = ref ( ) ;
const openExportCalibrationPrompt = ( ) => {
exportCalibration . value . click ( ) ;
2024-01-03 14:32:04 -07:00
} ;
const importCalibrationFromPhotonJson = ref ( ) ;
const openUploadPhotonCalibJsonPrompt = ( ) => {
importCalibrationFromPhotonJson . value . click ( ) ;
} ;
const importCalibration = async ( ) => {
const files = importCalibrationFromPhotonJson . value . files ;
if ( files . length === 0 ) return ;
const uploadedJson = files [ 0 ] ;
const data = await parseJsonFile < CameraCalibrationResult > ( uploadedJson ) ;
if (
data . resolution . height != props . videoFormat . resolution . height ||
data . resolution . width != props . videoFormat . resolution . width
) {
useStateStore ( ) . showSnackbarMessage ( {
color : "error" ,
message : ` The resolution of the calibration export doesn't match the current resolution ${ props . videoFormat . resolution . height } x ${ props . videoFormat . resolution . width } `
} ) ;
return ;
}
useCameraSettingsStore ( )
. importCalibrationFromData ( { calibration : data } )
. then ( ( response ) => {
useStateStore ( ) . showSnackbarMessage ( {
color : "success" ,
message : response . data . text || response . data
} ) ;
} )
. catch ( ( error ) => {
if ( error . response ) {
useStateStore ( ) . showSnackbarMessage ( {
color : "error" ,
message : error . response . data . text || error . response . data
} ) ;
} else if ( error . request ) {
useStateStore ( ) . showSnackbarMessage ( {
color : "error" ,
message : "Error while trying to process the request! The backend didn't respond."
} ) ;
} else {
useStateStore ( ) . showSnackbarMessage ( {
color : "error" ,
message : "An error occurred while trying to process the request."
} ) ;
}
} ) ;
} ;
interface ObservationDetails {
mean : number ;
index : number ;
}
2024-02-01 21:42:54 -05:00
const currentCalibrationCoeffs = computed < CameraCalibrationResult | undefined > ( ( ) =>
useCameraSettingsStore ( ) . getCalibrationCoeffs ( props . videoFormat . resolution )
) ;
2024-01-03 14:32:04 -07:00
const getObservationDetails = ( ) : ObservationDetails [ ] | undefined => {
2024-02-01 21:42:54 -05:00
const coefficients = currentCalibrationCoeffs . value ;
return coefficients ? . meanErrors . map ( ( m , i ) => ( {
index : i ,
mean : parseFloat ( m . toFixed ( 2 ) )
} ) ) ;
2024-01-03 14:32:04 -07:00
} ;
2024-02-01 21:42:54 -05:00
const exportCalibrationURL = computed < string > ( ( ) =>
useCameraSettingsStore ( ) . getCalJSONUrl ( inject ( "backendHost" ) as string , props . videoFormat . resolution )
) ;
const calibrationImageURL = ( index : number ) =>
useCameraSettingsStore ( ) . getCalImageUrl ( inject < string > ( "backendHost" ) as string , props . videoFormat . resolution , index ) ;
2024-01-03 14:32:04 -07:00
< / script >
< template >
2025-01-08 16:46:31 -05:00
< v-card color = "primary" dark >
Clean up spacing and other things in various parts of the UI (#1972)
## Description
After the Vue 3 upgrade, the spacing for various UI elements was left
inconsistent in many places. Dialogs were hit especially hard and had
some very inconsistent spacing. Additionally, the 24 pixels of padding
around all cards was noted as a waste of space and unnecessary, so it
has been shrunk down to 20 pixels to make the UI a tiny bit more compact
and to make it visually closer to some parts of the UI that have 16
pixels of padding (the camera views are the most notable example).
Padding between input elements has also been reduced to 20 pixels (this
required some hackery to get consistent sizes on input elements, since
switches and sliders have different heights.)
Some other minor UI tweaks were made, such as removing the divider
between dialog contents and dialog buttons because it visually looks
better, shrinking the banner padding so it doesn't displace as much
content, making the banner background one uniform color instead of a
highlight around the icon, fixing the targets tab so that the columns
stop shifting around when the values change, preserving newlines in the
log view, cleaning up the object detection UI, and making the import
dialogs have consistently inset input elements.
Old dashboard:

New dashboard:

Old Camera tab:

New Camera tab:

Old Calibration Info:

New Calibration Info:

Old Log Viewer:

New Log Viewer:

Old Pipeline Creation Dialog:

New Pipeline Creation Dialog:

Old Factory Reset:

New Factory Reset:

Old Pipeline Change:

New Pipeline Change:

Old Import Dialog:

New Import Dialog:

## Meta
Merge checklist:
- [x] Pull Request title is [short, imperative
summary](https://cbea.ms/git-commit/) of proposed changes
- [x] The description documents the _what_ and _why_
- [ ] If this PR changes behavior or adds a feature, user documentation
is updated
- [ ] If this PR touches photon-serde, all messages have been
regenerated and hashes have not changed unexpectedly
- [ ] If this PR touches configuration, this is backwards compatible
with settings back to v2024.3.1
- [ ] If this PR touches pipeline settings or anything related to data
exchange, the frontend typing is updated
- [ ] If this PR addresses a bug, a regression test for it is added
2025-07-12 00:02:23 -04:00
< div class = "d-flex flex-wrap pt-2 pl-2 pr-2" >
2025-01-08 16:46:31 -05:00
< v-col cols = "12" md = "6" >
Clean up spacing and other things in various parts of the UI (#1972)
## Description
After the Vue 3 upgrade, the spacing for various UI elements was left
inconsistent in many places. Dialogs were hit especially hard and had
some very inconsistent spacing. Additionally, the 24 pixels of padding
around all cards was noted as a waste of space and unnecessary, so it
has been shrunk down to 20 pixels to make the UI a tiny bit more compact
and to make it visually closer to some parts of the UI that have 16
pixels of padding (the camera views are the most notable example).
Padding between input elements has also been reduced to 20 pixels (this
required some hackery to get consistent sizes on input elements, since
switches and sliders have different heights.)
Some other minor UI tweaks were made, such as removing the divider
between dialog contents and dialog buttons because it visually looks
better, shrinking the banner padding so it doesn't displace as much
content, making the banner background one uniform color instead of a
highlight around the icon, fixing the targets tab so that the columns
stop shifting around when the values change, preserving newlines in the
log view, cleaning up the object detection UI, and making the import
dialogs have consistently inset input elements.
Old dashboard:

New dashboard:

Old Camera tab:

New Camera tab:

Old Calibration Info:

New Calibration Info:

Old Log Viewer:

New Log Viewer:

Old Pipeline Creation Dialog:

New Pipeline Creation Dialog:

Old Factory Reset:

New Factory Reset:

Old Pipeline Change:

New Pipeline Change:

Old Import Dialog:

New Import Dialog:

## Meta
Merge checklist:
- [x] Pull Request title is [short, imperative
summary](https://cbea.ms/git-commit/) of proposed changes
- [x] The description documents the _what_ and _why_
- [ ] If this PR changes behavior or adds a feature, user documentation
is updated
- [ ] If this PR touches photon-serde, all messages have been
regenerated and hashes have not changed unexpectedly
- [ ] If this PR touches configuration, this is backwards compatible
with settings back to v2024.3.1
- [ ] If this PR touches pipeline settings or anything related to data
exchange, the frontend typing is updated
- [ ] If this PR addresses a bug, a regression test for it is added
2025-07-12 00:02:23 -04:00
< v-card-title class = "pa-0" > Calibration Details < / v-card-title >
2024-01-03 14:32:04 -07:00
< / v-col >
2025-01-08 16:46:31 -05:00
< v-col cols = "6" md = "3" class = "d-flex align-center pt-0 pt-md-3 pl-6 pl-md-3" >
< v-btn color = "secondary" style = "width: 100%" @click ="openUploadPhotonCalibJsonPrompt" >
2025-05-06 18:21:41 -04:00
< v-icon start > mdi - import < / v-icon >
2024-01-03 14:32:04 -07:00
< span > Import < / span >
< / v-btn >
< input
ref = "importCalibrationFromPhotonJson"
type = "file"
accept = ".json"
style = "display: none"
@ change = "importCalibration"
/ >
< / v-col >
2025-01-08 16:46:31 -05:00
< v-col cols = "6" md = "3" class = "d-flex align-center pt-0 pt-md-3 pr-6 pr-md-3" >
2024-01-03 14:32:04 -07:00
< v-btn
color = "secondary"
2024-02-01 21:42:54 -05:00
: disabled = "!currentCalibrationCoeffs"
2024-01-03 14:32:04 -07:00
style = "width: 100%"
2024-02-01 21:42:54 -05:00
@ click = "openExportCalibrationPrompt"
2024-01-03 14:32:04 -07:00
>
2025-05-06 18:21:41 -04:00
< v-icon start > mdi - export < / v-icon >
2024-01-03 14:32:04 -07:00
< span > Export < / span >
< / v-btn >
2024-02-01 21:42:54 -05:00
< a
ref = "exportCalibration"
style = "color: black; text-decoration: none; display: none"
: href = "exportCalibrationURL"
target = "_blank"
/ >
2024-01-03 14:32:04 -07:00
< / v-col >
2025-01-08 16:46:31 -05:00
< / div >
Clean up spacing and other things in various parts of the UI (#1972)
## Description
After the Vue 3 upgrade, the spacing for various UI elements was left
inconsistent in many places. Dialogs were hit especially hard and had
some very inconsistent spacing. Additionally, the 24 pixels of padding
around all cards was noted as a waste of space and unnecessary, so it
has been shrunk down to 20 pixels to make the UI a tiny bit more compact
and to make it visually closer to some parts of the UI that have 16
pixels of padding (the camera views are the most notable example).
Padding between input elements has also been reduced to 20 pixels (this
required some hackery to get consistent sizes on input elements, since
switches and sliders have different heights.)
Some other minor UI tweaks were made, such as removing the divider
between dialog contents and dialog buttons because it visually looks
better, shrinking the banner padding so it doesn't displace as much
content, making the banner background one uniform color instead of a
highlight around the icon, fixing the targets tab so that the columns
stop shifting around when the values change, preserving newlines in the
log view, cleaning up the object detection UI, and making the import
dialogs have consistently inset input elements.
Old dashboard:

New dashboard:

Old Camera tab:

New Camera tab:

Old Calibration Info:

New Calibration Info:

Old Log Viewer:

New Log Viewer:

Old Pipeline Creation Dialog:

New Pipeline Creation Dialog:

Old Factory Reset:

New Factory Reset:

Old Pipeline Change:

New Pipeline Change:

Old Import Dialog:

New Import Dialog:

## Meta
Merge checklist:
- [x] Pull Request title is [short, imperative
summary](https://cbea.ms/git-commit/) of proposed changes
- [x] The description documents the _what_ and _why_
- [ ] If this PR changes behavior or adds a feature, user documentation
is updated
- [ ] If this PR touches photon-serde, all messages have been
regenerated and hashes have not changed unexpectedly
- [ ] If this PR touches configuration, this is backwards compatible
with settings back to v2024.3.1
- [ ] If this PR touches pipeline settings or anything related to data
exchange, the frontend typing is updated
- [ ] If this PR addresses a bug, a regression test for it is added
2025-07-12 00:02:23 -04:00
< v-card-title class = "pt-0 pb-0"
2025-01-08 16:46:31 -05:00
> { { useCameraSettingsStore ( ) . currentCameraName } } @ { { getResolutionString ( videoFormat . resolution ) } } < / v - c a r d - t i t l e
>
< v-card-text v-if = "!currentCalibrationCoeffs" >
2025-05-06 18:21:41 -04:00
< v-banner
rounded
bg - color = "secondary"
color = "secondary"
text - color = "white"
Clean up spacing and other things in various parts of the UI (#1972)
## Description
After the Vue 3 upgrade, the spacing for various UI elements was left
inconsistent in many places. Dialogs were hit especially hard and had
some very inconsistent spacing. Additionally, the 24 pixels of padding
around all cards was noted as a waste of space and unnecessary, so it
has been shrunk down to 20 pixels to make the UI a tiny bit more compact
and to make it visually closer to some parts of the UI that have 16
pixels of padding (the camera views are the most notable example).
Padding between input elements has also been reduced to 20 pixels (this
required some hackery to get consistent sizes on input elements, since
switches and sliders have different heights.)
Some other minor UI tweaks were made, such as removing the divider
between dialog contents and dialog buttons because it visually looks
better, shrinking the banner padding so it doesn't displace as much
content, making the banner background one uniform color instead of a
highlight around the icon, fixing the targets tab so that the columns
stop shifting around when the values change, preserving newlines in the
log view, cleaning up the object detection UI, and making the import
dialogs have consistently inset input elements.
Old dashboard:

New dashboard:

Old Camera tab:

New Camera tab:

Old Calibration Info:

New Calibration Info:

Old Log Viewer:

New Log Viewer:

Old Pipeline Creation Dialog:

New Pipeline Creation Dialog:

Old Factory Reset:

New Factory Reset:

Old Pipeline Change:

New Pipeline Change:

Old Import Dialog:

New Import Dialog:

## Meta
Merge checklist:
- [x] Pull Request title is [short, imperative
summary](https://cbea.ms/git-commit/) of proposed changes
- [x] The description documents the _what_ and _why_
- [ ] If this PR changes behavior or adds a feature, user documentation
is updated
- [ ] If this PR touches photon-serde, all messages have been
regenerated and hashes have not changed unexpectedly
- [ ] If this PR touches configuration, this is backwards compatible
with settings back to v2024.3.1
- [ ] If this PR touches pipeline settings or anything related to data
exchange, the frontend typing is updated
- [ ] If this PR addresses a bug, a regression test for it is added
2025-07-12 00:02:23 -04:00
class = "pt-3 pb-3"
2025-05-06 18:21:41 -04:00
density = "compact"
icon = "mdi-alert-circle-outline"
>
2025-01-08 16:46:31 -05:00
The selected video format has not been calibrated .
< / v-banner >
< / v-card-text >
2025-05-06 18:21:41 -04:00
< v-card-text class = "pt-0" >
< v-table density = "compact" style = "width: 100%" >
2024-01-03 14:32:04 -07:00
< template # default >
< thead >
< tr >
< th class = "text-left" > Name < / th >
< th class = "text-left" > Value < / th >
< / tr >
< / thead >
< tbody >
< tr >
< td > Fx < / td >
2024-01-03 15:23:39 -07:00
< td >
{ {
useCameraSettingsStore ( )
. getCalibrationCoeffs ( props . videoFormat . resolution )
? . cameraIntrinsics . data [ 0 ] . toFixed ( 2 ) || 0.0
} }
mm
< / td >
2024-01-03 14:32:04 -07:00
< / tr >
< tr >
< td > Fy < / td >
2024-01-03 15:23:39 -07:00
< td >
{ {
useCameraSettingsStore ( )
. getCalibrationCoeffs ( props . videoFormat . resolution )
? . cameraIntrinsics . data [ 4 ] . toFixed ( 2 ) || 0.0
} }
mm
< / td >
2024-01-03 14:32:04 -07:00
< / tr >
< tr >
< td > Cx < / td >
2024-01-03 15:23:39 -07:00
< td >
{ {
useCameraSettingsStore ( )
. getCalibrationCoeffs ( props . videoFormat . resolution )
? . cameraIntrinsics . data [ 2 ] . toFixed ( 2 ) || 0.0
} }
px
< / td >
2024-01-03 14:32:04 -07:00
< / tr >
< tr >
< td > Cy < / td >
2024-01-03 15:23:39 -07:00
< td >
{ {
useCameraSettingsStore ( )
. getCalibrationCoeffs ( props . videoFormat . resolution )
? . cameraIntrinsics . data [ 5 ] . toFixed ( 2 ) || 0.0
} }
px
< / td >
2024-01-03 14:32:04 -07:00
< / tr >
< tr >
< td > Distortion < / td >
2024-01-03 15:23:39 -07:00
< td >
{ {
useCameraSettingsStore ( )
. getCalibrationCoeffs ( props . videoFormat . resolution )
? . distCoeffs . data . map ( ( it ) => parseFloat ( it . toFixed ( 3 ) ) ) || [ ]
} }
< / td >
2024-01-03 14:32:04 -07:00
< / tr >
< tr >
< td > Mean Err < / td >
< td >
{ {
videoFormat . mean !== undefined
? isNaN ( videoFormat . mean )
? "NaN"
: videoFormat . mean . toFixed ( 2 ) + "px"
: "-"
} }
< / td >
< / tr >
< tr >
< td > Horizontal FOV < / td >
2024-02-01 21:42:54 -05:00
< td >
{ { videoFormat . horizontalFOV !== undefined ? videoFormat . horizontalFOV . toFixed ( 2 ) + "°" : "-" } }
< / td >
2024-01-03 14:32:04 -07:00
< / tr >
< tr >
< td > Vertical FOV < / td >
< td > { { videoFormat . verticalFOV !== undefined ? videoFormat . verticalFOV . toFixed ( 2 ) + "°" : "-" } } < / td >
< / tr >
< tr >
< td > Diagonal FOV < / td >
< td > { { videoFormat . diagonalFOV !== undefined ? videoFormat . diagonalFOV . toFixed ( 2 ) + "°" : "-" } } < / td >
< / tr >
2024-01-05 12:26:17 -07:00
<!-- Board warp , only shown for mrcal - calibrated cameras -- >
2024-02-01 21:42:54 -05:00
< tr v-if = "currentCalibrationCoeffs?.calobjectWarp?.length === 2" >
2024-01-05 12:26:17 -07:00
< td > Board warp , X / Y < / td >
< td >
{ {
useCameraSettingsStore ( )
. getCalibrationCoeffs ( props . videoFormat . resolution )
? . calobjectWarp ? . map ( ( it ) => ( it * 1000 ) . toFixed ( 2 ) + " mm" )
. join ( " / " )
} }
< / td >
< / tr >
2024-01-03 14:32:04 -07:00
< / tbody >
< / template >
2025-05-06 18:21:41 -04:00
< / v-table >
2025-01-08 16:46:31 -05:00
< / v-card-text >
Clean up spacing and other things in various parts of the UI (#1972)
## Description
After the Vue 3 upgrade, the spacing for various UI elements was left
inconsistent in many places. Dialogs were hit especially hard and had
some very inconsistent spacing. Additionally, the 24 pixels of padding
around all cards was noted as a waste of space and unnecessary, so it
has been shrunk down to 20 pixels to make the UI a tiny bit more compact
and to make it visually closer to some parts of the UI that have 16
pixels of padding (the camera views are the most notable example).
Padding between input elements has also been reduced to 20 pixels (this
required some hackery to get consistent sizes on input elements, since
switches and sliders have different heights.)
Some other minor UI tweaks were made, such as removing the divider
between dialog contents and dialog buttons because it visually looks
better, shrinking the banner padding so it doesn't displace as much
content, making the banner background one uniform color instead of a
highlight around the icon, fixing the targets tab so that the columns
stop shifting around when the values change, preserving newlines in the
log view, cleaning up the object detection UI, and making the import
dialogs have consistently inset input elements.
Old dashboard:

New dashboard:

Old Camera tab:

New Camera tab:

Old Calibration Info:

New Calibration Info:

Old Log Viewer:

New Log Viewer:

Old Pipeline Creation Dialog:

New Pipeline Creation Dialog:

Old Factory Reset:

New Factory Reset:

Old Pipeline Change:

New Pipeline Change:

Old Import Dialog:

New Import Dialog:

## Meta
Merge checklist:
- [x] Pull Request title is [short, imperative
summary](https://cbea.ms/git-commit/) of proposed changes
- [x] The description documents the _what_ and _why_
- [ ] If this PR changes behavior or adds a feature, user documentation
is updated
- [ ] If this PR touches photon-serde, all messages have been
regenerated and hashes have not changed unexpectedly
- [ ] If this PR touches configuration, this is backwards compatible
with settings back to v2024.3.1
- [ ] If this PR touches pipeline settings or anything related to data
exchange, the frontend typing is updated
- [ ] If this PR addresses a bug, a regression test for it is added
2025-07-12 00:02:23 -04:00
< v-card-title v-if = "currentCalibrationCoeffs" class="pt-0 pb-0" > Individual Observations < / v-card-title >
< v-card-text v-if = "currentCalibrationCoeffs" class="pt-0" >
2024-01-03 14:32:04 -07:00
< v-data-table
2025-05-06 18:21:41 -04:00
density = "compact"
2024-01-03 14:32:04 -07:00
style = "width: 100%"
: headers = " [
2025-05-06 18:21:41 -04:00
{ title : 'Observation Id' , key : 'index' } ,
{ title : 'Mean Reprojection Error' , key : 'mean' } ,
{ title : '' , key : 'data-table-expand' }
2024-01-03 14:32:04 -07:00
] "
: items = "getObservationDetails()"
2025-05-06 18:21:41 -04:00
item - value = "index"
2024-01-03 14:32:04 -07:00
show - expand
>
2025-05-06 18:21:41 -04:00
< template # item.data -table -expand = " { internalItem , toggleExpand } " >
< v-btn
icon = "mdi-eye"
class = "text-none"
color = "medium-emphasis"
size = "small"
variant = "text"
slim
@ click = "toggleExpand(internalItem)"
> < / v-btn >
< / template >
< template # expanded -row = " { columns , item } " >
< td :colspan = "columns.length" >
2024-01-03 14:32:04 -07:00
< div style = "display: flex; justify-content: center; width: 100%" >
2024-02-01 21:42:54 -05:00
< img :src = "calibrationImageURL(item.index)" alt = "observation image" class = "snapshot-preview pt-2 pb-2" / >
2024-01-03 14:32:04 -07:00
< / div >
< / td >
< / template >
< / v-data-table >
2025-01-08 16:46:31 -05:00
< / v-card-text >
2024-01-03 14:32:04 -07:00
< / v-card >
< / template >
< style scoped >
. v - data - table {
background - color : # 006492 ! important ;
}
. snapshot - preview {
max - width : 55 % ;
}
@ media only screen and ( max - width : 512 px ) {
. snapshot - preview {
max - width : 100 % ;
}
}
< / style >