add a fitness function and change the way fitting rects are found.

This commit is contained in:
lukas fricke 2025-01-17 02:21:13 +01:00
parent 007b23da89
commit 7ac01c78c0

View file

@ -88,13 +88,13 @@
</table>
</div>
</div>
<div class="row">
<button class="btn btn-primary float-end" onclick="toggleFullscreen();" id="fullscreen-button">toggle Fullscreen video</button>
<button class="btn btn-primary float-end" onclick="toggle_cam();">Toggle camera</button>
<button class="btn btn-primary float-end" onclick="do_opencv_magic();">opencv</button>
</div>
</div>
</div>
<button class="btn btn-primary float-end" onclick="toggleFullscreen();" id="fullscreen-button">toggle Fullscreen video</button>
<div class="row">
<button class="btn btn-primary float-end" onclick="toggle_cam();">Toggle camera</button>
<button class="btn btn-primary float-end" onclick="do_opencv_magic();">opencv</button>
</div>
</div>
<canvas id="canvas-debug"></canvas>
@ -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);