VideoCapture()读取多个视频和帧分辨率问题 [英] VideoCapture() to read multiple videos and frame resolution problem

查看:234
本文介绍了VideoCapture()读取多个视频和帧分辨率问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据此

According to the answer from this article which refer to the way to combine single image into a 4 side. From there, I want to change from using only single video to use 4 videos as an input.

这是我的代码,它使用单个视频作为输入

This is my code which used single video as an input

import cv2
import numpy as np


def make4side(image, scale=0.5):

   # image = cv2.imread(image)
   h = int((scale*image.shape[0])) #height
   w = int((scale*image.shape[1])) #width
   image = cv2.resize(image, (w,h ), interpolation = cv2.INTER_AREA) #shrink image to half

   output = np.zeros((w+h+h , w + h + h, 3), dtype="uint8")

   # top 
   output[0:h, h:h+w] = image 
   # left >> rotate 90
   output[h:h+w, 0:h] = np.rot90(image,1) 
   # right >> rotate 270
   output[h:h + w, h + w:h +w +h] = np.rot90(image,3)  
   # bottom >> rotate 180
   output[h+w:h+w+h, h:h+w] = np.rot90(image,2) 

   return output
   #cv2.imwrite('test.jpg', output)

def process(video):
   cap = cv2.VideoCapture(video)
   fourcc = cv2.VideoWriter_fourcc(*'XVID')
   holo = None
   ret = False
   while(not ret):
    ret, frame = cap.read()
    if ret:
        frame = cv2.resize(frame, (640, 480), interpolation = cv2.INTER_AREA)
        holo = make4side(frame)
   out = cv2.VideoWriter('hologram640x480.avi',fourcc, 23.98, (holo.shape[0],holo.shape[1]))
   total_frames = cap.get(cv2.CAP_PROP_FRAME_COUNT)
   count = 0
   print("Processing %d frames"%(total_frames))
   while(True):
       # Capture frame-by-frame
       ret, frame = cap.read()
       if ret:
           frame = cv2.resize(frame, (640, 480), interpolation = cv2.INTER_AREA)
           holo = make4side(frame)
           out.write(holo)
           count += 1
           print("Total:%d of %d"%(count,total_frames))
       if(count>=total_frames-1):
           break

   cap.release()
   out.release()
   return

process('g.mov')

结果是这样的.

在此代码中,整个帧的高度和宽度仅基于输入,这也是我关注的单个视频,因为我使用了4个视频,当然帧分辨率也不相同(但所有分辨率都是横向的) ).函数make4side()中的变量h和w是帮助定位每个小框架的主要部分.那么对于这种情况,大帧(可变输出)分辨率应该是什么?

In this code, the overall frame's height and width are based only on the input which is the single video which I concern on this too since I use 4 videos and of course the frame resolution are not the same (but all are landscape). Variables h and w in the function make4side() are the main part that help positioning each of the small frame. So for this case, what should the big frame (variable output) resolution be?

我必须阅读4个视频并将其写入一个视频,因此,如何使用VideoCapture对象来实现此目的

I have to read 4 videos and write it into one so, how can I use VideoCapture object to do it for this purpose

为使我的问题更清楚,我希望有一个包含4个输入视频的视频,每个输入视频都将放置在每个位置(顶部,底部,左侧和右侧).我对大帧分辨率有问题,如果我有4个视频而不是一个,我不知道该怎么用.另一个问题与VideoCapture对象有关.如何同时或通过其他任何方式读取所有视频的帧?

To make my question clear, I want to have a single video that consist of 4 input videos, each of them are going to be placed at each of the position (top, bottom, left and right). I have a problem with the big frame resolution which I don't know what to use if I have 4 videos instead of one. Another problem is about the VideoCapture object. How can I read frames of all videos at the same time or any other way to do this?

谢谢

顶部

左侧

背面

右侧

这些不是我将要使用的真实帧,而仅仅是一个简单的想法,我将在视频中使用什么帧.另一件事,输入文件的分辨率可能不同.如何使用许多视频捕获对象读取每个对象并将其放置在大框架的每一侧以编写单个视频

These are not the real frames I will be used but just a simple idea what I am going to use for my video. Another thing, input files may not have the same resolution. How can I use many videocapture objects to read each of them and place it on each side of the big frame to write a single video

推荐答案

因此,一切都取决于您要执行的操作,因此它取决于要处理的图像类型.首先,您始终可以拥有4个VideoCapture类的实例,并且每个实例都加载一个新视频,例如:

So everything depends on what you want to do, so it will come on what type of images you will be processing. First of all, you can always have 4 instances of the VideoCapture class, and each of them loads a new video, something like:

videoTop = cv2.VideoCapture(videoTopFileName)
videoLeft = cv2.VideoCapture(videoLeftFileName)
videoRight = cv2.VideoCapture(videoRightFileName)
videoBottom = cv2.VideoCapture(videoBottomFileName)

