Mercurial Hosting > traffic-intelligence
changeset 890:85bcc758ee5b
new version to manual annotation, easy to configure to add new road user type and characteristics
author | Nicolas Saunier <nicolas.saunier@polymtl.ca> |
---|---|
date | Tue, 28 Mar 2017 17:17:02 -0400 |
parents | 4ea296ee1ae2 |
children | ab3a4cb524a9 |
files | scripts/manual-video-analysis.py |
diffstat | 1 files changed, 84 insertions(+), 55 deletions(-) [+] |
line wrap: on
line diff
--- a/scripts/manual-video-analysis.py Fri Mar 24 14:20:01 2017 -0400 +++ b/scripts/manual-video-analysis.py Tue Mar 28 17:17:02 2017 -0400 @@ -1,6 +1,6 @@ #! /usr/bin/env python -import sys, argparse, cv2 +import sys, argparse, cv2, numpy as np parser = argparse.ArgumentParser(description=''''The program replays the video and allows to manually id vehicles and mark instants, eg when they cross given areas in the scene. Use this program in combination with a screen marker program (For example, Presentation Assistant) to draw multiple lines on the screen.''', epilog = '''The output should give you a .csv file with the same name as your video file with columns in this format: @@ -10,21 +10,20 @@ parser.add_argument('-i', dest = 'videoFilename', help = 'name of the video file', required = True) parser.add_argument('-o', dest = 'outputFilename', help = 'name of the output file (csv file)') parser.add_argument('-f', dest = 'firstFrameNum', help = 'number of first frame number to display', default = 0, type = int) +parser.add_argument('-n', dest = 'nAttributes', help = 'number of attributes characterizing users', default = 0, type = int) args = parser.parse_args() print('''Commands: -u: New vehicle crossing the first line -i: Vehicle crossing subsequent lines -o: Press o when you make a mistake in input -p: Press p for a new pedestrian event (eg crossing) -d: Skip 100 frames -s: Skip 10 frames -c: Go back 100 frames -x: Go back 10 frames -Spacebar: Go forward one frame -l: Skip to frame number -q: Quit and end program''') +Press o when you make a mistake in input +Press d to skip 100 frames +Press s to skip 10 frames +Press c to go back 100 frames +Press x to go back 10 frames +Press spacebar to go forward one frame +Press l to skip to frame number +Press Enter to finish inputting user characteristics (if any in pop up window) +Press q to quit and end program''') # configuration of keys and user types (see moving) userTypeNames = ['unknown', 'car', @@ -34,13 +33,30 @@ 'bus', 'truck'] class UserConfiguration(object): - def __init__(self, name, keyNew, keyAddInstant): + def __init__(self, name, keyNew, keyAddInstant, nAttributes): self.name = name self.keyNew = ord(keyNew) self.keyAddInstant = ord(keyAddInstant) self.userNum = 0 + self.nAttributes = nAttributes + self.resetAttributes() + + def getHelpStr(self): + return 'Press {} for new {}, {} for new instant for current {}'.format(chr(self.keyNew), self.name, chr(self.keyAddInstant), self.name) + + def resetAttributes(self): self.userInstant = 0 + self.attributes = [-1]*self.nAttributes + def setAttribute(self, i, value): + self.attributes[i%self.nAttributes] = value + + def getAttributeStr(self): + if self.nAttributes > 0: + return ','.join([str(i) for i in self.attributes])+',' + else: + return '' + def isKeyNew(self, k): return (k == self.keyNew) @@ -48,21 +64,27 @@ return (k == self.keyAddInstant) def isKey(self, k): - return self.isKeyNew() or self.isKeyAddInstant() + return self.isKeyNew(k) or self.isKeyAddInstant(k) @staticmethod - def isKey(configurations): + def getConfigurationWithKey(configurations, k): for c in configurations: - if c.isKey(): + if c.isKey(k): return c return None -userConfigurations = [UserConfiguration(userTypeNames[1],1,'u','i'), - UserConfiguration(userTypeNames[2],2,'j','k')] +userConfigurations = [UserConfiguration(userTypeNames[1],'u','i', args.nAttributes), + UserConfiguration(userTypeNames[2],'j','k', args.nAttributes)] + +print(' ') +for c in userConfigurations: + print(c.getHelpStr()) # start of program cap = cv2.VideoCapture(args.videoFilename) cap.set(cv2.cv.CV_CAP_PROP_POS_FRAMES, args.firstFrameNum) +fps = cap.get(cv2.cv.CV_CAP_PROP_FPS) +print('Video at {} frames/s'.format(fps)) cv2.namedWindow('Video', cv2.WINDOW_NORMAL) # output filename @@ -89,45 +111,52 @@ if key == ord('q'): break else: - config = UserConfiguration.isKey(userConfigurations) + config = UserConfiguration.getConfigurationWithKey(userConfigurations, key) if config is not None: - if c.isKeyNew(): - pass # increment userNum - elif c.isKeyAddInstant(): - pass # increment userInstant - # print/write - - elif key == ord('u') or key == ord('i'): - if key == ord('u'): - vehNumber += 1 - lineNum = 0 - print('New Vehicle') - out.write('{},{}\n'.format(vehNumber,frameNum)) - if vehNumber >= 1 and key == ord('i'): - lineNum = lineNum+1 - print('Line number {}'.format(lineNum)) - elif key == ord('o'): - out.write('{},SKIP\n'.format(vehNumber)) - print('SKIPPED') - elif key == ord('p'): - print("New Pedestrian") - out.write('Pedestrian,{}\n'.format(frameNum)) -#Change the number of frames skipped or the keys in this section - elif key == ord('d'): - cap.set(1,frameNum+100) - elif key == ord('s'): - cap.set(1,frameNum+10) - elif key == ord('a'): - cap.set(1,frameNum+1) - elif key == ord('x'): - cap.set(1,frameNum-10) - elif key == ord('c'): - cap.set(1,frameNum-100) - elif key == ord('l'): - frameNum = int(raw_input("Please enter the frame number you would like to skip to\n")) - cap.set(cv2.cv.CV_CAP_PROP_POS_FRAMES,frameNum-5) + if config.isKeyNew(key): + config.userNum += 1 + config.resetAttributes() + print('New {} {}'.format(config.name, config.userNum)) + if args.nAttributes > 0: + key2 = ord('1') + cv2.namedWindow('Input', cv2.WINDOW_NORMAL) + attributeNum = 0 + while key2 != ord('\n'): + attrImg = 255*np.ones((20*args.nAttributes, 20, 3)) + for i in xrange(args.nAttributes): + if i == (attributeNum%args.nAttributes): + cv2.putText(attrImg, str(config.attributes[i]), (1,20*(i+1)), cv2.FONT_HERSHEY_PLAIN, 1, (0, 0, 255)) + else: + cv2.putText(attrImg, str(config.attributes[i]), (1,20*(i+1)), cv2.FONT_HERSHEY_PLAIN, 1, (0, 255, 0)) + cv2.imshow('Input', attrImg) + key2 = cv2.waitKey(0) + if chr(key2).isdigit(): + config.setAttribute(attributeNum, chr(key2)) + attributeNum += 1 + cv2.destroyWindow('Input') + elif config.isKeyAddInstant(key): + config.userInstant += 1 + print('User {} no {} at line {}'.format(config.name, config.userNum, config.userInstant)) + out.write('{},{},{}{}\n'.format(config.userNum, config.name, config.getAttributeStr(), config.userInstant)) + oldUserConfig = config + if key == ord('o'): + print('SKIPPED') + out.write('{},{},SKIP\n'.format(oldUserConfig.userNum, oldUserConfig.name)) + elif key == ord('d'): + cap.set(1,frameNum+100) + elif key == ord('s'): + cap.set(1,frameNum+10) + elif key == ord('a'): + cap.set(1,frameNum+1) + elif key == ord('x'): + cap.set(1,frameNum-10) + elif key == ord('c'): + cap.set(1,frameNum-100) + elif key == ord('l'): + frameNum = int(raw_input("Please enter the frame number you would like to skip to\n")) + cap.set(cv2.cv.CV_CAP_PROP_POS_FRAMES,frameNum) - +out.close() cap.release() cv2.destroyAllWindows()