add choosers, add some functions to count bacteria and the like
This commit is contained in:
parent
35e0b27364
commit
91a20b5b13
|
|
@ -61,6 +61,24 @@
|
||||||
<canvas id="canvas-temp"></canvas>
|
<canvas id="canvas-temp"></canvas>
|
||||||
|
|
||||||
<div class="container">
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-3">
|
||||||
|
<label class = "form-label" for="camera_chooser">choose the camera setup</label>
|
||||||
|
<select class="form-select" name="camera_chooser" id = "camera_chooser"></select>
|
||||||
|
</div>
|
||||||
|
<div class="col-3">
|
||||||
|
<label class = "form-label" for="protocol_chooser">choose the preparation protocol</label>
|
||||||
|
<select class="form-select" name="protocol_chooser" id = "protocol_chooser"></select>
|
||||||
|
</div>
|
||||||
|
<div class="col-3">
|
||||||
|
<label class = "form-label" for="dilution">change dilution</label>
|
||||||
|
<input class="form-control" name="dilution" id = "dilution"></input>
|
||||||
|
</div>
|
||||||
|
<div class="col-3">
|
||||||
|
<label class = "form-label" for="sample_chooser">choose the sample</label>
|
||||||
|
<select class="form-select" name="sample_chooser" id = "sample_chooser"></select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<!-- the output div is used to display the video, the photo and the canvas where you can draw in (and measure) your organisms. -->
|
<!-- the output div is used to display the video, the photo and the canvas where you can draw in (and measure) your organisms. -->
|
||||||
<div id="output" class="row">
|
<div id="output" class="row">
|
||||||
<div id = "video_container" class="col-9">
|
<div id = "video_container" class="col-9">
|
||||||
|
|
@ -115,21 +133,426 @@
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var db;
|
||||||
|
let openRequest = indexedDB.open("my_db");
|
||||||
|
|
||||||
|
openRequest.onerror = function() {
|
||||||
|
console.error("Error", openRequest.error);
|
||||||
|
};
|
||||||
|
|
||||||
|
openRequest.onsuccess = function() {
|
||||||
|
db = openRequest.result;
|
||||||
|
get_default_camera_setup();
|
||||||
|
get_default_prep_setup();
|
||||||
|
get_all_samples();
|
||||||
|
|
||||||
|
// continue working with database using db object
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
function get_default_camera_setup(){
|
||||||
|
const request = db.transaction('defaults')
|
||||||
|
.objectStore('defaults')
|
||||||
|
.get(0);
|
||||||
|
request.onsuccess = ()=> {
|
||||||
|
default_setup_id = request.result.microscope_setup;
|
||||||
|
get_all_video_prefs();
|
||||||
|
// width of FoV -- will be supplied by FLASK microscope setup.
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
request.onerror = (err)=> {
|
||||||
|
console.error(`Error to get all setups: ${err}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function get_all_video_prefs(){
|
||||||
|
const request = db.transaction('microscope_setup')
|
||||||
|
.objectStore('microscope_setup')
|
||||||
|
.openCursor();
|
||||||
|
request.onsuccess = ()=> {
|
||||||
|
let cursor = event.target.result;
|
||||||
|
if (cursor) {
|
||||||
|
// Access the current record
|
||||||
|
make_camera_chooser(cursor.value, cursor.key);
|
||||||
|
// Move to the next record
|
||||||
|
cursor.continue();
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
startup();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
request.onerror = (err)=> {
|
||||||
|
console.error(`Error to get all setups: ${err}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var camera_chooser = document.querySelector("#camera_chooser");
|
||||||
|
|
||||||
|
function make_camera_chooser(setup, key){
|
||||||
|
let cameraID = document.createElement("option");
|
||||||
|
let text = document.createTextNode(setup.name);
|
||||||
|
cameraID.value = key;
|
||||||
|
microscope_setups[key] = setup
|
||||||
|
|
||||||
|
|
||||||
|
if (key == default_setup_id){
|
||||||
|
cameraID.defaultSelected = true;
|
||||||
|
text.textContent += " (default)"
|
||||||
|
microscope_setup = setup;
|
||||||
|
}
|
||||||
|
cameraID.appendChild(text);
|
||||||
|
camera_chooser.appendChild(cameraID);
|
||||||
|
}
|
||||||
|
|
||||||
|
camera_chooser.addEventListener("change", change_cam);
|
||||||
|
function change_cam(){
|
||||||
|
microscope_setup = microscope_setups[this.value];
|
||||||
|
startup();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
function get_default_prep_setup(){
|
||||||
|
const request = db.transaction('defaults')
|
||||||
|
.objectStore('defaults')
|
||||||
|
.get(1);
|
||||||
|
request.onsuccess = ()=> {
|
||||||
|
default_protocol_id = request.result.prep_setup;
|
||||||
|
get_all_prep_prefs();
|
||||||
|
|
||||||
|
// width of FoV -- will be supplied by FLASK microscope setup.
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
request.onerror = (err)=> {
|
||||||
|
console.error(`Error to get all setups: ${err}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function get_all_prep_prefs(){
|
||||||
|
const request = db.transaction('prep_protocol')
|
||||||
|
.objectStore('prep_protocol')
|
||||||
|
.openCursor();
|
||||||
|
request.onsuccess = ()=> {
|
||||||
|
let cursor = event.target.result;
|
||||||
|
if (cursor) {
|
||||||
|
// Access the current record
|
||||||
|
make_protocol_chooser(cursor.value, cursor.key);
|
||||||
|
// Move to the next record
|
||||||
|
cursor.continue();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
request.onerror = (err)=> {
|
||||||
|
console.error(`Error to get all setups: ${err}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var protocol_chooser = document.querySelector("#protocol_chooser");
|
||||||
|
|
||||||
|
function make_protocol_chooser(protocol, key){
|
||||||
|
let protocolID = document.createElement("option");
|
||||||
|
let text = document.createTextNode(protocol.name);
|
||||||
|
protocolID.value = key;
|
||||||
|
prep_protocols[key] = protocol;
|
||||||
|
if (key == default_protocol_id){
|
||||||
|
protocolID.defaultSelected = true;
|
||||||
|
prep_protocol = protocol;
|
||||||
|
text.textContent += " (default)";
|
||||||
|
dilution_chooser.value = protocol.Main_Dilution;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
protocolID.appendChild(text);
|
||||||
|
protocol_chooser.appendChild(protocolID);
|
||||||
|
}
|
||||||
|
|
||||||
|
protocol_chooser.addEventListener("change", change_protocol);
|
||||||
|
function change_protocol(){
|
||||||
|
prep_protocol = prep_protocols[this.value];
|
||||||
|
dilution_chooser.value = prep_protocol.Main_Dilution;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
function get_all_samples(){
|
||||||
|
const request = db.transaction('sample')
|
||||||
|
.objectStore('sample')
|
||||||
|
.openCursor();
|
||||||
|
request.onsuccess = ()=> {
|
||||||
|
let cursor = event.target.result;
|
||||||
|
if (cursor) {
|
||||||
|
// Access the current record
|
||||||
|
make_sample_chooser(cursor.value, cursor.key);
|
||||||
|
sample = cursor.key;
|
||||||
|
// Move to the next record
|
||||||
|
cursor.continue();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
request.onerror = (err)=> {
|
||||||
|
console.error(`Error to get all setups: ${err}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var sample_chooser = document.querySelector("#sample_chooser");
|
||||||
|
|
||||||
|
function make_sample_chooser(sample, key){
|
||||||
|
let sampleID = document.createElement("option");
|
||||||
|
let text = document.createTextNode(sample.Name);
|
||||||
|
sampleID.value = key;
|
||||||
|
samples[key] = sample;
|
||||||
|
sampleID.appendChild(text);
|
||||||
|
sample_chooser.appendChild(sampleID);
|
||||||
|
}
|
||||||
|
|
||||||
|
sample_chooser.addEventListener("change", change_sample);
|
||||||
|
function change_sample(){
|
||||||
|
sample = samples[this.value];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
var org_table = document.querySelector("#org-table");
|
||||||
|
|
||||||
|
function add_organism_candidate(tracked_obj, index){
|
||||||
|
let newRow = org_table.children[1].insertRow();
|
||||||
|
let number = newRow.insertCell(0);
|
||||||
|
let canvas = newRow.insertCell(1);
|
||||||
|
let area = newRow.insertCell(2);
|
||||||
|
let choose_frame = newRow.insertCell(3);
|
||||||
|
let bacteria_type = newRow.insertCell(4);
|
||||||
|
// number of candidate
|
||||||
|
number.innerHTML = index;
|
||||||
|
// canvas
|
||||||
|
let can_bact = document.createElement('canvas');
|
||||||
|
canvas.appendChild(can_bact);
|
||||||
|
console.log('hithere')
|
||||||
|
console.log(tracked_obj);
|
||||||
|
cv.imshow(can_bact, tracked_obj[2]);
|
||||||
|
can_bact.style.height = '100px';
|
||||||
|
can_bact.id = "bact_candidate_canvas" + index;
|
||||||
|
// display area of contour
|
||||||
|
area_text = document.createTextNode(tracked_obj[3]);
|
||||||
|
area.id = "bact_candidate_area" + index;
|
||||||
|
area.appendChild(area_text);
|
||||||
|
|
||||||
|
// frame chooser
|
||||||
|
let frame_chooser = document.createElement('input');
|
||||||
|
frame_chooser.setAttribute("type", "range");
|
||||||
|
frame_chooser.id = "bact_candidate" + index;
|
||||||
|
frame_chooser.addEventListener("change", change_frame);
|
||||||
|
frame_chooser.min = 0;
|
||||||
|
frame_chooser.value = 0;
|
||||||
|
|
||||||
|
let bact_type = document.createElement('form');
|
||||||
|
bact_type.id = "bact_candidate_type" + index;
|
||||||
|
bacteria_types = [
|
||||||
|
"Bacteria", "Cocci", "Vibrio", "Spirilla", "Spirochetes"
|
||||||
|
]
|
||||||
|
for (let i=0; i < bacteria_types.length; i++){
|
||||||
|
input = document.createElement('input');
|
||||||
|
input.type = 'radio';
|
||||||
|
input.classList.add('btn-check');
|
||||||
|
input.name = 'choice';
|
||||||
|
input.id = 'org-type-'+bacteria_types[i]+''+index;
|
||||||
|
input.value = bacteria_types[i];
|
||||||
|
input.addEventListener("click",change_type);
|
||||||
|
input
|
||||||
|
label = document.createElement('label');
|
||||||
|
switch (bacteria_types[i]){
|
||||||
|
case "Bacteria":
|
||||||
|
case "Cocci":
|
||||||
|
label.classList.add("btn", "btn-outline-success");
|
||||||
|
break;
|
||||||
|
case "Vibrio":
|
||||||
|
case "Spirilla":
|
||||||
|
case "Spirochetes":
|
||||||
|
label.classList.add("btn", "btn-outline-danger");
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
label.htmlFor = 'org-type-'+bacteria_types[i]+''+index;
|
||||||
|
label.textContent = bacteria_types[i];
|
||||||
|
bact_type.appendChild(input);
|
||||||
|
bact_type.appendChild(label);
|
||||||
|
}
|
||||||
|
input = document.createElement('input');
|
||||||
|
input.type = 'radio';
|
||||||
|
input.classList.add('btn-check');
|
||||||
|
input.name = 'choice';
|
||||||
|
input.id = 'org-type-no'+''+index;
|
||||||
|
input.value = 'no';
|
||||||
|
input.checked = 'checked';
|
||||||
|
label = document.createElement('label');
|
||||||
|
label.classList.add("btn", "btn-outline-secondary");
|
||||||
|
label.htmlFor = 'org-type-no'+''+index;
|
||||||
|
label.textContent = 'no bacterium';
|
||||||
|
bact_type.appendChild(input);
|
||||||
|
bact_type.appendChild(label);
|
||||||
|
bacteria_type.appendChild(bact_type);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
choose_frame.appendChild(frame_chooser);
|
||||||
|
for (let i=0; i<objects_tracked.length; i++){
|
||||||
|
let chooser = document.getElementById("bact_candidate"+(i+1))
|
||||||
|
chooser.max = objects_tracked[i].length-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
let bacteria = new Map();
|
||||||
|
|
||||||
|
function change_type(event){
|
||||||
|
console.log(event.target)
|
||||||
|
id = Number(event.target.id.replace(/\D/g, ""));
|
||||||
|
let c = document.getElementById("bact_candidate"+id);
|
||||||
|
let v = c.value;
|
||||||
|
bacteria.set(id, {
|
||||||
|
'type' : event.target.value,
|
||||||
|
'picture' : objects_tracked[id-1][v][2],
|
||||||
|
'area' : objects_tracked[id-1][v][3]
|
||||||
|
});
|
||||||
|
update_bact_count();
|
||||||
|
}
|
||||||
|
|
||||||
|
function change_frame(event){
|
||||||
|
let id = Number(event.target.id.replace(/\D/g, ""));
|
||||||
|
let canvas = document.getElementById("bact_candidate_canvas"+id);
|
||||||
|
let area = document.getElementById("bact_candidate_area"+id);
|
||||||
|
let type = document.getElementById("bact_candidate_type"+id);
|
||||||
|
console.log(type.choice.value);
|
||||||
|
|
||||||
|
area.textContent = objects_tracked[id-1][Number(this.value)][3];
|
||||||
|
cv.imshow(canvas, objects_tracked[id-1][Number(this.value)][2]);
|
||||||
|
bacteria.set(id, {
|
||||||
|
'type' : type.choice.value,
|
||||||
|
'picture' : objects_tracked[id-1][Number(this.value)][2],
|
||||||
|
'area' : objects_tracked[id-1][Number(this.value)][3]
|
||||||
|
});
|
||||||
|
update_bact_count();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
let bacilli_count = document.getElementById("Bacilli_count");
|
||||||
|
let cocci_count = document.getElementById("Cocci_count");
|
||||||
|
let pathogen_count = document.getElementById("Pathogen_count");
|
||||||
|
let total_area = document.getElementById("total_area");
|
||||||
|
|
||||||
|
|
||||||
|
function update_bact_count(){
|
||||||
|
let bc = 0;
|
||||||
|
let cc = 0;
|
||||||
|
let pc = 0;
|
||||||
|
let area = 0;
|
||||||
|
bacteria.forEach((value, key, map) => {
|
||||||
|
switch(value.type){
|
||||||
|
case "Bacteria":
|
||||||
|
bc += 1
|
||||||
|
area += value.area;
|
||||||
|
break;
|
||||||
|
case "Cocci":
|
||||||
|
cc += 1
|
||||||
|
area += value.area;
|
||||||
|
break;
|
||||||
|
case "Vibrio":
|
||||||
|
case "Spirilla":
|
||||||
|
case "Spirochetes":
|
||||||
|
pc += 1
|
||||||
|
area += value.area;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
);
|
||||||
|
bacilli_count.value = bc;
|
||||||
|
cocci_count.value = cc;
|
||||||
|
pathogen_count.value = pc;
|
||||||
|
total_area.value = area;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function submit_FoV(){
|
||||||
|
bact = []
|
||||||
|
bacteria.forEach((value, key, map) => {
|
||||||
|
bact.push([key, value.type, value.area, value.picture])
|
||||||
|
})
|
||||||
|
console.log(bacteria);
|
||||||
|
FoVs.push([bact, [bacilli_count.value, bacilli_count.value*4, cocci_count.value, cocci_count.value*2, pathogen_count.value, pathogen_count.value*2, total_area.value]]);
|
||||||
|
bacteria.clear();
|
||||||
|
objects_tracked = [];
|
||||||
|
while (org_table.children[1].hasChildNodes()) {
|
||||||
|
org_table.children[1].removeChild(org_table.children[1].lastChild);
|
||||||
|
}
|
||||||
|
update_bact_count();
|
||||||
|
update_FoV_table();
|
||||||
|
}
|
||||||
|
var FoV_table = document.getElementById("FoV_table");
|
||||||
|
|
||||||
|
function update_FoV_table(){
|
||||||
|
while (FoV_table.children[1].hasChildNodes()) {
|
||||||
|
FoV_table.children[1].removeChild(FoV_table.children[1].lastChild);
|
||||||
|
}
|
||||||
|
FoVs.forEach(function (value, index){
|
||||||
|
let newRow = FoV_table.children[1].insertRow();
|
||||||
|
let number = newRow.insertCell(0);
|
||||||
|
let bacilli = newRow.insertCell(1);
|
||||||
|
let cocci = newRow.insertCell(2);
|
||||||
|
let pathogens = newRow.insertCell(3);
|
||||||
|
let total_area = newRow.insertCell(4);
|
||||||
|
let button = newRow.insertCell(5);
|
||||||
|
number.innerHTML = index+1;
|
||||||
|
bacilli.innerHTML = value[1][0];
|
||||||
|
cocci.innerHTML = value[1][2];
|
||||||
|
pathogens.innerHTML = value[1][4];
|
||||||
|
total_area.innerHTML = value[1][6];
|
||||||
|
button.innerHTML = "<button class='btn btn-primary float-end' onclick=remove_FoV(" + index + ")>remove</button>";
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
function remove_FoV(index){
|
||||||
|
FoVs.splice(index, 1);
|
||||||
|
update_FoV_table();
|
||||||
|
}
|
||||||
|
|
||||||
|
function submit_result(){
|
||||||
|
let to_send = {
|
||||||
|
"result" : FoVs,
|
||||||
|
"sampleID" : sample_chooser.value,
|
||||||
|
"setupID" : camera_chooser.value,
|
||||||
|
"prepID" : protocol_chooser.value,
|
||||||
|
"dilution" : dilution_chooser.value,
|
||||||
|
"datetime" : new Date,
|
||||||
|
}
|
||||||
|
|
||||||
|
let transaction = db.transaction(["bacterial_scan"], "readwrite");
|
||||||
|
let objectStore = transaction.objectStore("bacterial_scan");
|
||||||
|
let add_request = objectStore.add(to_send); // (3)
|
||||||
|
add_request.onsuccess = (event) => {
|
||||||
|
console.log("All done!");
|
||||||
|
};
|
||||||
|
add_request.onerror = (event) => {
|
||||||
|
console.log("something went wrong");
|
||||||
|
// Don't forget to handle errors!
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
var video = document.querySelector("#video");
|
var video = document.querySelector("#video");
|
||||||
|
|
||||||
var out = document.querySelector("#output");
|
var out = document.querySelector("#output");
|
||||||
// width of FoV -- will be supplied by FLASK microscope setup.
|
|
||||||
var real_width_FoV = 255;
|
|
||||||
// opencv stuff
|
// opencv stuff
|
||||||
var canvas_draw = document.getElementById("canvas-draw");
|
var canvas_draw = document.getElementById("canvas-draw");
|
||||||
|
|
||||||
const context = canvas_draw.getContext('2d');
|
const context = canvas_draw.getContext('2d');
|
||||||
|
|
||||||
var contours;
|
var contours;
|
||||||
var hierarchy;
|
var hierarchy;
|
||||||
var objects_tracked = [];
|
var objects_tracked = [];
|
||||||
var objects_lost = [];
|
|
||||||
|
|
||||||
|
|
||||||
// define a fitness function --> it is the distance from one centeroid to the another
|
// define a fitness function --> it is the distance from one centeroid to the another
|
||||||
function fit(last_rect, rect){
|
function fit(last_rect, rect){
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue