在视频中裁剪一帧

Cropping a frame in video

我想要实现的是将我在视频帧中的 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

我在处理图像时不存在此错误,但在处理视频输入时出现此错误。

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

基本上,当视频结束且无法读取任何帧时,您正在切片 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 这里.
  • 如果你想让你的变量在循环之外,你必须定义 它在循环之外。
  • 此外,您应该选择要裁剪的帧。

您还可以添加用于选择框架等的 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',当前帧被裁剪并呈现在新的 window 中。 按'Q':循环存在,裁剪的帧保存为图像。