我编写了一个脚本,从视频中提取帧以获取一些信息,因此我循环遍历帧,将图像写入临时文件夹,执行一些操作,删除图像:
# if frame exists, capture
while framesleft:
framesleft,image = vid.read()
if framesleft:
imfile = cv2.imwrite("temperonispaghettioni/video%03dframe%05d.png" % (videonr, framenr), image)
# write the filename, video and frame to FrameList.csv
row = ["bla bla bla unimportant stuff"]
writer.writerow(row)
# Make sure the image is closed and remove the image
image = None
imfile = None
os.remove("temperonispaghettioni/video%03dframe%05d.png" % (videonr, framenr))
大多数时候这一切都很好。每 10000 次迭代左右一次(不是一个确切的数字并且它会变化),我会收到以下错误:
os.remove("temperonispaghettioni/video%03dframe%05d.png" % (videonr, framenr))
PermissionError: [WinError 5] Access is denied: 'temperonispaghettioni/video000frame01218.png'
如您所见,我尝试将 image 和 imfile 设置为 None 以尝试关闭文件。这似乎并不能解决问题。我还能尝试什么来正确关闭文件,或者这里还有其他问题吗?
我也意识到,我的 whileframesleft:ifframesleft: 是一种低效的方法。我遇到的问题是,当视频超出帧时,代码会创建 1 个我无法处理的最后损坏的 .png。如果有人提出改进建议,我们将非常欢迎。
编辑: 我已经 try catch 原始错误:
try:
os.remove("temperonispaghettioni/video%03dframe%05d.png" % (videonr, framenr))
except PermissionError:
print('Ran into an error with deleting frame %05d of video %03d, trying again...' %(framenr,videonr))
time.sleep(0.5)
try:
os.remove("temperonispaghettioni/video%03dframe%05d.png" % (videonr, framenr))
print('Succesfully removed frame%05d of video %03d, moving on...' %(framenr,videonr))
except PermissionError:
print('Removal failed, frame will remain in the folder and the folder won\'t delete itself. Moving on...')
我已经将整个脚本循环运行了几百次,看看是否可以重新创建错误,到目前为止它甚至没有进入 except 阶段,但我收到了一个新错误:
os.mkdir('temperonispaghettioni')
PermissionError: [WinError 5] Access is denied: 'temperonispaghettioni'
同样的问题,但现在要制作目录。我应该 try catch 每个写入/删除操作吗?
最佳答案
这里的构造需要中间循环中断:
while True:
framesleft, image = vid.read()
if not framesleft:
break
process(framesleft, image)
另一种方式,如果你不介意一点点重复,你也可以在循环外进行第一次读取:
framesleft, image = vid.read()
while framesleft:
process(framesleft, image)
framesleft, image = vid.read()
在 Python 3.8 之前,这些实际上是在 Python 中编写此类循环的唯一方法。
在 Python 3.8 及更高版本中,Python 获得了一种新的赋值表达式语法,人们将其称为海象运算符::=
。使用 walrus 运算符,您可以执行如下操作:
while (frame_image := vid.read())[0]:
framesleft, image = frame_image
process(framesleft, image)
至于为什么你会收到权限被拒绝的错误,我真的不能说,你的帖子中没有足够的信息来真正了解这里发生了什么。您是否在启动程序之前确保该目录为空,并且不存在先前运行中可能具有不正确权限的剩余文件?您是否有另一个程序实例在后台或单独的线程/进程中运行?
此外,由于您创建文件只是为了稍后删除它,为什么不直接使用 https://docs.python.org/3.7/library/tempfile.html#tempfile.mkstemp这样您就不必生成唯一的文件名并祈祷不存在冲突或权限问题。
关于python - 使用 os.remove() 时,每 10000 次左右就有 1 次出现 PermissionError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59071780/