cv2 problem when saving image - majstr - Jan-21-2020
Hello. I'm wiriting a program that saves the first and the last frame from a video file. Everything is woking perfectly until I try to save the first frame of the video to my PC.
The error happens on line 17 and it says:
TypeError: Expected Ptr<cv::UMat> for argument '%s'
Thank you for any advice you can provide.
def FindScore(path):
cam = cv2.VideoCapture(path)
last_frame = int(cam.get(cv2.CAP_PROP_FRAME_COUNT))
first_frame = "1"
framerate = int(cam.get(cv2.CAP_PROP_FPS)) # ni pomembno
relative = int(cam.get(cv2.CAP_PROP_POS_AVI_RATIO)) # ni pomembno
print("Video frames: {} ".format(last_frame) )
print("Framerate: {} fps".format(framerate))
# Find first frame
cam.set(1,2-1)
frame = cam.read()
name = './data/frame' + str(last_frame) + '.jpg'
cv2.imwrite(name, frame)
myimage1 = Image.open(name)
RE: cv2 problem when saving image - buran - Jan-21-2020
can you post the full traceback you get?
RE: cv2 problem when saving image - majstr - Jan-21-2020
(Jan-21-2020, 01:22 PM)buran Wrote: can you post the full traceback you get?
Error: Traceback (most recent call last):
File ".\LeagueClipSort.py", line 87, in <module>
FindScore(filepath)
File ".\LeagueClipSort.py", line 35, in FindScore
cv2.imwrite(name, frame)
TypeError: Expected Ptr<cv::UMat> for argument '%s'
Here is the full code
from time import sleep
import os
import cv2
import time
import pytesseract
from PIL import Image
from PIL import ImageFilter
pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract.exe' #import tesseract from file
WorkingDirectory="D:/testing" # .py file has to be in the same disk as this folder
print(os.getcwd()) # Current working directory
os.chdir(WorkingDirectory)
print(os.listdir())
start_time = time.time()
counter = 0
# Main
def FindScore(path):
cam = cv2.VideoCapture(path)
last_frame = int(cam.get(cv2.CAP_PROP_FRAME_COUNT))
first_frame = "1"
framerate = int(cam.get(cv2.CAP_PROP_FPS)) # ni pomembno
print("Video frames: {} ".format(last_frame) )
print("Framerate: {} fps".format(framerate))
# Find first frame
cam.set(1,2-1)
frame = cam.read()
name = 'frame' + str(last_frame) + '.jpg'
cv2.imwrite(name, frame)
myimage1 = Image.open(name)
# Find last frame
cam.set(1,last_frame-1)
frame = cam.read()
name = 'picture' + str(first_frame)+ ".jpg"
cv2.imwrite(name, frame)
myimage2 = Image.open(name)
# Get score text
text1 = pytesseract.image_to_string(myimage1)
text2 = pytesseract.image_to_string(myimage2)
# Get Kills
char1 = '#'
char2 = '/'
kills_start = int(text1[text1.find(char1)+1 : text1.find(char2)])
kills_end = int(text2[text2.find(char1)+1 : text2.find(char2)])
kills_diff = kills_end - kills_start
# Get Deaths
dth1 = text1.split('/')
deaths_start = int((dth1[1]))
dth2 = text2.split('/')
deaths_end = int((dth2[1]))
deaths_diff= deaths_end - deaths_start
# Get Assists
ass_begin = find_nth(text1, "/", 2)
ass_end = find_nth(text2, "/", 2)
ass_diff = ass_end - ass_begin
# Rename
num_count= str(counter).zfill(4)
new_name = '{}---{}-{}-{}.mp4'.format(num_count, kills_diff, deaths_diff, ass_diff)
os.rename(path, new_name)
for subdir, dirs, files in os.walk(WorkingDirectory):
for file in files:
filepath = subdir + os.sep + file
if filepath.endswith(".mp4"):
print (file)
#print ("Analyzing: "+file)
FindScore(filepath)
#FindScore(file)
counter = counter +1
sleep(.01)
# Get Assists Function
def find_nth(haystack, needle, n):
start = haystack.find(needle)
while start >= 0 and n > 1:
start = haystack.find(needle, start+len(needle))
n -= 1
besd1=haystack[start+1]
besd2=haystack[start+2]
ass1= int(besd1)
ass2=0
if(besd2 != " "):
ass2= int(besd2)
haystack = ass1*10+ ass2
return haystack
print("Files Analyzed: "+str(counter))
print ("Program took", time.time() - start_time, "seconds to run")
RE: cv2 problem when saving image - buran - Jan-21-2020
Looking at this
https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_gui/py_video_display/py_video_display.html
cam.read() would return tuple and frame is the second element of that tuple
I would try to change
Error: frame = cam.read()
to
ret, frame = cam.read()
RE: cv2 problem when saving image - majstr - Jan-21-2020
That worked, thank you so much.
If you don't mind, I have another (probably very noobish) problem.
Since tesseract doesn't always find the required data from the video screenshots (they are league of legends screenshots), I added try/except in the main loop (line 86-92), but except doesn't work because the file is used by another process. I thought cam.release() would help, but the video file is still open even after that. Thank you again for your help.
Full traceback
Analyzing: D:/testing\a (10).mp4
Video frames: 384
Framerate: 30 fps
Traceback (most recent call last):
File ".\LeagueClipSort.py", line 87, in <module>
FindScore(filepath)
File ".\LeagueClipSort.py", line 52, in FindScore
kills_start = int(text1[text1.find(char1)+1 : text1.find(char2)])
ValueError: invalid literal for int() with base 10: 'Canna @ re TCraIL IE)\n\nvs38 £18'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File ".\LeagueClipSort.py", line 92, in <module>
os.rename(filepath, namerino)
PermissionError: [WinError 32] The process cannot access the file because it is being used by another process: 'D:/testing\\a (10).mp4' -> '000---League of Legends.mp4'
The Code
from time import sleep
import os
import cv2
import time
import pytesseract
from PIL import Image
from PIL import ImageFilter
pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract.exe' #import tesseract from file
WorkingDirectory="D:/testing" # .py file has to be in the same disk as this folder
print(os.getcwd()) # Current working directory
os.chdir(WorkingDirectory)
print(os.listdir())
start_time = time.time()
counter = 0
# Main
def FindScore(path):
cam = cv2.VideoCapture(path)
last_frame = int(cam.get(cv2.CAP_PROP_FRAME_COUNT))
first_frame = "1"
framerate = int(cam.get(cv2.CAP_PROP_FPS)) # ni pomembno
print("Video frames: {} ".format(last_frame))
print("Framerate: {} fps".format(framerate))
# Find first frame
cam.set(1,2-1)
ret, frame = cam.read()
name = '/data/frame' + str(first_frame) + '.jpg'
cv2.imwrite(name, frame)
myimage1 = Image.open(name)
# Find last frame
cam.set(1,last_frame-5)
ret, frame = cam.read()
name = '/data/frame' + str(last_frame) + '.jpg'
cv2.imwrite(name, frame)
myimage2 = Image.open(name)
# Get score text
text1 = pytesseract.image_to_string(myimage1)
text2 = pytesseract.image_to_string(myimage2)
# Get Kills
char1 = '#'
char2 = '/'
kills_start = int(text1[text1.find(char1)+1 : text1.find(char2)])
kills_end = int(text2[text2.find(char1)+1 : text2.find(char2)])
kills_diff = kills_end - kills_start
# Get Deaths
dth1 = text1.split('/')
deaths_start = int((dth1[1]))
dth2 = text2.split('/')
deaths_end = int((dth2[1]))
deaths_diff= deaths_end - deaths_start
# Get Assists
ass_begin = find_nth(text1, "/", 2)
ass_end = find_nth(text2, "/", 2)
ass_diff = ass_end - ass_begin
# Rename
num_count= str(counter).zfill(4)
new_name = '{}---{}-{}-{}.mp4'.format(num_count, kills_diff, deaths_diff, ass_diff)
os.rename(path, new_name)
cam.release()
cv2.destroyAllWindows()
for subdir, dirs, files in os.walk(WorkingDirectory):
for file in files:
filepath = subdir + os.sep + file
if filepath.endswith(".mp4"):
print ("Analyzing: "+filepath)
try:
FindScore(filepath)
except:
counterino= str(counter).zfill(3)
namerino = '{}---League of Legends.mp4'.format(counterino)
os.rename(filepath, namerino)
counter = counter +1
sleep(.01)
# Get Assists Function
def find_nth(haystack, needle, n):
start = haystack.find(needle)
while start >= 0 and n > 1:
start = haystack.find(needle, start+len(needle))
n -= 1
besd1=haystack[start+1]
besd2=haystack[start+2]
ass1= int(besd1)
ass2=0
if(besd2 != " "):
ass2= int(besd2)
haystack = ass1*10+ ass2
return haystack
print("Files Analyzed: "+str(counter))
print ("Program took", time.time() - start_time, "seconds to run")
RE: cv2 problem when saving image - buran - Jan-21-2020
Can you post your current code in python tags (minimal reproducible example)? also post traceback in error tags.
I would guess the problem is in myimage1 = Image.open(name)
but it's not clear what Image is (Pillow.Image?) or do you close it
Sorry - I saw the code
RE: cv2 problem when saving image - buran - Jan-21-2020
The problem is that the exception happens on line 52 - it try to convert str Canna @ re TCraIL IE)\n\nvs38 £18 to int which raise Value Error. At that time cam is not released thus mp4 file is still used by another process which in turn raise the second error.
So some advise - release cam immaterially when it is no longer needed - this should solve the current issue.
in addition- use with context manager to open the Image object - https://pillow.readthedocs.io/en/stable/reference/open_files.html#file-handling
- don't use general except (catch-all) like on 89.
- you may want to wrap lines 52-54 in try except of their own that catch ValueError during conversion to int
- you may want to break FindScore() function in to smaller functions - e.g. separate function to grab frame, or first and last frame, another one to calculate scores, etc.
RE: cv2 problem when saving image - majstr - Jan-21-2020
(Jan-21-2020, 03:30 PM)buran Wrote: The problem is that the exception happens on line 52 - it try to convert str Canna @ re TCraIL IE)\n\nvs38 £18 to int which raise Value Error. At that time cam is not released thus mp4 file is still used by another process which in turn raise the second error.
So some advise - release cam immaterially when it is no longer needed - this should solve the current issue.
in addition- use with context manager to open the Image object - https://pillow.readthedocs.io/en/stable/reference/open_files.html#file-handling
- don't use general except (catch-all) like on 89.
- you may want to wrap lines 52-54 in try except of their own that catch ValueError during conversion to int
- you may want to break FindScore() function in to smaller functions - e.g. separate function to grab frame, or first and last frame, another one to calculate scores, etc.
Thanks, thats a lot of very usefull information.
|