0

Hi Stackoverflow Users,

I'm currently trying to perform a multithreaded frame extraction using OpenCV. I've made such multithreaded operations before on other tasks, but for some reason it doesnt seem to work on the frame extraction. This is my Code:

    import cv2
import os
import face_recognition
from PIL import Image
import multiprocessing

try:
    if not os.path.exists('frames'):
        os.makedirs('frames')
except OSError:
    print('Error: Creating directory of frames')

try:
    if not os.path.exists('faces'):
        os.makedirs('faces')
except OSError:
    print('Error: Creating directory of faces')

def frame_extract_1():
    currentFrame_extract = 1
    video_capture = cv2.VideoCapture("DOLFACE_1.mp4")

    while(True):
        ret1, frame = video_capture.read()
        if ret1 == False:
            break
        name = 'frames/frame_' + str(currentFrame_extract) + '.jpg'
        print(f"Processor 1 extracted Frame {currentFrame_extract}, saving it as Frame_{currentFrame_extract}.jpg")
        cv2.imwrite(name, frame)
        currentFrame_extract += 4

    video_capture.release()
    cv2.destroyAllWindows()

def frame_extract_2():
    currentFrame_extract = 2
    video_capture = cv2.VideoCapture("DOLFACE_1.mp4")

    while(True):
        ret2, frame = video_capture.read()
        if ret2 == False:
            break
        name = 'frames/frame_' + str(currentFrame_extract) + '.jpg'
        print(f"Processor 2 extracted Frame {currentFrame_extract}, saving it as Frame_{currentFrame_extract}.jpg")
        cv2.imwrite(name, frame)
        currentFrame_extract += 4

    video_capture.release()
    cv2.destroyAllWindows()

def frame_extract_3():
    currentFrame_extract = 3
    video_capture = cv2.VideoCapture("DOLFACE_1.mp4")

    while(True):
        ret3, frame = video_capture.read()
        if ret3 == False:
            break
        name = 'frames/frame_' + str(currentFrame_extract) + '.jpg'
        print(f"Processor 3 extracted Frame {currentFrame_extract}, saving it as Frame_{currentFrame_extract}.jpg")
        cv2.imwrite(name, frame)
        currentFrame_extract += 4

    video_capture.release()
    cv2.destroyAllWindows()

def frame_extract_4():
    currentFrame_extract = 4
    video_capture = cv2.VideoCapture("DOLFACE_1.mp4")

    while(True):
        ret4, frame = video_capture.read()
        if ret4 == False:
            break
        name = 'frames/frame_' + str(currentFrame_extract) + '.jpg'
        print(f"Processor 4 extracted Frame {currentFrame_extract}, saving it as Frame_{currentFrame_extract}.jpg")
        cv2.imwrite(name, frame)
        currentFrame_extract += 4

    video_capture.release()
    cv2.destroyAllWindows()

if __name__ == "__main__":

    video_file_path = "DOLFACE_1.mp4"

    frame_extractor_1 = multiprocessing.Process(target=frame_extract_1)
    frame_extractor_2 = multiprocessing.Process(target=frame_extract_2)
    frame_extractor_3 = multiprocessing.Process(target=frame_extract_3)
    frame_extractor_4 = multiprocessing.Process(target=frame_extract_4)

    frame_extractor_1.start()
    frame_extractor_2.start()
    frame_extractor_3.start()
    frame_extractor_4.start()

    frame_extractor_1.join()
    frame_extractor_2.join()
    frame_extractor_3.join()
    frame_extractor_4.join()

Do you know what I am doing wrong? Every "Processor" creates the full Video, without skipping 4 Frames and letting the other Processors do the remaining 3.

marcr
  • 9
  • 3
  • ... You are using mutiprocessing not threads. – wwii Nov 17 '19 at 16:09
  • Does each function work as expected when executed (individually) in the *main* process? You have tested them and they work? – wwii Nov 17 '19 at 16:11
  • Hi wwii, Thanks for yours Help. I'm a Python beginner. I don't really understand the difference between Threading and Multiprocessing, but Multiprocessing seems to have served me well. All of the Functions are running at the same time, but it seems like I am doing something wrong and each function processes every frame, but I actually want to have four functions each processing every fourth frame. This way the work is split onto multiple of my processor cores and is done way quicker. – marcr Nov 17 '19 at 16:19
  • Possible duplicate of [Getting specific frames from VideoCapture opencv in python](https://stackoverflow.com/questions/33523751/getting-specific-frames-from-videocapture-opencv-in-python) ...searching with `python opencv specific frame` or variants produces a number of other results. – wwii Nov 17 '19 at 16:27
  • No, it's not a duplicate. I allready tried this attempt, but it's very CPU intensive to search for the Frames as described in the possible duplicate. – marcr Nov 17 '19 at 16:47
  • Seems like your actual question/problem is `"I want my functions to capture every fourth frame (each offset by one frame) but the functions capture Every frame`. That sounds analogous to `how do I capture specific frames with opencv VideoCapture?` Your functions are not behaving the way you want and it has nothing to do with running them in separate processes. – wwii Nov 17 '19 at 16:52
  • Hi, yes. This is true. However when I try to do it the described way of using specific frames, it seems to still go through every frame but just pick out every fourth. This takes a lot of CPU. – marcr Nov 17 '19 at 17:06

0 Answers0