Объединение функций всех видео с использованием Python - PullRequest
2 голосов
/ 03 июня 2019

Предположим, у меня есть 20 видео. Они одной сцены, размеров и с одной камеры. Давайте предположим, что в одном из этих двадцати видео проходит человек. Все остальные видео в основном одинаковы (за исключением незначительных естественных изменений, таких как ветряные листья и т. Д.).

Я ищу хороший способ объединить все 20 видео в 1 видео. Под слиянием я подразумеваю «оверлей». Все кадры каждого видео накладываются друг на друга, но так, как показывают «различия». Я не могу найти хороший способ. Вот то, что я до сих пор: (Код упрощен).

По сути, я перебираю 20 видео, смешиваю каждое видео со следующим и использую только что созданное смешанное видео со следующим видео и так далее.

Однако из-за того, что я использую cv2.addWeighted, видео с проходящим человеком почти исчезает (после 20 наложений при 50%). Как создать оверлейное видео, в котором сохраняются «существенные различия в пикселях»? Ничего не стоит, я не знаю, какое видео отличается - поэтому я не могу создавать маски. Учитывая, что большинство видео в основном похожи, должен быть какой-то способ сохранить функции кадров, которые значительно отличаются.

videos = ['1.mp4', '2.mp4' , ...., '20.mp4']

for video in videos:
    fourcc = cv2.VideoWriter_fourcc(*'mp4v')
    out = cv2.VideoWriter('new-blended.mp4', fourcc, orig_fps, (width,height)) 
    vid = cv2.VideoCapture(video) # read current video file
    try:
        blend_vid = cv2.VideoCaptire('blended.mp4')
    except: 
        print ('No worries, this is the first video, we will create a blend now')
        blend_vid = None

    while True: # read all frames, blend
        succ, frame = vid.read()
        succ_b = False
        if blend_vid: succ_b, frame_b = blend_vid.read()
        if not succ_b and not succ: 
            break
        if succ_b:
            merged_frame = cv2.addWeighted(frame, 0.5, frame_b, 0.5, 0)
        else:
            merged_frame = frame
        out.write(merged_frame)
    try:
        os.remove('blended.mp4')
    except:
       pass # will fail the first time
    os.rename ('new-blended.mp4', 'blended.mp4')

Добавление дополнительного контекста: В этом конкретном контексте «фон» - это дорога. На переднем плане будут определенные кадры, где люди выходят наружу. Меня больше всего интересует запись «различий» в кадрах и их сохранение. Чтобы дать больше контекста, давайте предположим, что есть 20 видео, каждое по 5 минут. Каждое видео имеет одну и ту же сцену, записанную последовательно более 100 минут. Я хочу создать одно видео продолжительностью 5 минут, которое объединяет (накладывает) 20 видео вместе, сохраняя при этом «ключевые различия». Цель состоит в том, чтобы помочь человеку быстро просмотреть (за 5 минут) 100-минутное видео с дороги, чтобы увидеть, изменилось ли что-нибудь.

1 Ответ

0 голосов
/ 03 июня 2019

Благодаря подсказке @Stephen Meschke я все заработал и понял, что неплохо, если вы все сделаете правильно это не совсем хороший подход к тому, что я хотел сделать.Разница между «фоном» и «передним планом» не очень хорошая.

В любом случае, это мой код.Если кто-нибудь найдет способы улучшить его, пожалуйста, дайте мне знать:

"frame" - это кадр из нового видео.frame_b - это смешанное видео, которое создается на каждой итерации обработки видео.

kernel_clean = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(3,3))
kernel_fill = np.ones((20,20),np.uint8)

# get foreground objects from new frame
frame_mask = fgbg.apply(frame)
# clean noise
frame_mask = cv2.morphologyEx(frame_mask, cv2.MORPH_OPEN, kernel_clean)
# fill up foreground mask better
frame_mask = cv2.morphologyEx(frame_mask, cv2.MORPH_CLOSE, kernel_fill)

# remove grey areas, or set detectShadows=False in the extractor, which I learned later. However, removing shadows sometimes causes gaps in the primary foreground object. I found this to produce better results.
indices = frame_mask > 100
frame_mask[indices] = 255
# get only foreground images from the new frame
foreground_a = cv2.bitwise_and(frame,frame, mask=frame_mask)
# clear out parts on blended frames where forground will be added
frame_mask_inv = cv2.bitwise_not(frame_mask)
modified_frame_b = cv2.bitwise_and(frame_b, frame_b, mask=frame_mask_inv)
merged_frame = cv2.add(modified_frame_b, foreground_a)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...