Search code examples
pythonopencvfilepathos.path

Formatting filepaths using variables on in os.path


I've written a script that splits a video file into frames using cv2 and some other modules. Up to now, I was happy pasting in the filepaths and running the code, but now I want the user to input the filepaths and names in response to a prompt. This should be easy, but I'm having a lot of trouble making os.path work for me. The main problem is that I want the name of each image file (i.e. frame) to have a number in it that shows where it comes in the sequence. The code below is what I have:

filepath = input('Please enter the filepath for the clip: ') 

clip = cv2.VideoCapture(filepath)

#### This code splits the clip into scenes

filepath1 = input('Please enter the filepath for where the frames should be saved: ') 

name = input('Please enter the name of the clip: ') 

ret, frame = clip.read()
count = 0
ret == True
while ret:
    ret, frame = clip.read()
    cv2.imwrite((os.path.join(filepath1,name, '(%d)','.png') % count, frame))
    count += 1

However, the produces the following error:

cv2.imwrite((os.path.join(filepath1,name, '(%d)','.png') % count, frame))
    TypeError: Required argument 'img' (pos 2) not found

Including the % count, frame variables in the parentheses in the os.path.join command gives a different error:

TypeError: not all arguments converted during string formatting

What it should do is write a number of .png files called name(x) to a location like MYcomputer/mydesktop/myfolder/. I'm not sure what's gone wrong here––any help appreciated!


Solution

  • Your parenthesis placement as well as the usage of join is wrong This

    cv2.imwrite((os.path.join(filepath1,name, '(%d)','.png') % count, frame))
    

    should be corrected to this:

    cv2.imwrite(os.path.join(filepath1, name+'(%d).png'%count), frame)
    

    To further improve the code I would suggest

    fname = "{name}({count}).png".format(name=name, count=count)
    cv2.imwrite(os.path.join(filepath1, fname), frame)
    

    Here a brief explanation of os.path.join: It concatenates all the arguments with the path delimiter of your OS ("/" on Unix-Based and "\" on Windows). As the result, your original code would result in following string:

    filepath1 = "some_dir"
    name = "some_name"
    count = 10
    print(os.path.join(filepath1, name, '(%d)' % count,'.png'))
    >>> "some_dir/some_name/10/.png"