Video processing using Python + OpenCV on Mac

There were some addictive points when creating a video processing program with OpenCV on Mac, so this is a memorandum.

at first

The created program performs arbitrary image processing on the image for each frame of the input video, and saves the processed image as a video again. The flow of video processing is as follows.

  1. Load a locally stored video
  2. Image processing frame by frame
  3. Write as a video file

Execution environment

Install opencv-python with the following command.

pip install opencv-python

Overview of source code

The whole picture of the created source code is as follows. The processing for the video is to flip the top, bottom, left, and right in processed_frame = cv2.flip (frame, -1) on the 67th line. By executing this program, you can create a video in which the input video is flipped vertically and horizontally.

By replacing the up / down / left / right inversion processing with arbitrary image processing, various video processing can be performed with Python.

python:./main.py


import os
import cv2
import argparse


class MovieIter(object):
    """
Video Iterator
    """

    def __init__(self, moviefile, inter_method=cv2.INTER_AREA):
        if os.path.isfile(moviefile):  #When the mp4 file exists
            print("[Loading]\tLoading Movie")
            self.org = cv2.VideoCapture(moviefile)

        self.framecnt = 0
        self.inter_method = inter_method

    def __iter__(self):
        return self

    def __next__(self):
        self.end_flg, self.frame = self.org.read()
        if not self.end_flg:  #End the loop when you reach the end of the video
            raise StopIteration()
        self.framecnt += 1
        return self.frame

    def __del__(self):
        self.org.release()

    def get_size(self) -> (int, int):
        """Returns video resolution

        Returns:
            (int, int): (w, h)
        """
        return (
            int(self.org.get(cv2.CAP_PROP_FRAME_WIDTH)),
            int(self.org.get(cv2.CAP_PROP_FRAME_HEIGHT)),
        )

    def get_fps(self) -> float:
        """Returns the Fps of the video

        Returns:
            float: fps
        """
        return self.org.get(cv2.CAP_PROP_FPS)


def main(movie_path, save_path):
    #Define the video to enter
    input_movie = MovieIter(movie_path)
    input_moveie_size = input_movie.get_size()

    #Definition of video file to output
    fourcc = cv2.VideoWriter_fourcc(*"mp4v")
    output_movie = cv2.VideoWriter(
        os.path.join(save_path, "output.mp4"),  #Path to save
        fourcc,  #Ko-Dick
        input_movie.get_fps(),  #Video fps
        input_moveie_size,  #Video resolution
    )

    for frame in input_movie:
        processed_frame = cv2.flip(frame, -1)  #Up / down / left / right inversion

        #Check if the video resolution is different because it cannot be saved.
        assert processed_frame.shape[:2][::-1] == input_moveie_size
        output_movie.write(processed_frame)

    #Release and save video
    output_movie.release()


if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="Purogram to process video")

    parser.add_argument("movie_path", help="URL of the video to be processed")
    parser.add_argument("--save_path", default="results", help="The path of the directory to save the generated image")

    args = parser.parse_args()
    main(args.movie_path, args.save_path)

The command at runtime is as follows. If the process is successful, a video with the top, bottom, left, and right of $ {path of the video to be processed} is created and saved in the folder specified in --save_path.

python main.py ${Video path to process} --save_path ${Path to save the processed video}

Where I was addicted

Specifying the image size to write to the video

The first addictive point is that if the size of the image specified in cv2.VideoWriter () on the 57th line of the source code is different from the size of the image written in output_movie.write (processed_frame) on the 71st line, The point is that the video export fails.

~~~abridgement~~~~
    output_movie = cv2.VideoWriter(
        os.path.join(save_path, "output.mp4"),  #Path to save
        fourcc,  #Ko-Dick
        input_movie.get_fps(),  #Video fps
        input_moveie_size,  #Video resolution ← here!
    )
~~~abridgement~~~~

Generally, the image size of opencv is defined in the order of (height, width, chnnel). However, on the other hand, the image size specified by cv2.VideoWriter () must be defined in the order of (width, height). So, if you usually think that "image size is in the order of(height, width)~", the phenomenon that video export fails due to the difference in image size between definition and writing occurs. To do.

Moreover, the trouble is that even if the above-mentioned phenomenon that the video export fails due to the difference in size occurs, opencv does not return an error or warning. As a result, I wasted time asking, "Why can't I save the program even though it's normal?", And it took me a long time to notice the mistake in specifying the image size.

As a solution, I put in the process of confirming with assert as follows.

