简体   繁体   English

使用注释绘制视频中对象的轨迹! [OpenCV]

[英]Draw trajectories of objects in a video using annotations! [OpenCV]

I have several videos about 5 minutes each along with annotation data containing information about each object's bounding box coordinates at each frame number. 我有一些大约5分钟的视频,以及包含有关每个帧号处每个对象的边界框坐标的信息的注释数据。 I am trying to read the videos and draw lines between center of bounding boxes frame by frame (when the current frame number matches the number from the ground truth data). 我正在尝试阅读视频并在边框的中心之间逐帧绘制线(当当前帧号与地面真实数据中的数字匹配时)。 I don't want to do this in a batch process, but every 30 or 60 frames would work for me. 我不想分批执行此操作,但是每30或60帧对我来说就可以工作。 Here is my code: 这是我的代码:

VideoCapture capture(path_video);
if (!capture.isOpened()){
   cout <<  "Failed to capture frame/Open the file" << "\n";
   return 0;
}
bool stop(false);
while(!stop){
   capture >> frame;
   if (frame.data==NULL) {
      break;
   }
   double rate = capture.get(CV_CAP_PROP_FPS);
   int delay = 1000/rate;
   frmNum = (capture.get(CV_CAP_PROP_POS_FRAMES));
   for (int i=0 ; i<db.size() ; i++){//db is a vector of vector that has annotation data for each object splited in inner vectors , and is sorted ascendingly on start frame number of objects.
      if (!db[i].empty()){
         for (int j=1 ; j<db[i].size() ; j++){
            if(frmNum == db[i][j-1].currFrame){
               cv::line(frame, db[i][j-1].pnt, db[i][j].pnt,Scalar(255,0,0),2);
            }
            else{
               break;
            }
         }
      }
   }
   imshow("Video", frame);
   int key = waitKey(delay);
   if (key==27){
      break;
   }

I checked and my if condition becomes true but no line is drawn on the video. 我检查了一下,如果条件成立,但视频上没有画线。 I guess I don't see the lines because frames are changing and the drawn lines are cleared by new frames, But I couldnt come up with an alternative way. 我想我看不到线条,因为框架在变化,绘制的线条被新的框架清除了,但是我无法提出另一种方法。 Thanks for your help. 谢谢你的帮助。

If you want to draw the annotations on every frame and you don't mind that the information may be "obsolete" in some cases, I would do the following: 如果您想在每个框架上绘制注释,并且您不介意在某些情况下信息可能已“过时”,我将执行以下操作:

  • have a global image variable called "overlay" which would hold the most up to date (in regards to current frame number) representation of annotations and would have the same size as a single frame from the videostream 具有称为“ overlay”的全局图像变量,该变量将保存最新的注释(关于当前帧号)表示,并且其大小与视频流中的单个帧相同
  • maintain an array of indices called "last_object_annotation_idx", which would store for each object the last index of its annotation already seen/used (initially set to -1 for each object) 维护一个称为“ last_object_annotation_idx”的索引数组,该数组将为每个对象存储已经看到/使用过的其注释的最后一个索引(每个对象最初设置为-1)
  • in each iteration of the main loop, update the "last_object_annotation_idx" array (that is, for each object check if the current frame number matches the "currFrame" field of the next annotation - I am using the information that the array of annotations is sorted) 在主循环的每次迭代中,更新“ last_object_annotation_idx”数组(即,对于每个对象,检查当前帧号是否与下一个注释的“ currFrame”字段匹配-我正在使用对注释数组进行排序的信息)
  • if there was a change to the array, redraw the overlay image using annotations referenced from "last_object_annotation_idx" 如果数组发生更改,请使用从“ last_object_annotation_idx”引用的注释重新绘制覆盖图像
  • finally, add the overlay image to the frame and display the result. 最后,将叠加图像添加到框架并显示结果。

Also, in the if statement 另外,在if语句中

if(frmNum == db[i][j-1].currFrame){
    cv::line(frame, db[i][j-1].pnt, db[i][j].pnt,Scalar(255,0,0),2);
}
else{
    break;
}

isn't the "break" kind of wrong? “休息”不是一种错误吗? It means you will break out of the loop if the first check fails, so you will not see anything past the first index in that case. 这意味着如果第一个检查失败,您将跳出循环,因此在这种情况下,您将看不到任何超出第一个索引的内容。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM