Enable auto search and other fixes (#62)

Closes: #58

Closes: #59

Signed-off-by: Justin Georgi <justin.georgi@gmail.com>

Reviewed-on: Georgi_Lab/ALVINN_f7#62
This commit is contained in:
2023-12-24 12:12:10 -07:00
parent cf4e9f7c3a
commit 01e8b73677
3 changed files with 63 additions and 35 deletions

View File

@@ -8,6 +8,8 @@
<path v-else-if="icon == 'photo_camera'" d="M480-260q75 0 127.5-52.5T660-440q0-75-52.5-127.5T480-620q-75 0-127.5 52.5T300-440q0 75 52.5 127.5T480-260Zm0-80q-42 0-71-29t-29-71q0-42 29-71t71-29q42 0 71 29t29 71q0 42-29 71t-71 29ZM160-120q-33 0-56.5-23.5T80-200v-480q0-33 23.5-56.5T160-760h126l74-80h240l74 80h126q33 0 56.5 23.5T880-680v480q0 33-23.5 56.5T800-120H160Zm0-80h640v-480H638l-73-80H395l-73 80H160v480Zm320-240Z"/> <path v-else-if="icon == 'photo_camera'" d="M480-260q75 0 127.5-52.5T660-440q0-75-52.5-127.5T480-620q-75 0-127.5 52.5T300-440q0 75 52.5 127.5T480-260Zm0-80q-42 0-71-29t-29-71q0-42 29-71t71-29q42 0 71 29t29 71q0 42-29 71t-71 29ZM160-120q-33 0-56.5-23.5T80-200v-480q0-33 23.5-56.5T160-760h126l74-80h240l74 80h126q33 0 56.5 23.5T880-680v480q0 33-23.5 56.5T800-120H160Zm0-80h640v-480H638l-73-80H395l-73 80H160v480Zm320-240Z"/>
<path v-else-if="icon == 'cloud_upload'" d="M260-160q-91 0-155.5-63T40-377q0-78 47-139t123-78q25-92 100-149t170-57q117 0 198.5 81.5T760-520q69 8 114.5 59.5T920-340q0 75-52.5 127.5T740-160H520q-33 0-56.5-23.5T440-240v-206l-64 62-56-56 160-160 160 160-56 56-64-62v206h220q42 0 71-29t29-71q0-42-29-71t-71-29h-60v-80q0-83-58.5-141.5T480-720q-83 0-141.5 58.5T280-520h-20q-58 0-99 41t-41 99q0 58 41 99t99 41h100v80H260Zm220-280Z"/> <path v-else-if="icon == 'cloud_upload'" d="M260-160q-91 0-155.5-63T40-377q0-78 47-139t123-78q25-92 100-149t170-57q117 0 198.5 81.5T760-520q69 8 114.5 59.5T920-340q0 75-52.5 127.5T740-160H520q-33 0-56.5-23.5T440-240v-206l-64 62-56-56 160-160 160 160-56 56-64-62v206h220q42 0 71-29t29-71q0-42-29-71t-71-29h-60v-80q0-83-58.5-141.5T480-720q-83 0-141.5 58.5T280-520h-20q-58 0-99 41t-41 99q0 58 41 99t99 41h100v80H260Zm220-280Z"/>
<path v-else-if="icon == 'cloud_done'" d="m414-280 226-226-58-58-169 169-84-84-57 57 142 142ZM260-160q-91 0-155.5-63T40-377q0-78 47-139t123-78q25-92 100-149t170-57q117 0 198.5 81.5T760-520q69 8 114.5 59.5T920-340q0 75-52.5 127.5T740-160H260Zm0-80h480q42 0 71-29t29-71q0-42-29-71t-71-29h-60v-80q0-83-58.5-141.5T480-720q-83 0-141.5 58.5T280-520h-20q-58 0-99 41t-41 99q0 58 41 99t99 41Zm220-240Z"/> <path v-else-if="icon == 'cloud_done'" d="m414-280 226-226-58-58-169 169-84-84-57 57 142 142ZM260-160q-91 0-155.5-63T40-377q0-78 47-139t123-78q25-92 100-149t170-57q117 0 198.5 81.5T760-520q69 8 114.5 59.5T920-340q0 75-52.5 127.5T740-160H260Zm0-80h480q42 0 71-29t29-71q0-42-29-71t-71-29h-60v-80q0-83-58.5-141.5T480-720q-83 0-141.5 58.5T280-520h-20q-58 0-99 41t-41 99q0 58 41 99t99 41Zm220-240Z"/>
<path v-else-if="icon == 'check_list'" d="M655-200 513-342l56-56 85 85 170-170 56 57-225 226Zm0-320L513-662l56-56 85 85 170-170 56 57-225 226ZM80-280v-80h360v80H80Zm0-320v-80h360v80H80Z"/>
<path v-else-if="icon == 'refresh_search'" d="M822-142 592-372q-32 26-71 39t-81 13q-42 0-80-12.5T290-368l58-58q20 12 43 19t49 7q75 0 127.5-52.5T620-580q0-75-52.5-127.5T440-760q-69 0-119.5 46.5T262-598l50-50 56 56-148 148L72-592l56-56 54 52q6-103 80-173.5T440-840q109 0 184.5 75.5T700-580q0 42-13 82t-39 70l230 230-56 56Z"/>
</svg> </svg>
</template> </template>
@@ -26,7 +28,9 @@
'no_photography', 'no_photography',
'photo_camera', 'photo_camera',
'cloud_upload', 'cloud_upload',
'cloud_done' 'cloud_done',
'check_list',
'refresh_search'
] ]
return iconList.includes(value) return iconList.includes(value)
} }