~~~abridgement~~~~
        #Check if the video resolution is different because it cannot be saved.
        assert processed_frame.shape[:2][::-1] == input_moveie_size
~~~abridgement~~~~

When creating a grayscale video

If the format of the created video is grayscale, you need to specify 0 for the 5th argument of cv2.VideoWriter (). If you forget to specify this as well, the phenomenon of simply failing to export the video will occur without any error warning, as in the above case.

~~~abridgement~~~~
    output_movie = cv2.VideoWriter(
        os.path.join(save_path, "output.mp4"),  #Path to save
        fourcc,  #Ko-Dick
        input_movie.get_fps(),  #Video fps
        input_moveie_size,  #Video resolution ← here!
        0 #← Here!
    )
~~~abridgement~~~~

Specifying the video codec

The second point is that it is necessary to specify the corresponding format according to the execution environment for the codec format of the video on the 58th line of the source code.

~~~abridgement~~~~
    #Definition of video file to output
    fourcc = cv2.VideoWriter_fourcc(*"mp4v") #← Here!
~~~abridgement~~~~

Articles that appear at the top when you search for "opencv python video" etc. are often specified as cv2.VideoWriter_fourcc (*'XVID'), and the author follows it in the .avi format as it is. I tried to save it with, but the export did not work. Depending on the version, it seems that it can be saved in .avi format on MacOS, but saving in mp4 format seems to be the most stable.

The operating status of each format on Mac is summarized by volunteers in the following links. Before writing a program, you should make sure that the format you want to use works well on your Mac.

At the end

If you are failing to save due to a different format or size, I would like you to issue a warning ...

reference

-Python + OpenCV to detect anime cuts-Niseneko Memo -[Basic] Handling videos with python + openCV --Qiita

Recommended Posts

Video processing using Python + OpenCV on Mac
Using OpenCV with Python @Mac
python on mac
Notes for using OpenCV on Windows10 Python 3.8.3.
Install opencv on Mac using Anaconda Navigator
Install Python on Mac
Install Python 3 on Mac
Install Python 3.4 on Mac
"Apple processing" with OpenCV3 + Python3
Install pygame on python3.4 on mac
Try using OpenCV on Windows
Handling of python on mac
Update python on Mac to 3.7-> 3.8
Notes on installing Python on Mac
Build a Python environment on your Mac using pyenv
Broadcast on LINE using python
Minimum memo when using Python on Mac (pyenv edition)
Using Python mode in Processing
Minimum notes when using Python on Mac (Homebrew edition)
Using multiple versions of Python on Mac OS X (2) Usage
Using NAOqi 2.4.2 Python SDK on Mac OS X El Capitan
Building a Python environment on a Mac and using Jupyter lab
Easy on Mac! Plot of unit step response using Python
Building a Python environment on Mac
If python on mac goes missing
[Python] Using OpenCV with Python (Image Filtering)
[Python] Using OpenCV with Python (Image transformation)
Introducing Python using pyenv on Ubuntu 20.04
Notes on using MeCab from Python
Preparing python using vscode on ubuntu
Create a Python environment on Mac (2017/4)
Introducing OpenCV on Mac with homebrew
Python environment construction memo on Mac
Install Python 3.7 Anaconda on MAC, but Python 2
How to install OpenCV on Mac
Study on Tokyo Rent Using Python (3-2)
Environment construction of python3.8 on mac
Horizon processing using OpenCV morphology transformation
Notes on using rstrip with python.
Install Python on CentOS using Pyenv
If Python 3.5.0 installation fails on Mac
Study on Tokyo Rent Using Python (3-3)
Steps to install python3 on mac
Install Python on CentOS using pyenv
(Beginner) Notes on using pyenv on Mac
Call C / C ++ from Python on Mac
OpenCV3 & Python3 environment construction on Ubuntu
Update Python on Mac from 2 to 3
Using multiple versions of Python on Mac OS X (1) Multiple Ver installation
Stream speech recognition using Google Cloud Speech gRPC API on python3 on Mac!
[Image processing] Edge detection using Python and OpenCV makes Poo naked!
Aligning scanned images of animated video paper using OpenCV and Python
Execute Python code on C ++ (using Boost.Python)
Periodic execution processing when using tkinter [Python3]
[Python] Speeding up processing using cache tools
[Python] Matrix multiplication processing time using NumPy
Detect "brightness" using python on Raspberry Pi 3!
Build Python3 and OpenCV environment on Ubuntu 18.04
Introducing MAMP + Python + SQLAlchemy (Mysql-Python) on Mac
Create a python environment on your Mac
Put Anaconda on your Mac using Pyenv