readCorrect = True
while( readCorrect ):
  readCorrect , topFrame = videoTop.read()
  ret, leftFrame = videoLeft.read()
  readCorrect = readCorrect and ret
  ret, rightFrame = videoRight.read()
  readCorrect  = readCorrect and ret
  ret, bottomFrame = videoBottom.read()
  readCorrect = readCorrect and ret
  if readCorrect :
     holo = make4side(topFrame, leftFrame, rightFrame, bottomFrame )

您可以在此循环中将图像保存在VideoWriter中.

You can in this loop already save your image in the VideoWriter.

现在到了棘手的部分,您的图像大小不相等...您可以执行以下操作:

Now it comes the tricky part, your images are not of equal size... you can do something like:

import cv2
import numpy as np

# load images, in your case frames from videos
top = cv2.imread("D:\\testing\\1.jpg")
left = cv2.imread("D:\\testing\\2.jpg")
bottom = cv2.imread("D:\\testing\\3.jpg")
right = cv2.imread("D:\\testing\\4.jpg")

targetSize = (200,200)

h = targetSize[1] #height
w = targetSize[0] #width

top = cv2.resize(top,  targetSize )
left = cv2.resize(left,  targetSize )
bottom = cv2.resize(bottom,  targetSize )
right = cv2.resize(right,  targetSize )

output = np.zeros((w+h+h , w + h + h, 3), dtype="uint8")

# top
output[0:h, h:h+w] = top
# left >> rotate 90
output[h:h+w, 0:h] = np.rot90(left,1)
# right >> rotate 270
output[h:h + w, h + w:h +w +h] = np.rot90(bottom,3)
# bottom >> rotate 180
output[h+w:h+w+h, h:h+w] = np.rot90(right,2)

cv2.imshow("frame", output )
cv2.waitKey(0)import cv2
import numpy as np

# load images, in your case frames from videos
top = cv2.imread("D:\\testing\\1.jpg")
left = cv2.imread("D:\\testing\\2.jpg")
bottom = cv2.imread("D:\\testing\\3.jpg")
right = cv2.imread("D:\\testing\\4.jpg")

targetSize = (200,200)

h = targetSize[1] #height
w = targetSize[0] #width

top = cv2.resize(top,  targetSize )
left = cv2.resize(left,  targetSize )
bottom = cv2.resize(bottom,  targetSize )
right = cv2.resize(right,  targetSize )

output = np.zeros((w+h+h , w + h + h, 3), dtype="uint8")

# top
output[0:h, h:h+w] = top
# left >> rotate 90
output[h:h+w, 0:h] = np.rot90(left,1)
# right >> rotate 270
output[h:h + w, h + w:h +w +h] = np.rot90(bottom,3)
# bottom >> rotate 180
output[h+w:h+w+h, h:h+w] = np.rot90(right,2)

cv2.imshow("frame", output )
cv2.waitKey(0)

但这会生成一个像这样的坏"图像:

But this generates a "bad" image like this one:

为使其不失真,您应该找到长宽比并尝试将其调整为类似尺寸.如果宽高比不同,则必须填充图像.这是取决于您的任务的部分,您可以裁剪图像或将其填充.

To make it not distorted, you should find the aspect ratio and try to resize them something similar. In case that the aspect ratio is different, then you will have to pad the images. This is the part that depends on your task, you can crop the image or pad it.

但是基本上那是应该做的.希望对您有帮助.

But basically that is what should be done. I hope this helps you.

更新:

仅需澄清循环部分:

  readCorrect , topFrame = videoTop.read()
  ret, leftFrame = videoLeft.read()
  readCorrect = readCorrect and ret

在我分配给readCorrect变量的第一行中,read的布尔值返回.然后在下一个图像中,我分配给ret并对上一个结果进行逻辑and.通过这种方式,您可以知道它们是否全部为真,或者ANY是否为假.

In the first line I assigned to the readCorrect variable the boolean return from read. Then in the next image I assigned to ret and do a logic and with the previous result. This way you know if all of them are true, or if ANY is false.

我还纠正了循环中有错误的某些内容(我在未读取时正确放置了它,并且应该没有错误).

I also corrected something in the loop that had a mistake (I put while not readCorrect and it should be without the not).

在循环之前,您还应该创建VideoWriter对象,在使用

One more thing before the loop you should create the VideoWriter object, you can always get the sizes of each video before reading with the get with the argument CV_CAP_PROP_FRAME_WIDTH and CV_CAP_PROP_FRAME_HEIGHT, like videoTop.get(CV_CAP_PROP_FRAME_WIDTH).

然后在循环中,特别是在获取图像后可以将其写入的if内部.

And then inside the loop, specifically inside the if after getting the image you can write it to.

这篇关于VideoCapture()读取多个视频和帧分辨率问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