add a fitness function and change the way fitting rects are found.
This commit is contained in:
parent
007b23da89
commit
7ac01c78c0
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in a new issue