From 7ac01c78c03c1f1cf5148ab6e6f866ad5238cbbb Mon Sep 17 00:00:00 2001 From: lukas Date: Fri, 17 Jan 2025 02:21:13 +0100 Subject: [PATCH] add a fitness function and change the way fitting rects are found. --- observe_bact.html | 149 ++++++++++++++++++++++++++++------------------ 1 file changed, 90 insertions(+), 59 deletions(-) diff --git a/observe_bact.html b/observe_bact.html index 874eee1..4f8d008 100644 --- a/observe_bact.html +++ b/observe_bact.html @@ -88,13 +88,13 @@ +
+ + + +
+ - - -
- - -
@@ -132,6 +132,13 @@ var objects_lost = []; + // define a fitness function --> it is the distance from one centeroid to the another + function fit(last_rect, rect){ + return (last_rect.x-rect.x)**2 + (last_rect.y-rect.y)**2; + } + + + function do_opencv_magic() { var cap = new cv.VideoCapture(video); @@ -143,19 +150,24 @@ let hierarchy = new cv.Mat(); const FPS = 30; var framecount = 0; + let objects_tracked_handled = new Set(); + let objects_new_handled = new Set(); + let rects_handled = new Set(); + function processVideo() { cap.read(src); framecount+=1; let objects_this = []; - let object_found = false; - let where = ''; + let fits = []; + let rects = []; - for (let k = 0; k < objects_tracked.length; ++k){ - if (objects_tracked[k].at(-1)[0] < framecount-1){ - objects_lost.push(objects_tracked[k]); - objects_tracked.splice(k, 1); - } - } + //for (let k = 0; k < objects_tracked.length; ++k){ + // if (objects_tracked[k].at(-1)[0] < framecount-1){ + // objects_lost.push(objects_tracked[k]); + // objects_tracked.splice(k, 1); + // } + //} + //console.log(objects_last); try { if (!streaming) { @@ -169,68 +181,87 @@ // start processing. cv.cvtColor(src, dst, cv.COLOR_RGBA2GRAY, 0); cv.threshold(dst, dst, 120, 200, cv.THRESH_BINARY); - - // You can try more different parameters // Find contours cv.findContours(dst, contours, hierarchy, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE); // iterate over contours for (let i = 0; i < contours.size(); ++i) { - let rect_found = false; + //get contour let cnt = contours.get(i); // exclude contours with an area < 1000 if (cv.contourArea(cnt) < 1000){ continue; } - // get the bounding rect of the contour let rect = cv.boundingRect(cnt); - // first check if there are objects that currently get tracked that fit the detected contour rect - for (let k = 0; k < objects_tracked.length; ++k){ - let dist = (objects_tracked[k].at(-1)[1].x-rect.x)**2 + (objects_tracked[k].at(-1)[1].y-rect.y)**2; - if (dist < 100000 && objects_tracked[k].at(-1)[0] < framecount) { - objects_tracked[k].push([framecount, rect]); - rect_found = true; - where = k; - break; - } - } - if (rect_found){ - let rectangleColor = new cv.Scalar(255, 0, 255,255); - let point1 = new cv.Point(rect.x, rect.y); - let point2 = new cv.Point(rect.x + rect.width, rect.y + rect.height); - cv.rectangle(src, point1, point2, rectangleColor, 2, cv.LINE_AA, 0); - cv.putText(src, String(where), point1, cv.FONT_HERSHEY_COMPLEX, 1, rectangleColor, 1, cv.LINE_8) - continue; - } - for (let j = 0; j < objects_last.length; ++j){ - let dist = (objects_last[j].x-rect.x)**2 + (objects_last[j].y-rect.y)**2; - if (dist < 1000 ){ - objects_tracked.push([[framecount-1, objects_last[j]], [framecount, rect]]); - //let my_img = new cv.Mat(); - //my_img = src.roi(rect); - //cv.imshow("canvas-debug", my_img); - - rect_found = true; - break; - } - } - if (rect_found){ - let rectangleColor = new cv.Scalar(255, 0, 255,255); - let point1 = new cv.Point(rect.x, rect.y); - let point2 = new cv.Point(rect.x + rect.width, rect.y + rect.height); - cv.rectangle(src, point1, point2, rectangleColor, 2, cv.LINE_AA, 0); - cv.putText(src, String(objects_tracked.length), point1, cv.FONT_HERSHEY_COMPLEX, 1, rectangleColor, 1, cv.LINE_8) - - continue; - } - objects_this.push(rect); + // prepare an array for fitnes values + rects.push(rect); let rectangleColor = new cv.Scalar(255, 0, 255,255); let point1 = new cv.Point(rect.x, rect.y); let point2 = new cv.Point(rect.x + rect.width, rect.y + rect.height); cv.rectangle(src, point1, point2, rectangleColor, 2, cv.LINE_AA, 0); - //cv.drawContours(dst, contours, i, color, 1, cv.LINE_8, hierarchy, 100); + // get all fitness values for this rect. + for (let k = 0; k < objects_tracked.length; ++k){ + if (objects_tracked[k].at(-1)[0] == framecount-1){ + fits.push([k, 'NaN', rects.length-1, fit(objects_tracked[k].at(-1)[1], rect)]); + } + } + for (let j = 0; j < objects_last.length; ++j){ + fits.push(['NaN', j, rects.length-1, fit(objects_last[j], rect)]); + } } + // sort fits array + // Sort the Array + fits.sort(function(a, b){return a[3]-b[3]}); + // iterate over fits to associate objects. + objects_tracked_handled.clear(); + objects_new_handled.clear(); + rects_handled.clear(); + for (i = 0; i < fits.length; ++i) { + + let ind_tracked = fits[i][0]; + let ind_new = fits[i][1]; + let ind_rect = fits[i][2]; + let fit = fits[i][3]; + console.log(fit); + if (fit > 100000) { + break; + } + else if (ind_new == 'NaN' && !(objects_tracked_handled.has(ind_tracked)) && !(rects_handled.has(ind_rect))){ + objects_tracked[ind_tracked].push([framecount, rects[ind_rect]]); + objects_tracked_handled.add(ind_tracked); + rects_handled.add(ind_rect); + let rectangleColor = new cv.Scalar(255, 0, 255,255); + point1 = new cv.Point(rects[ind_rect].x, rects[ind_rect].y); + cv.putText(src, String(ind_tracked+objects_lost.length), point1, cv.FONT_HERSHEY_COMPLEX, 1, rectangleColor, 1, cv.LINE_8); + } + + } + for (i = 0; i < fits.length; ++i) { + + let ind_tracked = fits[i][0]; + let ind_new = fits[i][1]; + let ind_rect = fits[i][2]; + let fit = fits[i][3]; + console.log(fit); + if (fit > 1000) { + break; + } + else if (ind_tracked == 'NaN' && !(objects_new_handled.has(ind_new)) && !(rects_handled.has(ind_rect))){ + objects_tracked.push([[framecount-1, objects_last[ind_new]], [framecount, rects[ind_rect]]]); + objects_new_handled.add(ind_new); + rects_handled.add(ind_rect); + } + } + for (let i = 0; i < rects.length; ++i){ + if (!(rects_handled.has(i))) { + objects_this.push(rects[i]); + } + } + + //cv.drawContours(dst, contours, i, color, 1, cv.LINE_8, hierarchy, 100); + console.log([objects_new_handled.size, objects_tracked_handled.size]); + objects_last = objects_this; let contoursColor = new cv.Scalar(0, 0, 255,255);