OpenCV слишком медленный для этого

#python #opencv #video #webcam #video-processing

#python #opencv #Видео #Вебкам #обработка видео

Вопрос:

Я хочу наложить видео, снятое с веб-камеры, на другое видео в режиме реального времени. Итак, я попробовал приведенный выше код, но он слишком медленный.

Должен ли я перейти на другой язык или библиотеку или что-то в этом роде?

Любое предложение или помощь будут оценены.

 import numpy as np
from cv2 import cv2


def image_resize(image, width = None, height = None, inter = cv2.INTER_AREA):
     # initialize the dimensions of the image to be resized and
     # grab the image size
     dim = None
     (h, w) = image.shape[:2]

     # if both the width and height are None, then return the
     # original image
     if width is None and height is None:
          return image

     # check to see if the width is None
    if width is None:
         # calculate the ratio of the height and construct the
         # dimensions
         r = height / float(h)
         dim = (int(w * r), height)

         # otherwise, the height is None
    else:
         # calculate the ratio of the width and construct the
         # dimensions
         r = width / float(w)
         dim = (width, int(h * r))

    # resize the image
    resized = cv2.resize(image, dim, interpolation = inter)

    # return the resized image
    return resized



cap2 = cv2.VideoCapture('http://192.168.43.1:8080/video')
cap = cv2.VideoCapture('test.mp4')

# Define the codec and create VideoWriter object 
fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('sample3.mp4',fourcc,30, (640,480))


# watermark = logo

# cv2.imshow("watermark",watermark)

while(cap.isOpened()):
    ret, frame = cap.read()
    frame = cv2.cvtColor(frame,cv2.COLOR_BGR2BGRA)

    ret2 ,frame2 = cap2.read()
    frame2 = cv2.cvtColor(frame2,cv2.COLOR_BGR2BGRA)

    watermark = image_resize(frame2,height=177)

    if ret==True:
        frame_h, frame_w, frame_c = frame.shape
        overlay = np.zeros((frame_h, frame_w, 4), dtype='uint8')
        overlay[543:543 177,1044:1044 236] = watermark
        cv2.addWeighted(frame, 0.25, overlay, 1.0, 0, frame)
       
        frame = cv2.cvtColor(frame,cv2.COLOR_BGRA2BGR)

        out.write(frame) 

        cv2.imshow('frame',frame)
        if cv2.waitKey(1) amp; 0xFF == ord('q'):
            break
    else:
        break

# Release everything if job is finished
cap.release()
out.release()
cv2.destroyAllWindows()
 

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

Спасибо.

Комментарии:

1. Вы определили узкое место в своем конвейере?

2. В результате @eldesgraciado частота кадров очень низкая (1 или 2 кадра в секунду), но без наложения она работает со скоростью 30 кадров в секунду.

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

Ответ №1:

В принципе, если вы хотите, чтобы это было быстро, вы не можете перебирать изображение, используя цикл python. Вы пытаетесь скопировать уменьшенное изображение в пустое наложение, используя 2 вложенных цикла, и это ужасно медленно. Я не понимаю условия

              if watermark[i,j][3] != 0:
 

Также эта часть:

                 offset = 0
                h_offset = frame_h - watermark_h -offset
                w_offset = frame_w - watermark_w - offset
 

должно быть вне цикла — все они являются константами.

Но самое главное, что вместо циклического перемещения по изображению вы можете сделать:

 offset[h_offset:h_offset watermark_h,w_offset:w_offset watermark_w] = watermark
 

После этого я увеличил скорость с 9 до 28 кадров в секунду.