如何在流式传输期间每 n 秒获取特定帧?

Posted

技术标签:

【中文标题】如何在流式传输期间每 n 秒获取特定帧?【英文标题】:How to get specific frame every n seconds during streaming? 【发布时间】:2021-12-21 22:11:56 【问题描述】:

我是图像处理领域的新手,事实上,我遇到了一个与分类相关的小代码。在流式传输期间,我只想每 3 秒获得一个特定的帧,然后,我将该帧与分类算法一起使用。这是我当前使用线程进行的编码:(它有总帧数,我不想全部使用)

class ThreadCapture():
    
  def __init__(self, knn):
    self.frame = []
    self.status = False
    self.isStop = False
    self.knn = knn
    self.cap = cv2.VideoCapture(0)
    self.cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
    self.cap.set(cv2.CAP_PROP_FRAME_WIDTH, 480)
    
  def start(self):
    threading.Thread(target=self.current_frame, daemon=True, args=()).start()

  def stop(self):
    self.isStop = True
    
  def get_frame(self):
    return self.status, self.frame
  
  def current_frame(self):
    while(not self.isStop):
      self.status, self.frame = self.cap.read()
      self.crop_frame()
    self.cap.release()

  def run_knn(self):
    img_resize = cv2.resize(self.frame, (224, 224))
    img = cv2.cvtColor(img_resize, cv2.COLOR_BGR2RGB)
    img_pil = Image.fromarray(img)
    return self.knn.classify(img_pil)

def main(arg):
    .....
    stream = ThreadCapture(EagleEyes)
    stream.start()
    time.sleep(1)  
     
    while(True):
      
      status, frame = stream.get_frame()

      if status:
        info, res = stream.run_knn()
        print(info)
        cv2.putText(frame, info, (10,40), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0,0,255), 1, cv2.LINE_AA)
      
        cv2.imshow('abc', frame)

        if cv2.waitKey(1)==ord('q'):
          break

    stream.stop()
    cv2.destroyAllWindows()

我不擅长编码,所以我想知道是否有人可以支持我改进上述编码。 谢谢大家。

【问题讨论】:

main() 中的循环会在 status 为 false 时像疯了一样旋转,而且它永远不会摆脱它。 @ChristophRackwitz 你能给我一个获取帧或设置间隔的想法吗?其实我只要按“q”就可以退出程序了。 【参考方案1】:

最简单的方法可能是按照上面的思路继续,但只在一定间隔内对帧执行任何操作。

例如,如果您想每 10 秒处理一帧,并且您的视频帧速率为 25fps,那么您可以计数直到达到 250 帧,然后在该帧上进行操作。

.....
stream = ThreadCapture(EagleEyes)
stream.start()
time.sleep(1)  

frameCounter = 0
while(True):
    
    status, frame = stream.get_frame()

    //Increment the frame counter
    frameCounter += 1
    
    if frameCounter == 250
      //Do whatever work you want on the frame here
      
      //Reset the counter
      frameCounter = 0

    // Add some condition to break out of the loop,
    // e.g. end of file or status check.

cap.release()
cv2.destroyAllWindows()

【讨论】:

以上是关于如何在流式传输期间每 n 秒获取特定帧?的主要内容,如果未能解决你的问题,请参考以下文章

如何在火花流中刷新加载的数据帧内容?

通过流获取帧并在屏幕上显示

如何使用 opencv VideoCapture 方法获取实时帧?

如何实时流式传输音频文件

如何从 ServiceWorker 流式传输视频?

如何将特定日志文件从多容器 Docker Elastic Beanstalk 流式传输到 CloudWatch?