Upgrade image and structure outline to canvas (#64)

Closes: #61

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

Reviewed-on: Georgi_Lab/ALVINN_f7#64
This commit is contained in:
2023-12-28 08:06:06 -07:00
parent 01e8b73677
commit 59f79fcfa8

View File

@@ -6,8 +6,8 @@
</f7-navbar> </f7-navbar>
<f7-block class="detect-grid"> <f7-block class="detect-grid">
<div class="image-container"> <div class="image-container">
<img v-if="imageView" :src="imageView" id="im-display" ref="image_src" style="flex: 1 1 0%; object-fit: contain; max-width: 100%; max-height: 100%; min-width: 0; min-height: 0;" /> <canvas id="im-draw" ref="image_cvs" :style="`display: ${imageLoaded ? 'block' : 'none'}; flex: 1 1 0%; object-fit: contain; max-width: 100%; max-height: 100%; min-width: 0; min-height: 0; background-size: contain; background-position: center; background-repeat: no-repeat`" />
<SvgIcon v-else icon="image" fill-color="var(--avn-theme-color)" @click="selectImage" /> <SvgIcon v-if="!imageView" icon="image" fill-color="var(--avn-theme-color)" @click="selectImage" />
<div ref="structure_box" style="border: solid 3px var(--avn-structure-box-color); position: absolute; display: none; box-sizing: border-box;" /> <div ref="structure_box" style="border: solid 3px var(--avn-structure-box-color); position: absolute; display: none; box-sizing: border-box;" />
</div> </div>
<div v-if="resultData && resultData.detections" class="chip-results" style="grid-area: result-view; flex: 0 0 auto; align-self: center;"> <div v-if="resultData && resultData.detections" class="chip-results" style="grid-area: result-view; flex: 0 0 auto; align-self: center;">
@@ -301,9 +301,8 @@
resultData: {}, resultData: {},
selectedChip: -1, selectedChip: -1,
activeRegion: 4, activeRegion: 4,
imageRegion: '',
imageLoaded: false, imageLoaded: false,
imageView: '', imageView: null,
imageLoadMode: "environment", imageLoadMode: "environment",
detectPanel: false, detectPanel: false,
showDetectSettings: false, showDetectSettings: false,
@@ -358,8 +357,11 @@
xhr.send() xhr.send()
} }
}, },
deactivated () { mounted() {
console.log('destroy the panel!') const imCanvas = this.$refs.image_cvs
const imageCtx = imCanvas.getContext("2d")
imageCtx.strokeStyle = 'yellow'
imageCtx.lineWidth = 3
}, },
computed: { computed: {
showResults () { showResults () {
@@ -391,7 +393,6 @@
}, },
setData () { setData () {
var self = this var self = this
this.resetView()
if (this.serverSettings && this.serverSettings.use) { if (this.serverSettings && this.serverSettings.use) {
var modelURL = `http://${this.serverSettings.address}:${this.serverSettings.port}/detect` var modelURL = `http://${this.serverSettings.address}:${this.serverSettings.port}/detect`
var xhr = new XMLHttpRequest() var xhr = new XMLHttpRequest()
@@ -412,7 +413,7 @@
"detect": { "detect": {
"*": 1 "*": 1
}, },
"data": this.imageView.split(',')[1] "data": this.imageView.src.split(',')[1]
} }
xhr.send(JSON.stringify(doodsData)) xhr.send(JSON.stringify(doodsData))
@@ -445,70 +446,76 @@
alert(`Camera fail: ${message}`) alert(`Camera fail: ${message}`)
}, },
selectChip ( iChip ) { selectChip ( iChip ) {
const [imCanvas, imageCtx] = this.resetView()
if (this.selectedChip == iChip) { if (this.selectedChip == iChip) {
this.resetView() this.selectedChip = -1
return return
} }
var imgWidth var imgWidth
var imgHeight var imgHeight
this.selectedChip = iChip this.selectedChip = iChip
const box = this.$refs.structure_box var imgAspect = this.imageView.width / this.imageView.height
const img = this.$refs.image_src var rendAspect = imCanvas.width / imCanvas.height
var imgAspect = img.naturalWidth / img.naturalHeight
var rendAspect = img.offsetWidth / img.offsetHeight
if (imgAspect >= rendAspect) { if (imgAspect >= rendAspect) {
imgWidth = img.offsetWidth imgWidth = imCanvas.width
imgHeight = img.offsetWidth / imgAspect imgHeight = imCanvas.width / imgAspect
} else { } else {
imgWidth = img.offsetHeight * imgAspect imgWidth = imCanvas.height * imgAspect
imgHeight = img.offsetHeight imgHeight = imCanvas.height
} }
box.style.display = 'block' var boxLeft = (imCanvas.width - imgWidth) / 2 + this.resultData.detections[iChip].left * imgWidth
box.style.left = `${(img.offsetWidth - imgWidth) / 2 + this.resultData.detections[iChip].left * imgWidth}px` var boxTop = (imCanvas.height - imgHeight) / 2 + this.resultData.detections[iChip].top * imgHeight
box.style.top = `${(img.offsetHeight - imgHeight) / 2 + this.resultData.detections[iChip].top * imgHeight}px` var boxWidth = (Math.min(this.resultData.detections[iChip].right, 1) - Math.max(this.resultData.detections[iChip].left, 0)) * imgWidth
box.style.width = `${(Math.min(this.resultData.detections[iChip].right, 1) - Math.max(this.resultData.detections[iChip].left, 0)) * imgWidth}px` var boxHeight = (Math.min(this.resultData.detections[iChip].bottom, 1) - Math.max(this.resultData.detections[iChip].top, 0)) * imgHeight
box.style.height = `${(Math.min(this.resultData.detections[iChip].bottom, 1) - Math.max(this.resultData.detections[iChip].top, 0)) * imgHeight}px` imageCtx.strokeRect(boxLeft,boxTop,boxWidth,boxHeight)
this.resultData.detections[iChip].beenViewed = true this.resultData.detections[iChip].beenViewed = true
}, },
deleteChip ( iChip ) { deleteChip ( iChip ) {
f7.dialog.confirm(`${this.resultData.detections[iChip].label} is identified with ${this.resultData.detections[iChip].confidence.toFixed(1)}% confidence. Are you sure you want to delete it?`, () => { f7.dialog.confirm(`${this.resultData.detections[iChip].label} is identified with ${this.resultData.detections[iChip].confidence.toFixed(1)}% confidence. Are you sure you want to delete it?`, () => {
this.resultData.detections.splice(iChip, 1)
this.resetView() this.resetView()
this.resultData.detections.splice(iChip, 1)
this.selectedChip = -1
this.uploadDirty = true this.uploadDirty = true
}); });
}, },
resetView () {
const imCanvas = this.$refs.image_cvs
const imageCtx = imCanvas.getContext("2d")
imCanvas.width = imCanvas.clientWidth
imCanvas.height = imCanvas.clientHeight
imageCtx.clearRect(0,0,imCanvas.width,imCanvas.height)
return [imCanvas, imageCtx]
},
getImage (searchImage) { getImage (searchImage) {
var self = this
let loadImage =new Promise(resolve => { let loadImage =new Promise(resolve => {
if (this.isCordova && this.imageLoadMode == "camera") { if (this.isCordova && this.imageLoadMode == "camera") {
this.imageView = 'data:image/jpg;base64,' + searchImage resolve('data:image/jpg;base64,' + searchImage)
} 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", () => { reader.addEventListener("loadend", () => {
this.imageView = reader.result resolve(reader.result)
this.setData()
}) })
reader.readAsDataURL(searchImage) reader.readAsDataURL(searchImage)
} }
resolve()
}) })
loadImage.then(() => { loadImage.then((imgData) => {
this.imageLoaded = true this.imageLoaded = true
this.resultData = {} this.resultData = {}
this.resetView() this.imageView = new Image()
this.imageView.src = imgData
return(this.imageView.decode())
}).then( () => {
const [imCanvas, _] = this.resetView()
imCanvas.style['background-image'] = `url(${this.imageView.src})`
this.setData()
}).catch((e) => { }).catch((e) => {
console.log(e.message) console.log(e.message)
f7.dialog.alert(`Error loading image: ${e.message}`) f7.dialog.alert(`Error loading image: ${e.message}`)
}) })
}, },
resetView() {
this.selectedChip = -1
const box = this.$refs.structure_box
box.style.display = 'none'
},
videoStream() { videoStream() {
//TODO //TODO
return null return null
@@ -517,7 +524,7 @@
var uploadData = this.showResults var uploadData = this.showResults
.filter( d => { return d.aboveThreshold && d.isSearched && !d.isDeleted }) .filter( d => { return d.aboveThreshold && d.isSearched && !d.isDeleted })
.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.src.split(',')[1],uploadData,this.uploadUid)
if (this.uploadUid) { this.uploadDirty = false } if (this.uploadUid) { this.uploadDirty = false }
}, },
onLevelChange(value) { onLevelChange(value) {