Can anyone help me with reading a continuously updating video file with python?

Viewed 317

I have a small ImageAI program which is detecting a few objects via my webcam and/or IP webcam, the final part looks something like this:

execution_path = os.getcwd()
detector = VideoObjectDetection()
detector.setModelTypeAsYOLOv3()
detector.setModelPath(os.path.join(execution_path , "yolo.h5"))
detector.loadModel()
print('Model loaded')

cap = cv2.VideoCapture(0)

video_path = detector.detectObjectsFromVideo(camera_input=cap,
                        output_file_path=os.path.join(execution_path, "captured")
                        , frames_per_second=5, log_progress=True, detection_timeout=120)

print(video_path)

This is resulting in creating an avi file that is recording the video and detecting the objects. While I can see the progress by opening this file, I have to close it and open again in order to see the ongoing updated progress. Is there a way to display this video with something like %matplotlib inline, etc?

enter image description here

1 Answers

I have not used it, but if you look at the documentation it has an optional parameter to return the detected frame:

– parameter return_detected_frame (optional) : This parameter allows you to return the detected frame as a Numpy array at every frame, second and minute of the video detected. The returned Numpy array will be parsed into the respective per_frame_function, per_second_function and per_minute_function (See details below)

and then you need to also pass a function to this parameter:

—parameter per_frame_function (optional ) : This parameter allows you to parse in the name of a function you define. Then, for every frame of the video that is detected, the function will be parsed into the parameter will be executed and and analytical data of the video will be parsed into the function. The data returned can be visualized or saved in a NoSQL database for future processing and visualization.

The new function should look like the one in the documentation:

def forFrame(frame_number, output_array, output_count, returned_frame):

    plt.clf()

    this_colors = []
    labels = []
    sizes = []

    counter = 0

    for eachItem in output_count:
        counter += 1
        labels.append(eachItem + " = " + str(output_count[eachItem]))
        sizes.append(output_count[eachItem])
        this_colors.append(color_index[eachItem])

    global resized

    if (resized == False):
        manager = plt.get_current_fig_manager()
        manager.resize(width=1000, height=500)
        resized = True

    plt.subplot(1, 2, 1)
    plt.title("Frame : " + str(frame_number))
    plt.axis("off")
    plt.imshow(returned_frame, interpolation="none")

    plt.subplot(1, 2, 2)
    plt.title("Analysis: " + str(frame_number))
    plt.pie(sizes, labels=labels, colors=this_colors, shadow=True, startangle=140, autopct="%1.1f%%")

    plt.pause(0.01)

This will also plot a the other analytical data, but you can just plot the frame.

Your code will have to change to look like this:

video_path = detector.detectObjectsFromVideo(camera_input=cap,
                        output_file_path=os.path.join(execution_path, "captured")
                        , frames_per_second=5, log_progress=True, detection_timeout=120,
                        return_detected_frame=True, per_frame_function=forFrame)

Take note of the two last arguments.

I hope this helps you

Related