3 Commits

Author SHA1 Message Date
47ec235cfa Clean up new worker configuration
All checks were successful
Build Dev PWA / Build-PWA (push) Successful in 39s
Signed-off-by: Justin Georgi <justin.georgi@gmail.com>
2024-09-11 11:46:37 -07:00
dcdde0289b Set worker use as configuration setting
Signed-off-by: Justin Georgi <justin.georgi@gmail.com>
2024-09-11 10:55:26 -07:00
390faf0a29 Replace url parse with new url for safari
All checks were successful
Build Dev PWA / Build-PWA (push) Successful in 38s
Signed-off-by: Justin Georgi <justin.georgi@gmail.com>
2024-09-10 17:41:20 -07:00
8 changed files with 72 additions and 48 deletions

5
.gitignore vendored
View File

@@ -40,7 +40,8 @@ cordova/platforms/
cordova/plugins/ cordova/plugins/
cordova/www/ cordova/www/
# Production build # Production build
www/ www/
# VSCode settings
.vscode/settings.json

View File

@@ -47,9 +47,10 @@ The following site settings are avaible:
| name | description | values | default | | name | description | values | default |
| --- | --- | --- | --- | | --- | --- | --- | --- |
| `agreeExpire` | number of months before users are shown the site agreement dialog again<br />set to 0 to display dialog on every reload | integer >= 0 | 3 | | `agreeExpire` | number of months before users are shown the site agreement dialog again<br />set to 0 to display dialog on every reload | integer >= 0 | 3 |
| `demo` | set to **true** to enable demo mode by default | boolean | false | `demo` | set to **true** to enable demo mode by default | boolean | false |
| `regions` | array of regions names to enable | thorax, abdomen, limbs, head | [thorax, abdomen, limbs, head] | | `regions` | array of regions names to enable | thorax, abdomen, limbs, head | [thorax, abdomen, limbs, head] |
| `useExternal` | detemines the ability to use an external detection server:<br />**none** - external server cannot be configured<br />**optional** - external server can be configured in the app's settings page<br />**list** - external server can be selected in the app's settings page but only the configured server(s) may be selected<br />**required** - external server settings from conf file will be used by default and disable server options in the settings page | none, optional, list, required | **optional** | | `useExternal` | detemines the ability to use an external detection server:<br />**none** - external server cannot be configured<br />**optional** - external server can be configured in the app's settings page<br />**list** - external server can be selected in the app's settings page but only the configured server(s) may be selected<br />**required** - external server settings from conf file will be used by default and disable server options in the settings page | none, optional, list, required | **optional** |
| `disableWorkers` | force app to use a single thread for detection computations instead of multi threading web workers | boolean | **optional** |
| `external` | properties of the external server(s) ALVINN may connect to<br />This setting must be a single element array if **useExternal** is set to **required**.<br />This setting must be an array of one or more elements if **useExternal** is set to **list** | external server settings array | []| | `external` | properties of the external server(s) ALVINN may connect to<br />This setting must be a single element array if **useExternal** is set to **required**.<br />This setting must be an array of one or more elements if **useExternal** is set to **list** | external server settings array | []|
| `infoUrl` | root url for links to information about identified structures<br />Structure labels with spaces replaced by underscores will be appended to this value for full information links (*e.g.,* Abdominal_diapragm) | string | info link not shown | | `infoUrl` | root url for links to information about identified structures<br />Structure labels with spaces replaced by underscores will be appended to this value for full information links (*e.g.,* Abdominal_diapragm) | string | info link not shown |

View File

@@ -6,6 +6,7 @@ regions:
- limbs - limbs
- head - head
useExternal: none useExternal: none
disableWorkers: false
external: external:
- name: Mserver - name: Mserver
address: "192.169.1.105" address: "192.169.1.105"

View File

