VideoCapture () для чтения нескольких видео и проблема разрешения кадра - PullRequest
0 голосов
/ 11 сентября 2018

Согласно ответу из этой статьи , в которой говорится о способе объединения одного изображения в 4 стороны.Оттуда я хочу перейти от использования только одного видео к использованию 4 видео в качестве входа.

Это мой код, который использовал одно видео в качестве входа

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 sided video from single video

В этом коде общая высота и ширина кадра основаны только на входе, который является единственным видео, которое я тоже касаюсь этого, так как я использую 4 видео и, конечно, разрешение кадра не одинаково (но все альбомные).Переменные h и w в функции make4side () являются основной частью, которая помогает позиционировать каждый маленький кадр.Так что для этого случая, какое должно быть разрешение большого кадра (переменного вывода)?

Мне нужно прочитать 4 видео и записать их в одно, так как я могу использовать объект VideoCapture, чтобы сделать это для этой цели

Чтобы прояснить мой вопрос, я хочу иметь одно видео, состоящее из 4 входных видео, каждое из которых будет размещено в каждой позиции (сверху, снизу, слева и справа).У меня проблема с большим разрешением кадра, которое я не знаю, что использовать, если у меня 4 видео вместо одного.Другая проблема связана с объектом VideoCapture.Как я могу прочитать кадры всех видео одновременно или каким-либо другим способом сделать это?

Спасибо

Редактировать: top верхняя сторона

left левая сторона

back задняя сторона

right правая сторона

Это не реальные кадры, которые я буду использовать, а просто простая идея, которую я собираюсь использовать для моего видео.Другое дело, что входные файлы могут иметь разное разрешение.Как я могу использовать много объектов видеозахвата, чтобы прочитать каждый из них и поместить его с каждой стороны большого кадра, чтобы написать одно видео

1 Ответ

0 голосов
/ 17 сентября 2018

Таким образом, все зависит от того, что вы хотите сделать, поэтому будет зависеть от того, какой тип изображений вы будете обрабатывать.Прежде всего, вы всегда можете иметь 4 экземпляра класса VideoCapture, и каждый из них загружает новое видео, например:

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.

Теперь самое сложное: ваши изображения не одинакового размера ... вы можете сделать что-то вроде:

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)

Но это создает "плохое" изображение, подобное этому:

enter image description here

Чтобы оно не искажалось, вы должны найти соотношение сторон и попытаться изменить их размер примерно так же.В случае, если соотношение сторон отличается, вам придется дополнить изображения.Это часть, которая зависит от вашей задачи, вы можете обрезать изображение или дополнить его.

Но в основном это то, что должно быть сделано.Я надеюсь, что это поможет вам.


Обновление:

Просто чтобы уточнить часть цикла:

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

В первой строке яприсваивает переменной readCorrect логическое возвращение из read.Затем на следующем изображении я назначил ret и сделал логику and с предыдущим результатом.Таким образом, вы узнаете, все ли они верны, или если ЛЮБОЙ - ложь.

Я также исправил что-то в цикле, в котором произошла ошибка (я поставил, когда не читал, правильно, и это должно быть без нет).

Еще одна вещь перед циклом, вы должны создать объект VideoWriter, вы всегда можете получить размеры каждого видео перед чтением с get с аргументом CV_CAP_PROP_FRAME_WIDTH и CV_CAP_PROP_FRAME_HEIGHT, как videoTop.get(CV_CAP_PROP_FRAME_WIDTH).

А затем внутри цикла, особенно внутри if, после получения изображения вы можете записать его в.

...