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:
@@ -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) {
|
||||||
|
|||||||
Reference in New Issue
Block a user