View File

@@ -1,11 +1,8 @@
<template> <template>
<f7-page name="detect"> <f7-page name="detect" id="detect-page">
<!-- Top Navbar --> <!-- Top Navbar -->
<f7-navbar :sliding="false" back-link="true" back-link-url="/" back-link-force> <f7-navbar :sliding="false" back-link="true" back-link-url="/" back-link-force>
<f7-nav-title sliding>{{ regions[activeRegion] }}</f7-nav-title> <f7-nav-title sliding>{{ regions[activeRegion] }}</f7-nav-title>
<f7-nav-right>
<f7-link icon-ios="f7:menu" icon-md="material:settings" :panel-open="`#${detectorName}-settings`"></f7-link>
</f7-nav-right>
</f7-navbar> </f7-navbar>
<f7-block class="detect-grid"> <f7-block class="detect-grid">
<div class="image-container"> <div class="image-container">
@@ -26,6 +23,16 @@
/> />
<span v-if="numResults == 0" style="height: var(--f7-chip-height); font-size: calc(var(--f7-chip-height) - 4px); font-weight: bolder; margin: 2px;">No results.</span> <span v-if="numResults == 0" style="height: var(--f7-chip-height); font-size: calc(var(--f7-chip-height) - 4px); font-weight: bolder; margin: 2px;">No results.</span>
</div> </div>
<div v-if="showDetectSettings" class="detect-inputs" style="grid-area: detect-settings;">
<f7-range class="level-slide-horz" :min="0" :max="100" :step="1" @range:change="onLevelChange" v-model:value="detectorLevel" type="range" style="flex: 1 1 50px"/>
<f7-range class="level-slide-vert" vertical :min="0" :max="100" :step="1" @range:change="onLevelChange" v-model:value="detectorLevel" type="range" style="flex: 1 1 50px"/>
<f7-button @click="() => detectPanel = !detectPanel" :panel-open="!detectPanel && `#${detectorName}-settings`" :panel-close="detectPanel && `#${detectorName}-settings`">
<SvgIcon icon="check_list"/>
</f7-button>
<f7-button @click="setData">
<SvgIcon icon="refresh_search"/>
</f7-button>
</div>
<f7-segmented class="image-menu" raised> <f7-segmented class="image-menu" raised>
<f7-button popover-open="#region-popover"> <f7-button popover-open="#region-popover">
<RegionIcon :region="activeRegion" /> <RegionIcon :region="activeRegion" />
@@ -33,7 +40,7 @@
<f7-button popover-open="#capture-popover"> <f7-button popover-open="#capture-popover">
<SvgIcon icon="image"/> <SvgIcon icon="image"/>
</f7-button> </f7-button>
<f7-button @click="setData" :class="(imageLoaded) ? '' : 'disabled'"> <f7-button @click="() => showDetectSettings = !showDetectSettings" :class="(imageLoaded) ? '' : 'disabled'">
<SvgIcon icon="visibility"/> <SvgIcon icon="visibility"/>
</f7-button> </f7-button>
<f7-button :class="(numResults && uploadDirty && viewedAll) ? '' : 'disabled'" @click="submitData"> <f7-button :class="(numResults && uploadDirty && viewedAll) ? '' : 'disabled'" @click="submitData">
@@ -43,24 +50,14 @@
<input type="file" ref="image_chooser" @change="getImage()" accept="image/*" capture="environment" style="display: none;"/> <input type="file" ref="image_chooser" @change="getImage()" accept="image/*" capture="environment" style="display: none;"/>
</f7-block> </f7-block>
<f7-panel :id="detectorName + '-settings'" right cover> <f7-panel :id="detectorName + '-settings'" right cover :backdrop="false" container-el="#detect-page">
<f7-page> <f7-page>
<f7-navbar title="Detection Settings"></f7-navbar> <f7-navbar title="Detection Settings"></f7-navbar>
<f7-list> <f7-list>
<f7-list-input v-model:value="detectorLevel" :label="`Confidence % threshold: ${detectorLevel}`" type="range" /> <f7-list-button title="Close List" @click="() => detectPanel = false" :panel-close="`#${detectorName}-settings`"></f7-list-button>
<f7-list-item accordion-item title="Structures"> <f7-list-item checkbox checked checkbox-icon="end" title="All/none" @change="selectAll"></f7-list-item>
<f7-accordion-content> <f7-list-item v-for="structure in detectorLabels" :key="structure.name" checkbox checkbox-icon="end" v-model:checked="structure.detect" :title="structure.name"></f7-list-item>
<f7-list>
<f7-list-item checkbox checked checkbox-icon="end" title="All/none" @change="selectAll"></f7-list-item>
<f7-list-item v-for="structure in detectorLabels" :key="structure.name" checkbox checkbox-icon="end" v-model:checked="structure.detect" :title="structure.name"></f7-list-item>
</f7-list>
</f7-accordion-content>
</f7-list-item>
<f7-list-item title="Turn on debugging">
<f7-toggle v-model:checked="debugOn" style="margin-right: 16px;" />
</f7-list-item>
</f7-list> </f7-list>
<f7-block v-if="debugOn" v-html="debugDisplay" />
</f7-page> </f7-page>
</f7-panel> </f7-panel>
@@ -102,10 +99,11 @@
.detect-grid { .detect-grid {
display: grid; display: grid;
grid-template-columns: 1fr; grid-template-columns: 1fr;
grid-template-rows: 1fr auto min-content; grid-template-rows: 1fr auto auto min-content;
grid-template-areas: grid-template-areas:
"image-view" "image-view"
"result-view" "result-view"
"detect-settings"
"menu-view"; "menu-view";
justify-items: center; justify-items: center;
height: calc(100% - var(--f7-navbar-height) - var(--f7-safe-area-top) - var(--f7-safe-area-bottom)); height: calc(100% - var(--f7-navbar-height) - var(--f7-safe-area-top) - var(--f7-safe-area-bottom));
@@ -160,6 +158,19 @@
transform: translate(-2px, -2px); transform: translate(-2px, -2px);
} }
.detect-inputs {
display: flex;
align-items: center;
margin: 5px;
width: 100%;
max-width: 400px;
min-width: 192px;
}
.level-slide-vert {
display: none;
}
.image-menu { .image-menu {
grid-area: menu-view; grid-area: menu-view;
margin: 5px; margin: 5px;
@@ -192,10 +203,10 @@
@media (max-height: 450px) and (orientation: landscape) { @media (max-height: 450px) and (orientation: landscape) {
.detect-grid { .detect-grid {
grid-template-columns: minmax(0,1fr) max-content auto; grid-template-columns: minmax(0,1fr) max-content auto auto;
grid-template-rows: calc(100vh - var(--f7-navbar-height) - var(--f7-safe-area-top) - var(--f7-safe-area-bottom) - 64px); grid-template-rows: calc(100vh - var(--f7-navbar-height) - var(--f7-safe-area-top) - var(--f7-safe-area-bottom) - 64px);
grid-template-areas: grid-template-areas:
"image-view result-view menu-view"; "image-view result-view detect-settings menu-view";
justify-items: stretch; justify-items: stretch;
align-items: stretch; align-items: stretch;
height: calc(100% - var(--f7-navbar-height) - var(--f7-safe-area-top) - var(--f7-safe-area-bottom)); height: calc(100% - var(--f7-navbar-height) - var(--f7-safe-area-top) - var(--f7-safe-area-bottom));
@@ -211,6 +222,21 @@
overflow-y: scroll; overflow-y: scroll;
} }
.detect-inputs {
flex-direction: column;
min-width: 0;
max-width: 72px;
}
.level-slide-horz {
display: none;
}
.level-slide-vert {
display: block;
}
.image-container { .image-container {
flex-direction: column; flex-direction: column;
} }
@@ -279,12 +305,12 @@
imageLoaded: false, imageLoaded: false,
imageView: '', imageView: '',
imageLoadMode: "environment", imageLoadMode: "environment",
detectPanel: false,
showDetectSettings: false,
detectorName: '', detectorName: '',
detectorLevel: 50, detectorLevel: 50,
detectorLabels: [], detectorLabels: [],
serverSettings: {}, serverSettings: {},
debugOn: false,
debugText: ['Variables loaded'],
isCordova: !!window.cordova, isCordova: !!window.cordova,
uploadUid: null, uploadUid: null,
uploadDirty: false uploadDirty: false
@@ -317,10 +343,8 @@
xhr.open("GET", modelURL) xhr.open("GET", modelURL)
xhr.setRequestHeader('Content-Type', 'application/json') xhr.setRequestHeader('Content-Type', 'application/json')
xhr.onload = function () { xhr.onload = function () {
if (self.debugOn) self.debugText.push(xhr.response) //DEBUG ANDROID BUILD
if (this.status !== 200) { if (this.status !== 200) {
//this.response.text().then(function(message){alert(message)}) //this.response.text().then(function(message){alert(message)})
self.debugText.push(xhr.response)
console.log(xhr.response) console.log(xhr.response)
return; return;
} }
@@ -338,9 +362,6 @@
console.log('destroy the panel!') console.log('destroy the panel!')
}, },
computed: { computed: {
debugDisplay () {
return this.debugText.join('<br/>')
},
showResults () { showResults () {
var filteredResults = this.resultData.detections var filteredResults = this.resultData.detections
if (!filteredResults) return [] if (!filteredResults) return []
@@ -377,10 +398,8 @@
xhr.open("POST", modelURL) xhr.open("POST", modelURL)
xhr.setRequestHeader('Content-Type', 'application/json') xhr.setRequestHeader('Content-Type', 'application/json')
xhr.onload = function () { xhr.onload = function () {
if (self.debugOn) self.debugText.push(xhr.response)
if (this.status !== 200) { if (this.status !== 200) {
//this.response.text().then(function(message){alert(message)}) //this.response.text().then(function(message){alert(message)})
self.debugText.push(xhr.response)
console.log(xhr.response) console.log(xhr.response)
return; return;
} }
@@ -468,7 +487,10 @@
} else { } else {
const searchImage = this.$refs.image_chooser.files[0] const searchImage = this.$refs.image_chooser.files[0]
var reader = new FileReader() var reader = new FileReader()
reader.addEventListener("loadend", () => {this.imageView = reader.result}) reader.addEventListener("loadend", () => {
this.imageView = reader.result
this.setData()
})
reader.readAsDataURL(searchImage) reader.readAsDataURL(searchImage)
} }
resolve() resolve()
@@ -497,6 +519,9 @@
.map( r => { return {"top": r.top, "left": r.left, "bottom": r.bottom, "right": r.right, "label": r.label}}) .map( r => { return {"top": r.top, "left": r.left, "bottom": r.bottom, "right": r.right, "label": r.label}})
this.uploadUid = await this.uploadData(this.imageView.split(',')[1],uploadData,this.uploadUid) this.uploadUid = await this.uploadData(this.imageView.split(',')[1],uploadData,this.uploadUid)
if (this.uploadUid) { this.uploadDirty = false } if (this.uploadUid) { this.uploadDirty = false }
},
onLevelChange(value) {
this.detectorLevel = value
} }
} }
} }

View File

@@ -79,8 +79,7 @@
} }
.region-button { .region-button {
width: auto; max-height: calc(100% - 15px);
height: calc(100% - 15px);
} }
} }