【问题标题】:how to calculate time correctly如何正确计算时间
【发布时间】:2021-11-18 07:16:47
【问题描述】:

我在执行此操作时遇到问题: 我有一个视频,我想阅读它并在上面实时画圈。我有三个列表,其中包含圆圈的 x、y 坐标和秒数。

x = ['20' , '30' , '40', '50','60' , '70' , '80', '90','100' , '110' ]
y = ['20' , '30' , '40', '50','60' , '70' , '80', '90','100' , '110' ]
times = [1,2,3,4,5,6,7,8,9,10]#Seconds

我想在视频上绘制每个坐标与每一秒关联的视频,所以

One second, Draw a circle with 20(x) and 20(y)
Two second, Draw a circle with 30(x) and 30(y)
Three second, Draw a circle with 40(x) and 40(y)...

等等。

我尝试了一些东西,但我真的很糟糕

import cv2 
import numpy as np 
import time

a = ['20' , '30' , '40', '50','60' , '70' , '80', '90','100' , '110' ]
b = ['20' , '30' , '40', '50','60' , '70' , '80', '90','100' , '110' ]
time = [1,2,3,4,5,6,7,8,9,10]#Seconds

#ceate a capture object-------------------------------------------------------------------

cap=cv2.VideoCapture(r'C:/Users/aless/Documents/GitHub/Tobii-Glasses-Thesis/video/scenevideo5.mp4')

i=0

while(cap.isOpened()):
   ret, frame = cap.read()
   time_passed = int(cap.get(cv2.CAP_PROP_POS_MSEC))
   if time_passed % (time[i]*1000) and i<=(len(time)-1):
      print(time_passed)
      # draw circles
     
      cv2.circle(frame, (int(a[i]),int(b[i])), 10, (255, 0, 0), -1)
      cv2.imshow('test', frame)  # draw
      i+=1
   if cv2.waitKey(1) & 0xFF == ord('q'):
      break
cap.release()
cv2.destroyAllWindows()

绘制第一个圆圈后,它不会绘制另一个。有人可以帮忙吗? :C

编辑 1: 我尝试过这种方式,但它给了我错误

错误:(-215:Assertion failed) !_src.empty() in function 'cv::cvtColor'

import cv2 
import numpy as np 
import time

a = ['20' , '30' , '40', '50','60' , '70' , '80', '90','100' , '110' ]
b = ['20' , '30' , '40', '50','60' , '70' , '80', '90','100' , '110' ]
times = [1,2,3,4,5,6,7,8,9,10]#Seconds

#ceate a capture object-------------------------------------------------------------------

cap=cv2.VideoCapture(r'C:/Users/aless/Documents/GitHub/Tobii-Glasses-Thesis/video/scenevideo5.mp4')
count = 0
success = True
fps = int(cap.get(cv2.CAP_PROP_FPS))
i=0

while(cap.isOpened()):
   ret, frame = cap.read()
   time_passed = int(cap.get(cv2.CAP_PROP_POS_MSEC))
   for x,y,t in zip(a,b,times):
      if count%(t*fps) == 0 :
        
         # draw circles
         cv2.circle(frame, (int(x),int(x)), 10, (255, 0, 0), -1)
         cv2.imshow('test', frame)  # draw
      count+=1  
   
cap.release()
cv2.destroyAllWindows()

【问题讨论】:

  • 尝试不使用if cv2.waitKey(1) &amp; 0xFF == ord('q'): break
  • @GhostOps 查看编辑,不工作
  • 总是检查错误。视频捕捉总是一样的。 assert cap.isOpened()(一次!)并在循环中:if not ret: break 就在每个 cap.read 之后
  • 下一期:毫秒不是秒。它们之间的系数为 1000。只需使用int(cap.get(cv2.CAP_PROP_POS_MSEC) / 1000),这对您的代码来说已经足够了。然后将该值用作列表中的索引。 删除 count%(t*fps) == 0,没有意义

标签: python opencv video


【解决方案1】:

主要有两个问题:

  • count += 1 应该在for 循环之外。

  • 条件count % (t*fps) == 0不正确。
    你的意思可能是if (count - (t*fps)) == 0
    如果fps不是整数,我们也可以检查:if abs(count - (t*fps)) &lt;= 0.001
    如果fps 是一个整数,我们可以简单地检查一下:

     if count == (t*fps)
    

调试代码:

使用合成视频文件调试代码更简单,而不是处理一些任意视频文件。

以下代码创建一个合成视频,并运行帧计数器:

vid_filename = 'synthetic_video.mp4'
width, height, fps, n_frames = 320, 240, 25, 300

