OpenCV 视频只显示单帧而不是连续帧

Posted

技术标签:

【中文标题】OpenCV 视频只显示单帧而不是连续帧【英文标题】:OpenCV video only show a single frame instead of continuous frame 【发布时间】:2021-12-03 10:29:51 【问题描述】:

当我尝试导出以下视频时,它只显示一帧 12 秒,我想显示原始视频但它只显示一帧

下面附上代码:

ret, frame = day_video.read()
height, width = frame.shape[:2]

fourcc = cv2.VideoWriter_fourcc(*'MJPG')
out = cv2.VideoWriter('output_day.avi', fourcc, 20, (width,height))

while day_video.isOpened():
  ret, frame = day_video.read()
  if not ret:
    out.release()
    break

  new_output = cv2.cvtColor(result, cv2.COLOR_GRAY2BGR)
  out.write(new_output)

out.release()```

我得到的输出只有 12 秒的同一帧。 [![示例输出][1]][1]

我用来增强原始艺术品的代码

cap = cv2.VideoCapture('/content/drive/Shareddrives/Computer Vision/Assignment 2/Q1_day_video.avi')
while(cap.isOpened()):
    ret, frame = cap.read()
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    sobelx = cv2.Sobel(gray, cv2.CV_8U, 1, 0)
    sobely = cv2.Sobel(gray, cv2.CV_8U, 0, 1)
    sobel_all = cv2.add(sobelx, sobely)

    (ret_otsu,thresh_otsu) = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
    print(ret_otsu)
    
    # add the threshold effect with sobel filter
    result = cv2.add(sobel_all, thresh_otsu)
    cv2_imshow(result)
    break
        
cap.release()
cv2.destroyAllWindows()

我做了以下更改,但它只是保持无限加载

cap = cv2.VideoCapture('/content/drive/Shareddrives/Computer Vision/Assignment 2/Q1_day_video.avi')
ret, frame = cap.read()
height, width, _ = frame.shape
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
fourcc = cv2.VideoWriter_fourcc(*'MJPG')
out = cv2.VideoWriter('output_day.avi', fourcc, 20, (width,height))   

while(cap.isOpened()):
  ret, frame = cap.read()
  sobelx = cv2.Sobel(gray, cv2.CV_8U, 1, 0)
  sobely = cv2.Sobel(gray, cv2.CV_8U, 0, 1)
  sobel_all = cv2.add(sobelx, sobely)
  (ret_otsu,thresh_otsu) = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
# add the threshold effect with sobel filter 
  result = cv2.add(sobel_all, thresh_otsu)
  new_output = cv2.cvtColor(result, cv2.COLOR_GRAY2BGR)
  new2_output = new2_output + new_output

if not ret:
  out.release()
  break

out.write(new3_output)
        
cap.release()```

  [1]: https://i.stack.imgur.com/N0wCx.png

【问题讨论】:

您在第一个视频帧后打破循环...将cv2_imshow(result) 之后的break 替换为if not ret: breakcv2_imshow的实现在哪里?它应该类似于 cv2.imshow('result', result) cv2.waitKey(1) while(cap.isOpened()): ret, frame = cap.read() sobelx = cv2.Sobel(gray, cv2.CV_8U, 1, 0) sobely = cv2.Sobel(gray, cv2.CV_8U, 0, 1) sobel_all = cv2.add(sobelx, sobely) (ret_otsu,thresh_otsu) = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU) result = cv2.add(sobel_all, thresh_otsu) new_output = cv2.cvtColor(result, cv2.COLOR_GRAY2BGR) new2_output = new2_output + new_output if not ret: out.release() break out.write(new3_output) cap.release() 一直在无限加载,是不是我在特定部分出错了? @Rotem,cv_imshow 是 colabs 的替代品(不能在那里使用 opencv 的 gui) 【参考方案1】:

您的最新代码块是无限加载的,因为您的 break 语句缩进不正确 - 它需要在 while 循环内。此外,您仅将 sobel 过滤器应用于第一帧,并始终将该帧写入最终视频。您需要按照您希望它们执行的顺序放置逻辑语句。

您的代码:

cap = cv2.VideoCapture('/content/drive/Shareddrives/Computer Vision/Assignment 2/Q1_day_video.avi')
ret, frame = cap.read()
height, width, _ = frame.shape
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
fourcc = cv2.VideoWriter_fourcc(*'MJPG')
out = cv2.VideoWriter('output_day.avi', fourcc, 20, (width,height))   

while(cap.isOpened()):
  ret, frame = cap.read()
  sobelx = cv2.Sobel(gray, cv2.CV_8U, 1, 0)
  sobely = cv2.Sobel(gray, cv2.CV_8U, 0, 1)
  sobel_all = cv2.add(sobelx, sobely)
  (ret_otsu,thresh_otsu) = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
# add the threshold effect with sobel filter 
  result = cv2.add(sobel_all, thresh_otsu)
  new_output = cv2.cvtColor(result, cv2.COLOR_GRAY2BGR)
  new2_output = new2_output + new_output

if not ret:
  out.release()
  break

out.write(new3_output)
        
cap.release()

正确代码:

cap = cv2.VideoCapture('/content/drive/Shareddrives/Computer Vision/Assignment 2/Q1_day_video.avi')
fourcc = cv2.VideoWriter_fourcc(*'MJPG')
out = cv2.VideoWriter('output_day.avi', fourcc, 20, (width,height))   

while(cap.isOpened()):
  ret, frame = cap.read()
  if not ret:
    out.release()
    break
  height, width, _ = frame.shape
  gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
  sobelx = cv2.Sobel(gray, cv2.CV_8U, 1, 0)
  sobely = cv2.Sobel(gray, cv2.CV_8U, 0, 1)
  sobel_all = cv2.add(sobelx, sobely)
  (ret_otsu,thresh_otsu) = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
  # add the threshold effect with sobel filter 
  result = cv2.add(sobel_all, thresh_otsu)
  new_output = cv2.cvtColor(result, cv2.COLOR_GRAY2BGR)
  new2_output = new2_output + new_output
  out.write(new2_output)
        
cap.release()

【讨论】:

以上是关于OpenCV 视频只显示单帧而不是连续帧的主要内容,如果未能解决你的问题,请参考以下文章

opencv 将所有视频一起显示

opencv 提取avi视频中的帧,逐帧播放

如何使用opencv和eclipse从视频剪辑中获取单帧

AE怎么提取其中的一帧画面作为一张图片

重复调用以触发内存中的数据帧而减速

Android:是不是可以显示视频缩略图?