裁剪视频中的帧

Posted

技术标签:

【中文标题】裁剪视频中的帧【英文标题】:Cropping a frame in video 【发布时间】:2020-10-19 14:51:19 【问题描述】:

我想要实现的是将视频帧中的 roi 裁剪成一个变量,然后进一步将其作为参数发送..

考虑在人脸检测中,x,y,x+w,y+h 是 roi 的坐标,也就是人脸,我的目标是裁剪该人脸并显示出来。

下面的代码只是为了解释我的错误和问题...

import cv2

cap=cv2.VideoCapture("D:\\Downloads\\video2.mp4")
#x,y,w,h, will change according the video i.e. where the face is detected. 
#For the purpose of explaining, i took these values.
x=50
y=100
w=75
h=90
while(cap.isOpened()):
    _,frame=cap.read()
    
    crop_frame=frame[y:y+h,x:x+w] 
    
    cv2.imshow("Frame",frame)
    cv2.imshow("crop_frame",frame)
cv2.destroyAllWindows()
cap.release()

但是在这样做时,我得到了这个错误:

  crop_frame=frame[y:y+h,x:x+w]
TypeError: 'NoneType' object is not subscriptable

当我在处理图像时没有出现这个错误,但是在视频输入时,我得到了这个错误。

此问题的任何解决方案或任何替代解决方案?

【问题讨论】:

很明显,框架不是一个简单的图像。它是一个可能包含一个框架以及一些其他元数据的对象。您需要找出 cap.read() 返回的结构并相应地修改您的代码 我该怎么做? 检查我链接的骗子 我检查了那个链接...它没有回答我的问题。我得到了 cv2.imshow("frame",frame) 的输出。但是crop_frame 给出了这个错误...... 你说得对——我错过了_,frame,但我原来的说法是成立的。 【参考方案1】:

基本上,当视频结束并且无法读取任何帧时,您正在切片NoneNone[y:y+h,x:x+w] 您应该使用retval 检查是否有要处理的帧,请参阅此处的文档:cv::VideoCapture::read。

所以,试试这个代码作为实验:

import cv2

cap=cv2.VideoCapture("video.mp4")
while(cap.isOpened()):
    ret, frame=cap.read()
    if ret:
      cv2.imshow("Frame", frame)
    else:
      print('None frame:', frame)
      break

cv2.destroyAllWindows()
cap.release()

没有渲染是因为来不及做,这就是为什么你需要看下一个例子。


以一个简单的脚本为例。这些是要点: 首先,您的循环缺少允许渲染的 waytKey() 函数,请参阅doc here。 如果你想让你的变量在循环之外,你必须定义 它在循环之外。 此外,您应该选择要裁剪的帧。

您还可以添加用于选择框架等的 HighGui (https://docs.opencv.org/4.1.0/d7/dfc/group__highgui.html) 控件。

import cv2

cap=cv2.VideoCapture("video.mp4")
x=50
y=100
w=75
h=90

crop_frame = None

while(cap.isOpened()):
    ret, frame = cap.read()
    # if ret: to be added
    cv2.imshow("Frame",frame)
    keypressed = cv2.waitKey(10)
    if keypressed == ord('q'):
      break
    if keypressed == ord('f'):
      crop_frame = frame[y:y+h,x:x+w]
      cv2.imshow("crop_frame", crop_frame)
cv2.destroyAllWindows()
cap.release()

cv2.imwrite('crop_frame.jpg', crop_frame)

你跑了,它会显示视频。 按“F”,当前帧被裁剪并显示在新窗口中。 按“Q”:循环存在,裁剪后的帧保存为图像。

【讨论】:

好的,我知道你的答案了。但是我正在做的是,我正在使用这个概念来裁剪 roi,就像在视频中检测到人脸时一样,我想裁剪那张脸......我上面提到的代码只是我使用的一个例子解释我的查询。你上面写的代码只是捕捉那些坐标上的框架。将这些坐标视为您的投资回报率,其位置会根据视频而变化。那我该怎么办? 刚刚回答了您的问题。目前尚不清楚下一个问题是什么。也许您想用更多详细信息更新您的问题。 检查我的编辑:基本上,当视频结束并且无法读取任何帧时,您正在切片None 好的,我明白你的意思。裁剪没有渲染时间。我要做的是我将实现你的第二个示例并编写代码以检测人脸但是当我按 F 时它会裁剪人脸......我认为这可能有效

以上是关于裁剪视频中的帧的主要内容,如果未能解决你的问题,请参考以下文章

将视频裁剪为帧

掩蔽(裁剪)帧中的图像

python中的帧类型

iOS 确定视频中的帧数

从 iPhone 中的视频帧中获取图像

了解视频帧中的 PTS 和 DTS