Opencv videocapture with multiple files in scanned directory

Hi all,

I’m kinda stuck on this and can’t figure out what’s going on. What I would like to do is:

  • scan a directory for video (mp4) files
  • open each file for processing with opencv videocapture
# file operations
import os
# Motion detection
import cv2


# Scan target directory
# os.scandir returns an iterator, make it a list to be re-usable

# Target directory is in the same directory as the script
targetDirectory = "videofiles"
dircontent = list(os.scandir(targetDirectory))

# Search for mp4 files and make a list [ [filename, path], [filename, path], ... ]
mp4Files = [[f.name[:-4], os.path.abspath(f.name)] for f in dircontent if f.name.lower().endswith('.mp4')]

for videofile in mp4Files:

    print(videofile[1], " -- ", type(videofile[1]))
    # This print: E:\Projects\Programming\Python\OpenCV\_CaptureSaveROI\Motiondetection_Batch_Heatmap\Burglary.mp4  --  <class 'str'>

    # Open file to process
    cap = cv2.VideoCapture(videofile[1])

    print(cap)
    # This prints: <VideoCapture 018CB4C0>

    # the following doesn't give an error:
    # cap = cv2.VideoCapture("E:/Projects/Programming/Python/OpenCV/_CaptureSaveROI/Motiondetection_Batch_Heatmap/videofiles/Burglary.mp4")

    ret, frame1 = cap.read()
    heatmap = frame1.copy() # <<<<<<< ERROR

The error I get is:

heatmap = frame1.copy()
AttributeError: 'NoneType' object has no attribute 'copy'

Is there anyone who knows what’s going on here?
Thanks in advance

I just tried this:

for videofile in mp4Files:

    print(videofile[1], " -- ", type(videofile[1]))
    # This print: E:\Projects\Programming\Python\OpenCV\_CaptureSaveROI\Motiondetection_Batch_Heatmap\Burglary.mp4  --  <class 'str'>

    # Open file to process
    cap = cv2.VideoCapture(videofile[1])

    # the following doesn't give an error:
    # cap = cv2.VideoCapture("E:/Projects/Programming/Python/OpenCV/_CaptureSaveROI/Motiondetection_Batch_Heatmap/videofiles/Burglary.mp4")

    print(cap)
    # This prints: <VideoCapture 018CB4C0>

    if (cap.isOpened() == False):
        print("Error opening the video file")
    else:
        ret, frame1 = cap.read()
        heatmap = frame1.copy() # <<<<<<< ERROR

The output is:

E:\Projects\Programming\Python\OpenCV\_CaptureSaveROI\Motiondetection_Batch_Heatmap\Burglary.mp4  --  <class 'str'>
<VideoCapture 00C7B4C0>
Error opening the video file

I’m scratching my head over this one…

Howdy Bart,

The second element of the tuple returned by cap.read(), which is assigned to frame1, seems to be ‘None’. Does that answer your question?

Cheers, Dominik

maybe this helps:

?

Cheers, Dominik

The thing is that the cap object is not valid when using a (string) videofilepath coming from the list.

ret, frame1 = cap.read()
    print(ret)                  # returns false
    heatmap = frame1.copy()     # <<<<<<< ERROR: 'NoneType' object has no attribute 'copy'

ret returns false and frame1 doesnt exist (is nonetype) So yeah that a problem

cap.isOpened() returns true if I feed the literal string into cv2.VideoCapture() If I input the string from the list to cv2.VideoCapture() I get the nonetype error.

I’ve been staring at this too long and missed the difference in the paths:

…Motiondetection_Batch_Heatmap\Burglary.mp4
…Motiondetection_Batch_Heatmap/videofiles/Burglary.mp4

Changing
os.path.abspath(f.name)
to
os.path.abspath(f)

did the trick.

Problem solved

1 Like