def main(sysargs): args = EasyArgs(sysargs) cfg = EasyConfig(args.cfg, group="compare_trainer") window_name = "EagleEye Comparator" if "help" in args: usage() return 0 # grab marks from args if len(args) > 5: mark_in = args[4] mark_out = args[5] # test integer-ness try: int(mark_in) and int(mark_out) except: usage() return 1 # or grab them from a marker tool elif len(args) > 3: ret, mark_in, mark_out = marker_tool(args[1], 50, window_name) if not ret: print "Not processing - exiting." return 1 else: usage() return 1 # determine sides side = Theta.resolve(args.side or 'buttonside') # open inouts files vid = BuffSplitCap(args[1], buff_max=cfg.buffer_size, side=Theta.Both) mapper_xml = Xmlset(args[2], offset=cfg.offset, offmode=Xmlset.offset_mode(cfg.offset_mode)) trainer_xml = Xmltrainer(args[3], side=side) reprojerror_list = {} # list of reprojection error of all frames lastframe = False # reject mapper_xml if it doesn't contain the trainer_target if cfg.trainer_target not in mapper_xml.data(0): print "Mapping file must contain training target:", cfg.trainer_target print "Target names in mapping file:", mapper_xml.data(0) print "Please specifiy correct target name in config" return 1 # also reject if it's lens data doesn't match the trainer_xml _test_lens = mapper_xml.data(0)[cfg.trainer_target]['lens'] if (_test_lens == Theta.NonDual and side != Theta.NonDual) \ or (side != Theta.NonDual and _test_lens == Theta.NonDual): print "Mapping file doesn't match training file" print "map:", Theta.name(_test_lens), "trainer:", Theta.name(side) return 1 # sync the video and xml vid.restrict(mark_in, mark_out) cropped_total = mark_out - mark_in mapper_xml.setRatio(cropped_total) # status print "ratio at:", mapper_xml.ratio() print "offset by:", cfg.offset, "in", cfg.offset_mode, "mode" print "" # open export (if specified) if args.video_export: in_fps = vid.get(cv2.CAP_PROP_FPS) in_size = (int(vid.get(cv2.CAP_PROP_FRAME_WIDTH)), int(vid.get(cv2.CAP_PROP_FRAME_HEIGHT))) out_vid = cv2.VideoWriter(args.video_export, cv2.VideoWriter_fourcc(*cfg.fourcc), in_fps, vid.shape[:2]) print "exporting to:", args.video_export else: cv2.namedWindow(window_name) print "interactive mode" # main loop while vid.isOpened(): frame = vid.frame() reprojerror_list = compareReproj(frame, vid.at(), mapper_xml, trainer_xml, reprojerror_list, cfg) # export or navigate if args.video_export: sys.stdout.write("Reading Video Frame: {} / {}\r".format(vid.at(), mark_out)) sys.stdout.flush() out_vid.write(frame) if vid.next(): reprojerror_list = compareReproj(frame, vid.at(), mapper_xml, trainer_xml, reprojerror_list, cfg) mapper_xml.next() else: calReprojList(reprojerror_list) print "\nend of video" break else: cv2.imshow(window_name, frame) key = cv2.waitKey(0) showAll = False # toggle to show all training points in one frame # controls if key == Key.esc: print "\nexiting." break elif key == Key.right: if vid.next(): mapper_xml.next() else: if lastframe is False: print "\nEnd of video" calReprojList(reprojerror_list) lastframe = True elif key == Key.left: if vid.back(): mapper_xml.back() elif key == Key.enter: while True: reprojerror_list = compareReproj(frame, vid.at(), mapper_xml, trainer_xml, reprojerror_list, cfg) cv2.imshow(window_name, frame) if vid.next(): mapper_xml.next() frame = vid.frame() # break when over else: break calReprojList(reprojerror_list) print "\nFast forwarded to end of video" if args.compare_export: print "Output to file" writeFile(args.compare_export, reprojerror_list) break elif key == Key.space: ''' TODO: display all training points, may be abandoned problems: frame is not refreshed after imshow if showAll is False: displayTrainPts(frame, mark_in, mark_out, trainer_xml, cfg) # #except: # print "Error in displaying training points. Exiting..." # return 1 # showAll = True else: frame, reprojerror_list = compareReproj(frame, vid.at(), mapper_xml, trainer_xml, reprojerror_list, cfg) showAll = False ''' pass # clean up vid.release() if args.video_export: out_vid.release() else: cv2.destroyAllWindows() return 0
def main(sysargs): args = EasyArgs(sysargs) cfg = EasyConfig(args.cfg, group="compare") window_name = "EagleEye Comparator" if "help" in args: usage() return 0 # grab marks from args if len(args) > 5: mark_in = args[4] mark_out = args[5] # test integer-ness try: int(mark_in) and int(mark_out) except: usage() return 1 # or grab them from a marker tool elif len(args) > 3: ret, mark_in, mark_out = marker_tool(args[1], 50, window_name) if not ret: print "Not processing - exiting." return 1 else: usage() return 1 # open video files vid = BuffSplitCap(args[1], buff_max=cfg.buffer_size) xml1 = Xmlset(args[2]) xml2 = Xmlset(args[3]) # trim the video vid.restrict(mark_in, mark_out) # trim the CSV cropped_total = mark_out - mark_in xml1.setRatio(cropped_total) xml2.setRatio(cropped_total ) # should be 1.0 (total frames should be the same as video) print 'xml1 ratio:', xml1.ratio() print 'xml2 ratio:', xml2.ratio() # open export (if specified) if 'export' in args: in_fps = vid.get(cv2.CAP_PROP_FPS) in_size = (int(vid.get(cv2.CAP_PROP_FRAME_WIDTH)), int(vid.get(cv2.CAP_PROP_FRAME_HEIGHT))) out_vid = cv2.VideoWriter(args.export, cv2.VideoWriter_fourcc(*cfg.fourcc), in_fps, in_size) else: cv2.namedWindow(window_name) while vid.isOpened(): sys.stdout.write(vid.status() + "\r") sys.stdout.flush() frame = vid.frame() # draw objects from each dataset for name in xml1.data(): draw(frame, xml1.data()[name], cfg.xml1_colour) for name in xml2.data(): draw(frame, xml2.data()[name], cfg.xml2_colour) # print status to screen displayText(frame, vid.status(), top=True) displayText(frame, "{}: {}".format(os.path.basename(args[2]), xml1.status()), colour=cfg.xml1_colour) displayText(frame, "{}: {}".format(os.path.basename(args[3]), xml2.status()), colour=cfg.xml2_colour) # export or navigate if 'export' in args: sys.stdout.write("{}/{}\r".format(vid.at(), cropped_total)) sys.stdout.flush() out_vid.write(frame) if vid.next(): xml1.next() xml2.next() else: print "\nend of video" break else: cv2.imshow(window_name, frame) key = cv2.waitKey(0) # controls if key == Key.esc: print "\nexiting." break elif key == Key.right: if vid.next(): xml1.next() xml2.next() elif key == Key.left: if vid.back(): xml1.back() xml2.back() # clean up vid.release() if 'export' in args: out_vid.release() else: cv2.destroyAllWindows() return 0
def main(sysargs): args = EasyArgs(sysargs) cfg = EasyConfig(args.config, group="evaluate") window_name = "EagleEye Evaluation Tool" if "help" in args: usage() return 0 # check output path if len(args) < 4: usage() return 1 path = args[3] # grab marks from args if len(args) > 5: mark_in = args[4] mark_out = args[5] # test integer-ness try: int(mark_in) and int(mark_out) except: print "Invalid marks" usage() return 1 else: print "marks are required!" usage() return 1 # open input files mapper_xml = Xmlset(args[1], readmode="mapper") annotated_xml = Xmlset(args[2], readmode="annotated") # status print "Evaluating Mapper: {} | Annoated: {}".format(os.path.basename(args[1]), os.path.basename(args[2])) print "" if mapper_xml.total != annotated_xml.total: print "Warning: Mismatched size of Mapper and Annotated: Mapper: {} | Annotated: {}".format(mapper_xml.total, annotated_xml.total) # Compare frames, start from the frame after 1st flash frameStart = mark_in +1 frameEnd = mark_out -1 # list of compared frames for export compare_frames = {} # vars for plots obj_plotdata = {} # id should be based on object, then frame number and its projection error print "Number of frames to compare {} | From Frame no. {} - {}".format((frameEnd) - (frameStart) + 1, frameStart, frameEnd) for f in range(mark_in+1, mark_out): sys.stdout.write("Reading Mapper Frame: {}".format(f) + " | XML Frame number: {}\r".format(f)) sys.stdout.flush() # check if frame exists in xml, if not skip to next if mapper_xml.data(f) is None: continue if annotated_xml.data(f) is None: continue mapper_data = mapper_xml.data(f) annotated_data = annotated_xml.data(f) # initialise frame compare_frames[f] = {} for obj in mapper_data.keys(): if obj not in obj_plotdata.keys(): obj_plotdata[obj] = {} # initialise obj in dictionary if obj in annotated_data.keys(): # check sides if mapper_data[obj]["lens"] == mapper_data[obj]["lens"]: mapper_x = int(float(mapper_data[obj]["centre"]["x"])) mapper_y = int(float(mapper_data[obj]["centre"]["y"])) annotated_x = int(float(annotated_data[obj]["centre"]["x"])) annotated_y = int(float(annotated_data[obj]["centre"]["y"])) mapper_centroid = (mapper_x, mapper_y) annotated_centroid = (annotated_x, annotated_y) reproj_err = calReprojError(mapper_centroid, annotated_centroid) # for export compare_frames[f][obj] = {} # initialise compared object compare_frames[f][obj]["lens"] = mapper_data[obj]["lens"] compare_frames[f][obj]["map_x"] = mapper_x compare_frames[f][obj]["map_y"] = mapper_y compare_frames[f][obj]["ann_x"] = annotated_x compare_frames[f][obj]["ann_y"] = annotated_y compare_frames[f][obj]["err"] = float(reproj_err) obj_plotdata[obj].update({f: reproj_err}) print "\n\nFound {} frames with matched objects".format(len(compare_frames)) print "Mean Error (Full Set): {} \n".format(calMean(compare_frames)) if path != "": if path.find(".xml") is not -1: print "\nOutputing comparion in xml to {}".format(path) writeXML(compare_frames, path, args) elif cfg.outputformat == "csv": path = path.replace(".xml",".csv") print "Outputing comparison in csv to {}".format(path) writeCSV(compare_frames, path) else: print "\nUnkown file format, please specify file extension as .xml or .csv" else: print "\nNo output path has been specified" # plot! if cfg.plot: print "\nPlotting frame by frame comparison..." plot("Difference between Annotated Centroid and Mapped Centroid (Ground Truth) \n {}".format(os.path.basename(path)), dict_data=obj_plotdata)
def main(sysargs): args = EasyArgs(sysargs) cfg = EasyConfig(args.cfg, group="compare") window_name = "EagleEye Comparator" if "help" in args: usage() return 0 # grab marks from args if len(args) > 5: mark_in = args[4] mark_out = args[5] # test integer-ness try: int(mark_in) and int(mark_out) except: usage() return 1 # or grab them from a marker tool elif len(args) > 3: ret, mark_in, mark_out = marker_tool(args[1], 50, window_name) if not ret: print "Not processing - exiting." return 1 else: usage() return 1 # open video files vid = BuffSplitCap(args[1], buff_max=cfg.buffer_size) xml1 = Xmlset(args[2]) xml2 = Xmlset(args[3]) # trim the video vid.restrict(mark_in, mark_out) # trim the CSV cropped_total = mark_out - mark_in xml1.setRatio(cropped_total) xml2.setRatio(cropped_total) # should be 1.0 (total frames should be the same as video) print 'xml1 ratio:', xml1.ratio() print 'xml2 ratio:', xml2.ratio() # open export (if specified) if 'export' in args: in_fps = vid.get(cv2.CAP_PROP_FPS) in_size = (int(vid.get(cv2.CAP_PROP_FRAME_WIDTH)), int(vid.get(cv2.CAP_PROP_FRAME_HEIGHT))) out_vid = cv2.VideoWriter(args.export, cv2.VideoWriter_fourcc(*cfg.fourcc), in_fps, in_size) else: cv2.namedWindow(window_name) while vid.isOpened(): sys.stdout.write(vid.status() + "\r") sys.stdout.flush() frame = vid.frame() # draw objects from each dataset for name in xml1.data(): draw(frame, xml1.data()[name], cfg.xml1_colour) for name in xml2.data(): draw(frame, xml2.data()[name], cfg.xml2_colour) # print status to screen displayText(frame, vid.status(), top=True) displayText(frame, "{}: {}".format(os.path.basename(args[2]), xml1.status()), colour=cfg.xml1_colour) displayText(frame, "{}: {}".format(os.path.basename(args[3]), xml2.status()), colour=cfg.xml2_colour) # export or navigate if 'export' in args: sys.stdout.write("{}/{}\r".format(vid.at(), cropped_total)) sys.stdout.flush() out_vid.write(frame) if vid.next(): xml1.next() xml2.next() else: print "\nend of video" break else: cv2.imshow(window_name, frame) key = cv2.waitKey(0) # controls if key == Key.esc: print "\nexiting." break elif key == Key.right: if vid.next(): xml1.next() xml2.next() elif key == Key.left: if vid.back(): xml1.back() xml2.back() # clean up vid.release() if 'export' in args: out_vid.release() else: cv2.destroyAllWindows() return 0
def main(sysargs): args = EasyArgs(sysargs) cfg = EasyConfig(args.cfg, group="compare_trainer") window_name = "EagleEye Comparator" if "help" in args: usage() return 0 # grab marks from args if len(args) > 5: mark_in = args[4] mark_out = args[5] # test integer-ness try: int(mark_in) and int(mark_out) except: usage() return 1 # or grab them from a marker tool elif len(args) > 3: ret, mark_in, mark_out = marker_tool(args[1], 50, window_name) if not ret: print "Not processing - exiting." return 1 else: usage() return 1 # determine sides side = Theta.resolve(args.side or 'buttonside') # open inouts files vid = BuffSplitCap(args[1], buff_max=cfg.buffer_size, side=Theta.Both) mapper_xml = Xmlset(args[2], offset=cfg.offset, offmode=Xmlset.offset_mode(cfg.offset_mode)) trainer_xml = Xmltrainer(args[3], side=side) reprojerror_list = {} # list of reprojection error of all frames lastframe = False # reject mapper_xml if it doesn't contain the trainer_target if cfg.trainer_target not in mapper_xml.data(0): print "Mapping file must contain training target:", cfg.trainer_target print "Target names in mapping file:", mapper_xml.data(0) print "Please specifiy correct target name in config" return 1 # also reject if it's lens data doesn't match the trainer_xml _test_lens = mapper_xml.data(0)[cfg.trainer_target]['lens'] if (_test_lens == Theta.NonDual and side != Theta.NonDual) \ or (side != Theta.NonDual and _test_lens == Theta.NonDual): print "Mapping file doesn't match training file" print "map:", Theta.name(_test_lens), "trainer:", Theta.name(side) return 1 # sync the video and xml vid.restrict(mark_in, mark_out) cropped_total = mark_out - mark_in mapper_xml.setRatio(cropped_total) # status print "ratio at:", mapper_xml.ratio() print "offset by:", cfg.offset, "in", cfg.offset_mode, "mode" print "" # open export (if specified) if args.video_export: in_fps = vid.get(cv2.CAP_PROP_FPS) in_size = (int(vid.get(cv2.CAP_PROP_FRAME_WIDTH)), int(vid.get(cv2.CAP_PROP_FRAME_HEIGHT))) out_vid = cv2.VideoWriter(args.video_export, cv2.VideoWriter_fourcc(*cfg.fourcc), in_fps, vid.shape[:2]) print "exporting to:", args.video_export else: cv2.namedWindow(window_name) print "interactive mode" # main loop while vid.isOpened(): frame = vid.frame() reprojerror_list = compareReproj(frame, vid.at(), mapper_xml, trainer_xml, reprojerror_list, cfg) # export or navigate if args.video_export: sys.stdout.write("Reading Video Frame: {} / {}\r".format( vid.at(), mark_out)) sys.stdout.flush() out_vid.write(frame) if vid.next(): reprojerror_list = compareReproj(frame, vid.at(), mapper_xml, trainer_xml, reprojerror_list, cfg) mapper_xml.next() else: calReprojList(reprojerror_list) print "\nend of video" break else: cv2.imshow(window_name, frame) key = cv2.waitKey(0) showAll = False # toggle to show all training points in one frame # controls if key == Key.esc: print "\nexiting." break elif key == Key.right: if vid.next(): mapper_xml.next() else: if lastframe is False: print "\nEnd of video" calReprojList(reprojerror_list) lastframe = True elif key == Key.left: if vid.back(): mapper_xml.back() elif key == Key.enter: while True: reprojerror_list = compareReproj(frame, vid.at(), mapper_xml, trainer_xml, reprojerror_list, cfg) cv2.imshow(window_name, frame) if vid.next(): mapper_xml.next() frame = vid.frame() # break when over else: break calReprojList(reprojerror_list) print "\nFast forwarded to end of video" if args.compare_export: print "Output to file" writeFile(args.compare_export, reprojerror_list) break elif key == Key.space: ''' TODO: display all training points, may be abandoned problems: frame is not refreshed after imshow if showAll is False: displayTrainPts(frame, mark_in, mark_out, trainer_xml, cfg) # #except: # print "Error in displaying training points. Exiting..." # return 1 # showAll = True else: frame, reprojerror_list = compareReproj(frame, vid.at(), mapper_xml, trainer_xml, reprojerror_list, cfg) showAll = False ''' pass # clean up vid.release() if args.video_export: out_vid.release() else: cv2.destroyAllWindows() return 0