Параллельная обработка кадров в онлайн видео питоне - PullRequest
0 голосов
/ 21 сентября 2019

Я использовал решение , данное Уважаемым "Onlyjus", отвеченным 31 января 18 года в 21: 13 .В последовательном методе - работал хорошо и получил FPS - 18.

Но я получаю размер кадра как (1280,3), когда я использую многопоточность.при печати одного столбца, показывающего в cv2.imshow ().

Пожалуйста, предложите получить обработанный кадр как видимый.

import cv2
import numpy as np
import multiprocessing
import threading
import time


FRAME_QUEUE = multiprocessing.JoinableQueue()
RESULT_QUEUE = multiprocessing.Queue()

# defaults
FONT = cv2.FONT_HERSHEY_SIMPLEX


def process_frame(frame):
    image_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    # apply CLAHE to lightness channel
    clahe = cv2.createCLAHE(clipLimit=3.0, tileGridSize=(4, 4))
    cl1=clahe.apply(image_gray)
    #merge the CLAHE enhanced L channel with the original A and B channel
    frame = cv2.cvtColor(cl1, cv2.COLOR_GRAY2BGR)
    #cv2.imshow('video',frame)
    #cv2.waitKey(1)
    return frame


def parallel_process_frame(cls):
    """the main function that perfroms the image processing"""
    while True:
        next_frame = FRAME_QUEUE.get()
        if next_frame is None:
            # Poison pill means shutdown
            break

        # process the frame
        i, frame = next_frame
        frame = process_frame(frame)

        # draw worker on frame
        frame = cv2.putText(frame, '{}'.format(i),
                        (0, 20), FONT,
                        0.5, (255, 0, 0), 1, cv2.LINE_AA)

        # tell the queue that we are done
        FRAME_QUEUE.task_done()

        # place the results in the result queue
        RESULT_QUEUE.put((i, (frame)))


class ParallelProcessWorker(multiprocessing.Process):
    """multiprocess worker"""
    def __init__(self):
        multiprocessing.Process.__init__(self)

    def run(self):
        parallel_process_frame(self)


class ParallelThreadWorker(threading.Thread):
    """multithread worker"""
    def __init__(self):
        threading.Thread.__init__(self)

    def run(self):
        parallel_process_frame(self)


def serial(frame):
    """serial process the frame"""
    return process_frame(frame)


def multi(frame):
    """multithread/multiprocess process the frame"""
    # split the frame and place in the queue
    for i, chunk in enumerate(np.split(frame, NWORKERS)):
        FRAME_QUEUE.put((i, chunk))

    # wait for the chunks to finish
    FRAME_QUEUE.join()

    # collect the results
    results = []
    for i in range(NWORKERS):
        results.append(RESULT_QUEUE.get())

    # sort, because they can come back in any order
    results.sort(key=lambda x: x[0])

    # combine chunks
    frame = np.vstack((r[1][0] for r in results))


    return frame


if __name__ == "__main__":

    # set flags
    PARALLEL_TYPE = 'thread'
    NWORKERS = 4 

    # setup parallel scheme
    if PARALLEL_TYPE != 'serial':
        method = multi
        if PARALLEL_TYPE == 'thread':
            worker = ParallelThreadWorker
        else:
            worker = ParallelProcessWorker
        # start the workers
        for i in range(NWORKERS):
            w = worker()
            w.start()
    else:
        method = serial

    # variables

    frame_count = 0
    start = time.time()

    # start capture
    cap = cv2.VideoCapture(0)

    # start the loop
    while(True):
        frame_count += 1
        print('frame count {}:'.format(frame_count))
        # Take each frame
        _, frame = cap.read()
        print(frame.shape)

        frame = multi(frame)  
        print('After method {}:'.format(frame.shape))
        FPS = frame_count/(time.time()-start)
        print('FPS :{}'.format(FPS))
        frame = cv2.putText(frame, 'FPS: {0:.1f}'.format(FPS),
                        (10, 20), FONT,
                        0.5, (0, 255, 0), 1, cv2.LINE_AA)

        cv2.imshow('frame', frame)


        k = cv2.waitKey(1) & 0xFF
        if k == 27:
            break
    cap.release()
    cv2.destroyAllWindows()

    # place a bunch of Nones to shutdown the threads/process
    [FRAME_QUEUE.put(None) for i in range(NWORKERS*2)]

    # report
    print('Using a {0} approach with {1} workers resulted in an average FPS of {2:.1f}'.format(PARALLEL_TYPE, NWORKERS, FPS))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...