@@ -99,6 +99,9 @@
store().set('siteDemo',this.siteConf?.demo) store().set('siteDemo',this.siteConf?.demo)
store().set('infoUrl',this.siteConf?.infoUrl) store().set('infoUrl',this.siteConf?.infoUrl)
const loadServerSettings = localStorage.getItem('serverSettings') const loadServerSettings = localStorage.getItem('serverSettings')
if (this.siteConf.disableWorkers) {
store().disableWorkers()
}
if (this.siteConf?.useExternal) { if (this.siteConf?.useExternal) {
if (!['none','list','optional','required'].includes(this.siteConf.useExternal)) { if (!['none','list','optional','required'].includes(this.siteConf.useExternal)) {
console.warn(`'${this.siteConf.useExternal}' is not a valid value for useExternal configuration: using 'optional'`) console.warn(`'${this.siteConf.useExternal}' is not a valid value for useExternal configuration: using 'optional'`)

View File

@@ -7,6 +7,7 @@ const state = reactive({
version: '0.5.0-alpha', version: '0.5.0-alpha',
fullscreen: false, fullscreen: false,
useExternal: 'optional', useExternal: 'optional',
workersEnabled: 'true',
siteDemo: false, siteDemo: false,
externalServerList: [], externalServerList: [],
infoUrl: false, infoUrl: false,
@@ -26,6 +27,10 @@ const safariDetected = () => {
state.safariBrowser = true state.safariBrowser = true
} }
const disableWorkers = () => {
state.workersEnabled = false
}
const getServerList = () => { const getServerList = () => {
if (state.useExternal == 'required') { if (state.useExternal == 'required') {
return state.externalServerList[0] return state.externalServerList[0]
@@ -51,6 +56,7 @@ export default () => ({
isFullscreen: computed(() => state.fullscreen), isFullscreen: computed(() => state.fullscreen),
demoMode: computed(() => state.siteDemo), demoMode: computed(() => state.siteDemo),
externalType: computed(() => state.useExternal), externalType: computed(() => state.useExternal),
useWorkers: computed(() => state.workersEnabled),
getRegions: computed(() => state.enabledRegions), getRegions: computed(() => state.enabledRegions),
getVersion: computed(() => state.version), getVersion: computed(() => state.version),
getIconSet: computed(() => state.regionIconSet), getIconSet: computed(() => state.regionIconSet),
@@ -59,6 +65,7 @@ export default () => ({
set, set,
agree, agree,
safariDetected, safariDetected,
disableWorkers,
getServerList, getServerList,
toggleFullscreen toggleFullscreen
}) })

View File

@@ -205,9 +205,12 @@
this.activeRegion = 3 this.activeRegion = 3
break; break;
} }
this.modelLocation = URL.parse(`../models/${this.detectorName}${this.otherSettings.mini ? '-mini' : ''}/model.json`,import.meta.url).href let modelJ = `../models/${this.detectorName}${this.otherSettings.mini ? '-mini' : ''}/model.json`
this.miniLocation = URL.parse(`../models/${this.detectorName}-mini/model.json`,import.meta.url).href let miniJ = `../models/${this.detectorName}-mini/model.json`
fetch(URL.parse(`../models/${this.detectorName}/classes.json`,import.meta.url).href) this.modelLocation = new URL(modelJ,import.meta.url).href
this.miniLocation = new URL(miniJ,import.meta.url).href
let classesJ = `../models/${this.detectorName}/classes.json`
fetch(new URL(classesJ,import.meta.url).href)
.then((mod) => { return mod.json() }) .then((mod) => { return mod.json() })
.then((classes) => { .then((classes) => {
this.classesList = classes this.classesList = classes
@@ -217,6 +220,20 @@
if (loadServerSettings) this.serverSettings = JSON.parse(loadServerSettings) if (loadServerSettings) this.serverSettings = JSON.parse(loadServerSettings)
}, },
mounted () { mounted () {
if (this.serverSettings && this.serverSettings.use) {
this.getRemoteLabels()
this.modelLoading = false
} else {
this.modelLoading = true
if (!this.useWorkers) {
this.loadModel(this.modelLocation, true).then(() => {
this.modelLoading = false
}).catch((e) => {
console.log(e.message)
f7.dialog.alert(`ALVINN AI model error: ${e.message}`)
this.modelLoading = false
})
} else {
this.detectWorker = new detectionWorker() this.detectWorker = new detectionWorker()
this.detectWorker.onmessage = (eMount) => { this.detectWorker.onmessage = (eMount) => {
self = this self = this
@@ -234,21 +251,6 @@
f7.dialog.alert(`ALVINN AI nano model error: ${eMount.data.message}`) f7.dialog.alert(`ALVINN AI nano model error: ${eMount.data.message}`)
} }
} }
if (this.serverSettings && this.serverSettings.use) {
this.getRemoteLabels()
this.modelLoading = false
} else {
this.modelLoading = true
if (this.isSafari) {
this.loadModel(this.modelLocation, true).then(() => {
this.modelLoading = false
}).catch((e) => {
console.log(e.message)
f7.dialog.alert(`ALVINN AI model error: ${e.message}`)
this.modelLoading = false
})
} else {
this.detectWorker.postMessage({call: 'loadModel', weights: this.modelLocation, preload: true}) this.detectWorker.postMessage({call: 'loadModel', weights: this.modelLocation, preload: true})
this.vidWorker.postMessage({call: 'loadModel', weights: this.miniLocation, preload: true}) this.vidWorker.postMessage({call: 'loadModel', weights: this.miniLocation, preload: true})
} }
@@ -313,6 +315,7 @@
return `--chip-media-gradient: conic-gradient(from ${270 - (confFactor * 360 / 2)}deg, hsl(${confFactor * 120}deg, 100%, 50%) ${confFactor}turn, hsl(${confFactor * 120}deg, 50%, 66%) ${confFactor}turn)` return `--chip-media-gradient: conic-gradient(from ${270 - (confFactor * 360 / 2)}deg, hsl(${confFactor * 120}deg, 100%, 50%) ${confFactor}turn, hsl(${confFactor * 120}deg, 50%, 66%) ${confFactor}turn)`
}, },
async setData () { async setData () {
if (this.detectWorker) {
this.detectWorker.onmessage = (eDetect) => { this.detectWorker.onmessage = (eDetect) => {
self = this self = this
if (eDetect.data.error) { if (eDetect.data.error) {
@@ -332,11 +335,12 @@
loadSuccess() loadSuccess()
} }
} }
}
let loadSuccess = null let loadSuccess = null
let loadFailure = null let loadFailure = null
let modelReloading = null let modelReloading = null
if (this.isSafari && this.reloadModel) { if (!this.useWorkers && this.reloadModel) {
await this.loadModel(this.modelLocation) await this.loadModel(this.modelLocation)
this.reloadModel = false this.reloadModel = false
} else { } else {
@@ -353,12 +357,14 @@
if (this.serverSettings && this.serverSettings.use) { if (this.serverSettings && this.serverSettings.use) {
this.remoteDetect() this.remoteDetect()
} else if (!this.isSafari) { } else if (this.useWorkers) {
Promise.all([modelReloading,createImageBitmap(this.imageView)]).then(res => { Promise.all([modelReloading,createImageBitmap(this.imageView)]).then(res => {
this.detectWorker.postMessage({call: 'localDetect', image: res[1]}, [res[1]]) this.detectWorker.postMessage({call: 'localDetect', image: res[1]}, [res[1]])
}) })
} else { } else {
this.localDetect(this.imageView).then(dets => { createImageBitmap(this.imageView).then(res => {
return this.localDetect(res)
}).then(dets => {
this.detecting = false this.detecting = false
this.resultData = dets this.resultData = dets
this.uploadDirty = true this.uploadDirty = true
@@ -395,7 +401,7 @@
var vidElement = this.$refs.vid_viewer var vidElement = this.$refs.vid_viewer
vidElement.width = trackDetails.width vidElement.width = trackDetails.width
vidElement.height = trackDetails.height vidElement.height = trackDetails.height
if (this.isSafari) { if (!this.useWorkers) {
this.videoFrameDetect(vidElement) this.videoFrameDetect(vidElement)
} else { } else {
this.videoFrameDetectWorker(vidElement) this.videoFrameDetectWorker(vidElement)

View File

@@ -97,7 +97,6 @@
</style> </style>
<script> <script>
import { touchstart } from 'dom7'
import RegionIcon from '../components/region-icon.vue' import RegionIcon from '../components/region-icon.vue'
import store from '../js/store' import store from '../js/store'
import { f7 } from 'framework7-vue' import { f7 } from 'framework7-vue'
@@ -113,6 +112,11 @@ import RegionIcon from '../components/region-icon.vue'
} }
}, },
setup() { setup() {
//URL TESTING CODE
//let testUrl = URL.parse(`../models/thorax/model.json`,import.meta.url).href
//console.log(testUrl)
//let testUrl2 = new URL(`../models/thorax/model.json`,import.meta.url)
//console.log(testUrl2)
return store() return store()
}, },
methods: { methods: {

View File

@@ -8,7 +8,7 @@
<f7-block-title medium>Details</f7-block-title> <f7-block-title medium>Details</f7-block-title>
<f7-list> <f7-list>
<f7-list-item title="Version" :after="alvinnVersion"></f7-list-item> <f7-list-item title="Version" :after="alvinnVersion"></f7-list-item>
<f7-list-item v-if="isSafari" title="Safari" after="Workers disabled"></f7-list-item> <f7-list-item title="Workers" :after="useWorkers ? 'Enabled' : 'Disabled'"></f7-list-item>
</f7-list> </f7-list>
<f7-block-title medium>Models</f7-block-title> <f7-block-title medium>Models</f7-block-title>
<f7-list style="width: 100%;"> <f7-list style="width: 100%;">
@@ -54,6 +54,7 @@
alvinnVersion: store().getVersion, alvinnVersion: store().getVersion,
isCordova: !!window.cordova, isCordova: !!window.cordova,
isSafari: store().isSafari, isSafari: store().isSafari,
useWorkers: store().useWorkers,
otherSettings: {} otherSettings: {}
} }
}, },