|
|
|
|
@@ -1,11 +1,8 @@
|
|
|
|
|
<template>
|
|
|
|
|
<f7-page name="detect">
|
|
|
|
|
<f7-page name="detect" id="detect-page">
|
|
|
|
|
<!-- Top Navbar -->
|
|
|
|
|
<f7-navbar :sliding="false" back-link="true" back-link-url="/" back-link-force>
|
|
|
|
|
<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-block class="detect-grid">
|
|
|
|
|
<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>
|
|
|
|
|
</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-button popover-open="#region-popover">
|
|
|
|
|
<RegionIcon :region="activeRegion" />
|
|
|
|
|
@@ -33,7 +40,7 @@
|
|
|
|
|
<f7-button popover-open="#capture-popover">
|
|
|
|
|
<SvgIcon icon="image"/>
|
|
|
|
|
</f7-button>
|
|
|
|
|
<f7-button @click="setData" :class="(imageLoaded) ? '' : 'disabled'">
|
|
|
|
|
<f7-button @click="() => showDetectSettings = !showDetectSettings" :class="(imageLoaded) ? '' : 'disabled'">
|
|
|
|
|
<SvgIcon icon="visibility"/>
|
|
|
|
|
</f7-button>
|
|
|
|
|
<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;"/>
|
|
|
|
|
</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-navbar title="Detection Settings"></f7-navbar>
|
|
|
|
|
<f7-list>
|
|
|
|
|
<f7-list-input v-model:value="detectorLevel" :label="`Confidence % threshold: ${detectorLevel}`" type="range" />
|
|
|
|
|
<f7-list-item accordion-item title="Structures">
|
|
|
|
|
<f7-accordion-content>
|
|
|
|
|
<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-button title="Close List" @click="() => detectPanel = false" :panel-close="`#${detectorName}-settings`"></f7-list-button>
|
|
|
|
|
<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-block v-if="debugOn" v-html="debugDisplay" />
|
|
|
|
|
</f7-page>
|
|
|
|
|
</f7-panel>
|
|
|
|
|
|
|
|
|
|
@@ -102,10 +99,11 @@
|
|
|
|
|
.detect-grid {
|
|
|
|
|
display: grid;
|
|
|
|
|
grid-template-columns: 1fr;
|
|
|
|
|
grid-template-rows: 1fr auto min-content;
|
|
|
|
|
grid-template-rows: 1fr auto auto min-content;
|
|
|
|
|
grid-template-areas:
|
|
|
|
|
"image-view"
|
|
|
|
|
"result-view"
|
|
|
|
|
"detect-settings"
|
|
|
|
|
"menu-view";
|
|
|
|
|
justify-items: center;
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.detect-inputs {
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
margin: 5px;
|
|
|
|
|
width: 100%;
|
|
|
|
|
max-width: 400px;
|
|
|
|
|
min-width: 192px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.level-slide-vert {
|
|
|
|
|
display: none;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.image-menu {
|
|
|
|
|
grid-area: menu-view;
|
|
|
|
|
margin: 5px;
|
|
|
|
|
@@ -192,10 +203,10 @@
|
|
|
|
|
|
|
|
|
|
@media (max-height: 450px) and (orientation: landscape) {
|
|
|
|
|
.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-areas:
|
|
|
|
|
"image-view result-view menu-view";
|
|
|
|
|
"image-view result-view detect-settings menu-view";
|
|
|
|
|
justify-items: stretch;
|
|
|
|
|
align-items: stretch;
|
|
|
|
|
height: calc(100% - var(--f7-navbar-height) - var(--f7-safe-area-top) - var(--f7-safe-area-bottom));
|
|
|
|
|
@@ -211,6 +222,21 @@
|
|
|
|
|
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 {
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
}
|
|
|
|
|
@@ -279,12 +305,12 @@
|
|
|
|
|
imageLoaded: false,
|
|
|
|
|
imageView: '',
|
|
|
|
|
imageLoadMode: "environment",
|
|
|
|
|
detectPanel: false,
|
|
|
|
|
showDetectSettings: false,
|
|
|
|
|
detectorName: '',
|
|
|
|
|
detectorLevel: 50,
|
|
|
|
|
detectorLabels: [],
|
|
|
|
|
serverSettings: {},
|
|
|
|
|
debugOn: false,
|
|
|
|
|
debugText: ['Variables loaded'],
|
|
|
|
|
isCordova: !!window.cordova,
|
|
|
|
|
uploadUid: null,
|
|
|
|
|
uploadDirty: false
|
|
|
|
|
@@ -317,10 +343,8 @@
|
|
|
|
|
xhr.open("GET", modelURL)
|
|
|
|
|
xhr.setRequestHeader('Content-Type', 'application/json')
|
|
|
|
|
xhr.onload = function () {
|
|
|
|
|
if (self.debugOn) self.debugText.push(xhr.response) //DEBUG ANDROID BUILD
|
|
|
|
|
if (this.status !== 200) {
|
|
|
|
|
//this.response.text().then(function(message){alert(message)})
|
|
|
|
|
self.debugText.push(xhr.response)
|
|
|
|
|
console.log(xhr.response)
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
@@ -338,9 +362,6 @@
|
|
|
|
|
console.log('destroy the panel!')
|
|
|
|
|
},
|
|
|
|
|
computed: {
|
|
|
|
|
debugDisplay () {
|
|
|
|
|
return this.debugText.join('<br/>')
|
|
|
|
|
},
|
|
|
|
|
showResults () {
|
|
|
|
|
var filteredResults = this.resultData.detections
|
|
|
|
|
if (!filteredResults) return []
|
|
|
|
|
@@ -377,10 +398,8 @@
|
|
|
|
|
xhr.open("POST", modelURL)
|
|
|
|
|
xhr.setRequestHeader('Content-Type', 'application/json')
|
|
|
|
|
xhr.onload = function () {
|
|
|
|
|
if (self.debugOn) self.debugText.push(xhr.response)
|
|
|
|
|
if (this.status !== 200) {
|
|
|
|
|
//this.response.text().then(function(message){alert(message)})
|
|
|
|
|
self.debugText.push(xhr.response)
|
|
|
|
|
console.log(xhr.response)
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
@@ -468,7 +487,10 @@
|
|
|
|
|
} else {
|
|
|
|
|
const searchImage = this.$refs.image_chooser.files[0]
|
|
|
|
|
var reader = new FileReader()
|
|
|
|
|
reader.addEventListener("loadend", () => {this.imageView = reader.result})
|
|
|
|
|
reader.addEventListener("loadend", () => {
|
|
|
|
|
this.imageView = reader.result
|
|
|
|
|
this.setData()
|
|
|
|
|
})
|
|
|
|
|
reader.readAsDataURL(searchImage)
|
|
|
|
|
}
|
|
|
|
|
resolve()
|
|
|
|
|
@@ -497,6 +519,9 @@
|
|
|
|
|
.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)
|
|
|
|
|
if (this.uploadUid) { this.uploadDirty = false }
|
|
|
|
|
},
|
|
|
|
|
onLevelChange(value) {
|
|
|
|
|
this.detectorLevel = value
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|