synthetic_out = cv2.VideoWriter(vid_filename, cv2.VideoWriter_fourcc(*'mp4v'), fps, (width, height))

for i in range(n_frames):
    img = np.full((height, width, 3), 60, np.uint8)
    cv2.putText(img, str(i+1), (width//2-40*len(str(i+1)), height//2+40), cv2.FONT_HERSHEY_DUPLEX, 4, (30, 255, 30), 8)  # Green number
    synthetic_out.write(img)

synthetic_out.release()

为了测试,在cv2.imshow('test', frame)之后添加cv2.waitKey(1000)
等待一整秒让我们看看圆圈是否画在正确的框架上。


下断点,开始调试,并在监视窗口中放置相关变量。

示例(使用PyCharm IDE):

它还有助于逐步执行代码...


完整的代码示例:

import numpy as np
import cv2
import os.path

# Build synthetic video for testing (320x240 at 25fps and 300 frames)
################################################################################
vid_filename = 'synthetic_video.mp4'

if not os.path.isfile(vid_filename):  # Create the file only once (if not exists).
    width, height, fps, n_frames = 320, 240, 25, 300

    synthetic_out = cv2.VideoWriter(vid_filename, cv2.VideoWriter_fourcc(*'mp4v'), fps, (width, height))

    for i in range(n_frames):
        img = np.full((height, width, 3), 60, np.uint8)
        cv2.putText(img, str(i+1), (width//2-40*len(str(i+1)), height//2+40), cv2.FONT_HERSHEY_DUPLEX, 4, (30, 255, 30), 8)  # Green number
        synthetic_out.write(img)

    synthetic_out.release()
################################################################################


a = ['20', '30', '40', '50', '60', '70', '80', '90', '100', '110']
b = ['20', '30', '40', '50', '60', '70', '80', '90', '100', '110']
times = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]  # Seconds

# create a capture object-------------------------------------------------------------------

cap = cv2.VideoCapture(vid_filename)
count = 1  # Start counting from 1 - assume first frame is 1 and not zero (draw a circle on frames 25, 50, 75 and not 26, 51, 76...)
fps = int(cap.get(cv2.CAP_PROP_FPS))
i = 0

while cap.isOpened():
    ret, frame = cap.read()

    if ret is False:
        break  # Break loop in case ret is false (should be false after the last frame)

    for x, y, t in zip(a, b, times):
        if count == (t*fps):
            # draw circles
            cv2.circle(frame, (int(x), int(y)), 10, (255, 0, 0), -1)
            cv2.imshow('test', frame)
            cv2.waitKey(1000)

    count += 1
   
cap.release()
cv2.destroyAllWindows()

输出样本:

【讨论】:

  • 非常感谢,我在使用这样的时间列表时遇到问题。 [0.5, 2.0, 4.6, 6.2, 6.6, 6.8, 7.3, 7.8, 8.2, 9.1, 9.3, 10.2, 10.6, 11.0, 12.2, 16.3, 16.5, 17.0, 17.9, 19.1, 19.6, 19.9, 20.5, 20.9, 21.7, 22.7, 23.9, 26.2, 27.2, 27.5, 28.9, 29.9, 30.2, 31.3, 31.7, 33.3, 34.9, 35.2, 37.5, 37.9, 38.6, 38.9, 39.4, 40.2, 41.5, 41.8]我已经改变了如果你说if abs(count - (t*fps)) &lt;= 0.001没有错误它甚至不打开视频,我认为是如果问题(?)
  • 还有办法让点停留在下一帧吗??
  • “让点停留”的方式是在每一帧上不断绘制圆圈(在同一位置绘制它直到它改变位置)。 abs(count - (t*fps)) &lt;= 0.001 只是一个例子,你可以试试:abs(count - t*fps) &lt;= 1。请使用调试器,尝试自己解决问题。
  • 是否可以在每一帧上绘制也绘制所有先前的点?
  • 是的,只要在 for 循环找到的最后一个 xy 位置继续绘制即可。将 for 循环修改为:for x0, y0, t in zip(a, b, times): if abs(count - t*fps) &lt;= 0.5: x, y = int(x0), int(y0)(保存xy)。并在每个循环中绘制cv2.circle(frame, (x, y), 10, (255, 0, 0), -1)。每个周期也要使用imshowwaitKey。想想如何解决第一帧的情况。
猜你喜欢
  • 2014-12-21
  • 1970-01-01
  • 1970-01-01
  • 2013-11-18
  • 1970-01-01
  • 1970-01-01
  • 2011-02-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多