Python opencv 无法从视频中裁剪帧
Python opencv having trouble cropping frames from a video
描述
我是 Python 和 opencv 的新手,我想使用 opencv 从视频中裁剪帧。工作流程如下:我打开一个图像并从 mousecallback 函数中获取一些坐标值。由于视频是用三脚架上的电池 phone 拍摄的,我希望感兴趣的区域应该固定在 space 中。因此,我可以使用坐标来批量处理其他帧。第一个裁剪图像已按预期完成并保存,但我在处理其他帧时遇到问题。
代码
导入包
import cv2
鼠标回调
def get_retval(event, x, y, flags, param):
global ix, iy
if event == cv2.EVENT_LBUTTONDBLCLK:
ix, iy = x, y
获取坐标
def get_cropped():
while True:
count = 1
while count < 4:
cv2.imshow('get reference', img)
k = cv2.waitKey(20) & 0xFF
if k == 27:
break
elif k == ord('a'):
if count == 1:
# upperleft
x1, y1 = ix, iy
elif count == 2:
# upperright
x2, _ = ix, iy
# bottom
elif count == 3:
_, y2 = ix, iy
count += 1
cropped_img = img[y1:y2, x1:x2]
cv2.imshow("cropped", cropped_img)
k = cv2.waitKey(0) & 0xFF
if k == ord('g'):
cv2.imwrite(data_out + "frame_0.png", cropped_img)
return [x1, y1, x2, y2]
cv2.destroyWindow("cropped")
break
else:
cv2.destroyWindow("cropped")
只要双击左键,就会记录坐标,我按'a'键记录赋值给$x_i$和$y_i$ 表示 i = 1 和 2。然后,它为我提供了裁剪图像的预览。如果图像看起来不错,脚本 returns 坐标。
主要功能
try:
base_dir = 'xxx'
vid_dir = base_dir + 'yyy'
processing_vid = 'zzz'
data_out = '/Data/Work/'
vidcap = cv2.VideoCapture(vid_dir + processing_vid)
frame_count = 0
while vidcap.isOpened() is True:
retval, image = vidcap.read()
totalFrames = int(vidcap.get(cv2.CAP_PROP_FRAME_COUNT))
if retval is True and frame_count == 0:
cv2.imwrite('/tmp/ref.png', image)
img = cv2.imread('/tmp/ref.png')
cv2.namedWindow('get reference')
img = cv2.resize(img, (960, 540))
cv2.setMouseCallback('get reference', get_retval)
x1, x2, y1, y2 = get_cropped()
if retval is True and frame_count != 0:
cv2.namedWindow('test cropping')
image = cv2.resize(image, (960, 540))
cropped = image[y1:y2, x1:x2]
cv2.imshow('test cropping', cropped)
if frame_count == 10:
break
frame_count += 1
except KeyboardInterrupt:
cv2.destroyAllWindows()
我使用第一帧作为参考来获取坐标。这很好用。然后,对于另一帧,我将它们调整为与参考帧相同的大小,并按照我在函数 get_cropped
中所做的相同方式裁剪它们。然而,它只是给我一个错误
来自终端的错误消息
回溯(最近调用最后):
文件“/Data/Dropbox/coding/functions/imageProcessing/June11.py”,第 71 行,位于
cv2.imshow('test cropping', 裁剪)
cv2.error: OpenCV(4.5.2) /builddir/build/BUILD/opencv-4.5.2/modules/highgui/src/window.cpp:412: 错误: (-215:断言失败) size.width>0 && size.height>0 函数 'imshow'
调试
我试着不裁剪地打印出图像,它看起来很正常。然而,一旦我裁剪它,它 returns 一个空数组 [].
谁能帮我找出我做错了什么?抱歉我的长描述!非常感谢!
我无法测试它,但我想我看到了问题 - 你弄乱了坐标。
get_cropped()
returns
return [x1, y1, x2, y2]
但是你把它分配给了
x1, x2, y1, y2 = get_cropped(...)
所以你以错误的顺序分配它们 - 你将 x2
替换为 y1
应该是
x1, y1, x2, y2 = get_cropped(...)
描述
我是 Python 和 opencv 的新手,我想使用 opencv 从视频中裁剪帧。工作流程如下:我打开一个图像并从 mousecallback 函数中获取一些坐标值。由于视频是用三脚架上的电池 phone 拍摄的,我希望感兴趣的区域应该固定在 space 中。因此,我可以使用坐标来批量处理其他帧。第一个裁剪图像已按预期完成并保存,但我在处理其他帧时遇到问题。
代码
导入包
import cv2
鼠标回调
def get_retval(event, x, y, flags, param):
global ix, iy
if event == cv2.EVENT_LBUTTONDBLCLK:
ix, iy = x, y
获取坐标
def get_cropped():
while True:
count = 1
while count < 4:
cv2.imshow('get reference', img)
k = cv2.waitKey(20) & 0xFF
if k == 27:
break
elif k == ord('a'):
if count == 1:
# upperleft
x1, y1 = ix, iy
elif count == 2:
# upperright
x2, _ = ix, iy
# bottom
elif count == 3:
_, y2 = ix, iy
count += 1
cropped_img = img[y1:y2, x1:x2]
cv2.imshow("cropped", cropped_img)
k = cv2.waitKey(0) & 0xFF
if k == ord('g'):
cv2.imwrite(data_out + "frame_0.png", cropped_img)
return [x1, y1, x2, y2]
cv2.destroyWindow("cropped")
break
else:
cv2.destroyWindow("cropped")
只要双击左键,就会记录坐标,我按'a'键记录赋值给$x_i$和$y_i$ 表示 i = 1 和 2。然后,它为我提供了裁剪图像的预览。如果图像看起来不错,脚本 returns 坐标。
主要功能
try:
base_dir = 'xxx'
vid_dir = base_dir + 'yyy'
processing_vid = 'zzz'
data_out = '/Data/Work/'
vidcap = cv2.VideoCapture(vid_dir + processing_vid)
frame_count = 0
while vidcap.isOpened() is True:
retval, image = vidcap.read()
totalFrames = int(vidcap.get(cv2.CAP_PROP_FRAME_COUNT))
if retval is True and frame_count == 0:
cv2.imwrite('/tmp/ref.png', image)
img = cv2.imread('/tmp/ref.png')
cv2.namedWindow('get reference')
img = cv2.resize(img, (960, 540))
cv2.setMouseCallback('get reference', get_retval)
x1, x2, y1, y2 = get_cropped()
if retval is True and frame_count != 0:
cv2.namedWindow('test cropping')
image = cv2.resize(image, (960, 540))
cropped = image[y1:y2, x1:x2]
cv2.imshow('test cropping', cropped)
if frame_count == 10:
break
frame_count += 1
except KeyboardInterrupt:
cv2.destroyAllWindows()
我使用第一帧作为参考来获取坐标。这很好用。然后,对于另一帧,我将它们调整为与参考帧相同的大小,并按照我在函数 get_cropped
中所做的相同方式裁剪它们。然而,它只是给我一个错误
来自终端的错误消息
回溯(最近调用最后): 文件“/Data/Dropbox/coding/functions/imageProcessing/June11.py”,第 71 行,位于 cv2.imshow('test cropping', 裁剪) cv2.error: OpenCV(4.5.2) /builddir/build/BUILD/opencv-4.5.2/modules/highgui/src/window.cpp:412: 错误: (-215:断言失败) size.width>0 && size.height>0 函数 'imshow'
调试
我试着不裁剪地打印出图像,它看起来很正常。然而,一旦我裁剪它,它 returns 一个空数组 [].
谁能帮我找出我做错了什么?抱歉我的长描述!非常感谢!
我无法测试它,但我想我看到了问题 - 你弄乱了坐标。
get_cropped()
returns
return [x1, y1, x2, y2]
但是你把它分配给了
x1, x2, y1, y2 = get_cropped(...)
所以你以错误的顺序分配它们 - 你将 x2
替换为 y1
应该是
x1, y1, x2, y2 = get_cropped(...)