def intWriter(path, camMat, distCoe, calibError={}): try: print 'Generating Intrinsic Parameters to:', path, '...' with open(path, 'w') as int_xml: w = XMLWriter(int_xml) w.declaration() # Camera Intrinsic (Root) root = w.start('StdIntrinsic') # Camera Matrix w.element('CamMat', fx=str(camMat[0][0]), fy=str(camMat[1][1]), cx=str(camMat[0][2]), cy=str(camMat[1][2])) # Distortion Coefficients if (len(distCoe[0]) == 8): # 8 coefficients Rational Model, k4 k5 k6 enabled w.element('DistCoe', k1=str(distCoe[0][0]), k2=str(distCoe[0][1]), p1=str(distCoe[0][2]), p2=str(distCoe[0][3]), k3=str(distCoe[0][4]), k4=str(distCoe[0][5]), k5=str(distCoe[0][6]), k6=str(distCoe[0][7])) elif (len(distCoe[0]) == 12): # 12 coefficients Prism Model, c1, c2, c3, c4 enabled, new in OpenCV 3.0.0 w.element('DistCoe', k1=str(distCoe[0][0]), k2=str(distCoe[0][1]), p1=str(distCoe[0][2]), p2=str(distCoe[0][3]), k3=str(distCoe[0][4]), k4=str(distCoe[0][5]), k5=str(distCoe[0][6]), k6=str(distCoe[0][7]), c1=str(distCoe[0][8]), c2=str(distCoe[0][9]), c3=str(distCoe[0][10]),c4=str(distCoe[0][11])) else: w.element('DistCoe', k1=str(distCoe[0][0]), k2=str(distCoe[0][1]), p1=str(distCoe[0][2]), p2=str(distCoe[0][3]), k3=str(distCoe[0][4])) # Error values if len(calibError) > 0: w.element('Error', rms=str(calibError['rms']), total=str(calibError['tot_err']), arth=str(calibError['arth_err'])) w.close(root) print 'Intrinsic calibration has been generated successfully.' except Exception as e: print 'ERROR: occurred in writing intrinsic XML file.' raise e # keep it bubbling up, to catch in main()
def writeXML(frames, path, args): out_xml = XMLWriter(path) out_xml.declaration() doc = out_xml.start("AnnotationEvaluation") # source information out_xml.element("video", mark_in=str(args[4]), mark_out=str(args[5])) out_xml.element("mapper", os.path.basename(args[1])) out_xml.element("annotation", os.path.basename(args[2])) out_xml.element("comparison", mean_err=str(calMean(frames))) # compared points out_xml.start("frames", total=str((args[5]-1) - (args[4]+1)+1), compared=str(len(frames))) for f in frames.keys(): out_xml.start("frame", num=str(f)) for key in frames[f]: out_xml.start("object", lens=Theta.name(frames[f][key]["lens"]), name=key, err=str(frames[f][key]["err"])) out_xml.element("annotatedCentroid", x=str(frames[f][key]["ann_x"]), y=str(frames[f][key]["ann_y"])) out_xml.element("mappedCentroid", x=str(frames[f][key]["map_x"]), y=str(frames[f][key]["map_y"])) out_xml.end() # object out_xml.end() # frames # clean up out_xml.close(doc)
def main(sysargs): args = EasyArgs(sysargs) cfg = EasyConfig(args.config, group="mapper") if "help" in args: usage() return 0 if ["calib", "trainer", "output"] not in args: print "Must specify: -calib, -trainer, -output files" usage() return 1 if len(args) == 1: print "Not enough input CSV files" usage() return 1 if len(args) > 2 and args.map_trainer_mode: print "Too many CSV for trainer-mapping mode" usage() return 1 if "force_side" in args: side = Theta.resolve(args.force_side) if side == Theta.NonDual: print "Invalid force_side argument:", args.force_side usage() return 1 # set side overrides force_button = (side == Theta.Buttonside) force_back = not force_button else: force_button = force_back = False # working vars csvs = {} frame_num = 0 # open source CSV datasets for i in range(1, len(args)): print args[i] csvs[i] = Memset(args[i]) # reel all the files up to their first flash for i in csvs: csvs[i].restrict() if len(csvs[i].row()) < 10: print "CSV file:", args[i], "contains no marker data!\nAborting." return 1 # override csv name if args.map_trainer_mode: csvs[1]._name = cfg.trainer_target # open calib files try: buttonside = Mapper(args.calib, args.trainer, cfg, Theta.Buttonside) backside = Mapper(args.calib, args.trainer, cfg, Theta.Backside) except Exception as e: print e.message return 1 count = {'bts': 0, 'bks': 0, 'rej': 0} # open destination XML with open(args.output, "w") as xmlfile: w = XMLWriter(xmlfile) w.declaration() xmlfile.write( "<!DOCTYPE dataset SYSTEM \"http://storage.gwillz.com.au/eagleeye_v2.dtd\">" ) doc = w.start("dataset") # iterates until all vicon csvs reach eof while True: w.start("frameInformation") w.element("frame", number=str(frame_num)) #iterates through each vicon csv at the current row for i in csvs: c = csvs[i] # determine marker quality try: max_reflectors = int(c.row()[8]) visible_reflectors = int(c.row()[9]) except: print "Error in reading quality at row {}".format(i) return 1 try: # read VICON data x = float(c.row()[2]) y = float(c.row()[3]) z = float(c.row()[4]) # TODO: is this necessary? We never use the object's rotation rx = float(c.row()[5]) ry = float(c.row()[6]) rz = float(c.row()[7]) except: print "Error occurred when converting VICON data at row {}".format( i) return 1 # run projection/mapping on VICON data if backside.isVisible((x, y, z)): points = backside.reprojpts((x, y, z)) side = 'backside' count['bks'] += 1 elif buttonside.isVisible((x, y, z)): points = buttonside.reprojpts((x, y, z)) points[ 0] += 960 # add 960 to x for rightside points (Ricoh video is both frames side by side) side = 'buttonside' count['bts'] += 1 # TODO don't write non visible dots? else: points = [0., 0.] count['rej'] += 1 # TODO: Change DTD and double check with Manjung w.start("object", id=str(i), name=c.name(), lens=Theta.name(side)) w.element("boxinfo", height="99", width="99", x=str(points[0] - 50), y=str(points[1] - 50)) w.element("centroid", x=str(points[0]), y=str(points[1]), rx=str(rx), ry=str(ry), rz=str(rz)) w.element("visibility", visible=str(visible_reflectors), visibleMax=str(max_reflectors)) w.end() w.end() # test end of files eofs = 0 for i in csvs: if csvs[i].eof(): eofs += 1 if len(csvs) == eofs: print "end of all datasets" break # load next vicon frame frame_num += 1 for i in csvs: csvs[i].next() w.close(doc) print "\nbuttonside", count['bts'] print "backside", count['bks'] print "rejected", count['rej'] return 0
def intWriter(path, buttonside=None, backside=None): try: status = "" print 'Generating Intrinsic Parameters to:', path, '...' with open(path, 'w') as int_xml: w = XMLWriter(int_xml) w.declaration() # Camera Intrinsic (Root) root = w.start('dual_intrinsic') num_sides = range(0, 2) #num_sides = range(0, 1) if buttonside is None or backside is None else range(0, 2) for i in num_sides: w.start("Buttonside" if i == 0 else "Backside") if i == 0 and buttonside[0].size > 0 and buttonside[1].size > 0: status += 'Buttonside' camMat = buttonside[0] distCoe = buttonside[1] calibError = buttonside[2] elif i == 1 and backside[0].size > 0 and backside[1].size > 0: if status == "": status += 'Backside' else: status += ' & Backside' camMat = backside[0] distCoe = backside[1] calibError = backside[2] else: w.end() continue # Camera Matrix w.element('CamMat', fx=str(camMat[0][0]), fy=str(camMat[1][1]), cx=str(camMat[0][2]), cy=str(camMat[1][2])) # Distortion Coefficients if (len(distCoe[0]) == 8): # 8 coefficients Rational Model, k4 k5 k6 enabled w.element('DistCoe', k1=str(distCoe[0][0]), k2=str(distCoe[0][1]), p1=str(distCoe[0][2]), p2=str(distCoe[0][3]), k3=str(distCoe[0][4]), k4=str(distCoe[0][5]), k5=str(distCoe[0][6]), k6=str(distCoe[0][7])) elif (len(distCoe[0]) == 12): # 12 coefficients Prism Model, c1, c2, c3, c4 enabled, new in OpenCV 3.0.0 w.element('DistCoe', k1=str(distCoe[0][0]), k2=str(distCoe[0][1]), p1=str(distCoe[0][2]), p2=str(distCoe[0][3]), k3=str(distCoe[0][4]), k4=str(distCoe[0][5]), k5=str(distCoe[0][6]), k6=str(distCoe[0][7]), c1=str(distCoe[0][8]), c2=str(distCoe[0][9]), c3=str(distCoe[0][10]),c4=str(distCoe[0][11])) else: w.element('DistCoe', k1=str(distCoe[0][0]), k2=str(distCoe[0][1]), p1=str(distCoe[0][2]), p2=str(distCoe[0][3]), k3=str(distCoe[0][4])) # Error values if len(calibError) > 0: w.element('Error', rms=str(calibError['rms']), total=str(calibError['tot_err']), arth=str(calibError['arth_err'])) w.end() #buttonside/backside w.close(root) print status, 'Intrinsic calibration has been generated successfully.' except Exception as e: # keep it bubbling up, to catch in main() raise Exception("{}: {}\n'ERROR: occurred in writing intrinsic XML file.'".format(type(e), e.message))
#Write datastreams manifest to XML #example datastream chunk ''' <foxml:datastream CONTROL_GROUP="M" ID="ORIGINAL" STATE="A"> <foxml:datastreamVersion ID="ORIGINAL.0" MIMETYPE="image/jpeg" LABEL="Page#"> <foxml:contentLocation TYPE="URL"> <xsl:attribute name="REF">http://image.url/Sketches_and_scraps0000#.jpg</xsl:attribute> </foxml:contentLocation> </foxml:datastreamVersion> </foxml:datastream> ''' fhand = item_path + "/" + item_ID + "_FOXML.xml" w = XMLWriter(fhand, encoding="utf-8") w.declaration() #namespace dictionary namespace={} namespace['xmlns:foxml'] = "info:fedora/fedora-system:def/foxml#" namespace['xmlns:xsi']="http://www.w3.org/2001/XMLSchema-instance" manifest = w.start("ebook_item", namespace) # iterate through parent collections and create <collection> elements for each for collection_name in collections: w.element("collection", Template("$collection_name").substitute(collection_name=collection_name)) w.element("PID_prefix", Template("$PID_prefix").substitute(PID_prefix=PID_prefix)) w.element("book_title", Template("$item_ID").substitute(item_ID=item_ID)) w.element("item_ID", Template("$item_ID").substitute(item_ID=item_ID))
def main(sysargs): # settings args = EasyArgs(sysargs) cfg = EasyConfig(args.config, group="trainer") max_clicks = args.clicks or cfg.default_clicks window_name = "EagleEye Trainer" 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 elif len(args) > 3: ret, mark_in, mark_out = marker_tool(args[1], cfg.buffer_size, window_name) if not ret: print "Not processing - exiting." return 1 else: usage() return 1 ## clicking time! cropped_total = mark_out - mark_in print "video cropped at:", mark_in, "to", mark_out, "- ({} frames)".format(cropped_total) # clicking function def on_mouse(event, x, y, flags, params): # left click to mark if event == cv2.EVENT_LBUTTONDOWN: params['pos'] = (x, y) params['status'] = Status.record # right click to skip elif event == cv2.EVENT_RBUTTONDOWN: params['status'] = Status.skip # working variables params = {'status': Status.wait, 'pos': None} write_xml = False textstatus = "" dataQuality = 0 # 0 = good, >0 = bad/potentially bad # default right side (buttonside) if cfg.dual_mode: lens = Theta.Right trainer_points = {Theta.Right:{}, Theta.Left:{}} else: # both sides otherwise lens = Theta.Both trainer_points = {Theta.Both:{}} print "Minimum reflectors: {} | Ignore Negative xyz: {}".format(cfg.min_reflectors, cfg.check_negatives) # load video (again) in_vid = BuffSplitCap(args[1], crop=(0,0,0,0), rotate=BuffSplitCap.r0, buff_max=cfg.buffer_size) in_vid.restrict(mark_in, mark_out) # load csv (with appropriate ratio) in_csv = Memset(args[2]) in_csv.restrict() in_csv.setRatio(cropped_total) # test for marker data if len(in_csv.row()) < 10: print "This CSV contains no marker data!\nAborting." return 1 # status print "" print "Writing to:", args[3] print "Number of clicks at:", max_clicks print "" cv2.namedWindow(window_name) cv2.setMouseCallback(window_name, on_mouse, params) # grab clicks (Process 2) while in_vid.isOpened(): frame = in_vid.frame(side=lens) sys.stdout.write(in_vid.status() + " | Clicks {} / {}\r".format( len(trainer_points[lens]), max_clicks)) sys.stdout.flush() # prepare CSV data, click data tx = float(in_csv.row()[2]) ty = float(in_csv.row()[3]) tz = float(in_csv.row()[4]) rx = float(in_csv.row()[5]) ry = float(in_csv.row()[6]) rz = float(in_csv.row()[7]) # data quality status visible = int(in_csv.row()[9]) max_visible = int(in_csv.row()[8]) # status text to write textrow = "VICON - x: {:.4f} y: {:.4f} z: {:.4f} | rx: {:.4f} ry: {:.4f} rz: {:.4f}".format(tx, ty, tz, rx, ry, rz) textquality = "Visible: {} , Max Visible: {}".format(visible, max_visible) textstatus = "{} | {}/{} clicks".format(in_vid.status(), len(trainer_points[lens]), max_clicks) if lens == Theta.Left: textstatus += " - back side" elif lens == Theta.Right: textstatus += " - button side" #else none, no lens split # if data is qualified bad, reduce timeout by one if dataQuality > 0: dataQuality -= 1 if dataQuality == 0: dataStatus = " - Good data!!" dataStatus_colour = (0, 255, 0) # green else: dataStatus = " - Potentially bad data (wait {})".format(dataQuality) dataStatus_colour = (0, 255, 255) # yellow # Data tests # values must be above 0 and minimum reflectors if (cfg.check_negatives and (tx <= 0 or ty <= 0 or tz <= 0)) \ or visible < cfg.min_reflectors: dataStatus = " - Bad data!!" dataStatus_colour = (0, 0, 255) # red if cfg.ignore_baddata: dataStatus += " Ignored." dataQuality = 1 + cfg.quality_delay # draw the trainer dot (if applicable) if in_vid.at() in trainer_points[lens]: cv2.circle(frame, trainer_points[lens][in_vid.at()][0], 1, cfg.dot_colour, 2) cv2.circle(frame, trainer_points[lens][in_vid.at()][0], 15, cfg.dot_colour, 1) # draw text and show displayText(frame, textrow, top=True) displayText(frame, textquality) displayText(frame, textstatus) displayText(frame, dataStatus, endl=True, colour=dataStatus_colour) cv2.imshow(window_name, frame) # pause for input while params['status'] == Status.wait: key = cv2.waitKey(10) if key == Key.esc: params['status'] = Status.stop elif key == Key.enter: write_xml = True params['status'] = Status.stop elif key == Key.right: params['status'] = Status.skip elif key == Key.left: params['status'] = Status.back elif key == Key.backspace: params['status'] = Status.remove elif Key.char(key, '1') and cfg.dual_mode: params['status'] = Status.still lens = Theta.Left elif Key.char(key, '2') and cfg.dual_mode: params['status'] = Status.still lens = Theta.Right # catch exit status if params['status'] == Status.stop: print "\nprocess aborted!" break # write data if params['status'] == Status.record \ and len(trainer_points[lens]) != max_clicks: # TODO: does this disable recording clicks on the last frame if dataQuality == 0: trainer_points[lens][in_vid.at()] = (params['pos'], in_csv.row()[2:5], in_csv.row()[8:10]) params['status'] = Status.skip # or remove it elif params['status'] == Status.remove \ and in_vid.at() in trainer_points[lens]: del trainer_points[lens][in_vid.at()] print "\nremoved dot" # load next csv frame if params['status'] == Status.skip: if in_vid.next(): in_csv.next() else: write_xml = True print "\nend of video: {}/{}".format(in_vid.at() -1, mark_out -1) break # or load previous csv frame elif params['status'] == Status.back: if in_vid.back(): in_csv.back() # reset status params['status'] = Status.wait # clean up cv2.destroyAllWindows() ## write xml if write_xml: out_xml = XMLWriter(args[3]) out_xml.declaration() doc = out_xml.start("TrainingSet") # source information out_xml.start("video", mark_in=str(mark_in), mark_out=str(mark_out)) out_xml.data(os.path.basename(args[1])) out_xml.end() out_xml.element("csv", os.path.basename(args[2])) # training point data for lens in trainer_points: if lens == Theta.Right: out_xml.start("buttonside", points=str(len(trainer_points[lens]))) elif lens == Theta.Left: out_xml.start("backside", points=str(len(trainer_points[lens]))) else: # non dualmode out_xml.start("frames", points=str(len(trainer_points[lens]))) for i in trainer_points[lens]: pos, row, markers = trainer_points[lens][i] x, y = pos out_xml.start("frame", num=str(i)) out_xml.element("plane", x=str(x), y=str(y)) out_xml.element("vicon", x=str(row[0]), y=str(row[1]), z=str(row[2])) out_xml.element("visibility", visibleMax=str(markers[0]), visible=str(markers[1])) out_xml.end() out_xml.end() # frames # clean up out_xml.close(doc) print "Data was written." else: print "No data was written" print "\nDone." return 0
correction = ' '.join(nltk.word_tokenize(correction)) required = tokens[3] annotator = int(tokens[5]) annotators[s].add(annotator) if c_start == -1 and c_end == -1 and etype.lower() == "noop": # Noop --> empty set of edits (source is right) pass else: ref_annot[s].append([c_start, c_end, etype, correction, annotator]) f_in.close() # Create the output XML if not out_file: out_file = in_file + ".ieval.xml" f_out = XMLWriter(out_file, "UTF-8") f_out.declaration() f_out.start("scripts") f_out.start("script", id="1") # Assume only one script # Do clustering for s in xrange(len(ref_annot)): sys.stdout.write("\rSentence %s..." % (s+1)) sys.stdout.flush() clusters = [] # Sort edits from longest to shortest range ref_annot[s].sort(key=lambda x: x[0] - x[1]) for e in ref_annot[s]: # Go through each edit merge = False for c in clusters: if cluster_has_overlap(c, e):
def intWriter(path, camMat, distCoe, calibError={}): try: print 'Generating Intrinsic Parameters to:', path, '...' with open(path, 'w') as int_xml: w = XMLWriter(int_xml) w.declaration() # Camera Intrinsic (Root) root = w.start('StdIntrinsic') # Camera Matrix w.element('CamMat', fx=str(camMat[0][0]), fy=str(camMat[1][1]), cx=str(camMat[0][2]), cy=str(camMat[1][2])) # Distortion Coefficients if (len(distCoe[0]) == 8 ): # 8 coefficients Rational Model, k4 k5 k6 enabled w.element('DistCoe', k1=str(distCoe[0][0]), k2=str(distCoe[0][1]), p1=str(distCoe[0][2]), p2=str(distCoe[0][3]), k3=str(distCoe[0][4]), k4=str(distCoe[0][5]), k5=str(distCoe[0][6]), k6=str(distCoe[0][7])) elif ( len(distCoe[0]) == 12 ): # 12 coefficients Prism Model, c1, c2, c3, c4 enabled, new in OpenCV 3.0.0 w.element('DistCoe', k1=str(distCoe[0][0]), k2=str(distCoe[0][1]), p1=str(distCoe[0][2]), p2=str(distCoe[0][3]), k3=str(distCoe[0][4]), k4=str(distCoe[0][5]), k5=str(distCoe[0][6]), k6=str(distCoe[0][7]), c1=str(distCoe[0][8]), c2=str(distCoe[0][9]), c3=str(distCoe[0][10]), c4=str(distCoe[0][11])) else: w.element('DistCoe', k1=str(distCoe[0][0]), k2=str(distCoe[0][1]), p1=str(distCoe[0][2]), p2=str(distCoe[0][3]), k3=str(distCoe[0][4])) # Error values if len(calibError) > 0: w.element('Error', rms=str(calibError['rms']), total=str(calibError['tot_err']), arth=str(calibError['arth_err'])) w.close(root) print 'Intrinsic calibration has been generated successfully.' except Exception as e: print 'ERROR: occurred in writing intrinsic XML file.' raise e # keep it bubbling up, to catch in main()
def main(sysargs): # settings args = EasyArgs(sysargs) cfg = EasyConfig(args.config, group="trainer") max_clicks = args.clicks or cfg.default_clicks window_name = "EagleEye Trainer" 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 elif len(args) > 3: ret, mark_in, mark_out = marker_tool(args[1], cfg.buffer_size, window_name) if not ret: print "Not processing - exiting." return 1 else: usage() return 1 ## clicking time! cropped_total = mark_out - mark_in print "video cropped at:", mark_in, "to", mark_out, "- ({} frames)".format( cropped_total) # clicking function def on_mouse(event, x, y, flags, params): # left click to mark if event == cv2.EVENT_LBUTTONDOWN: params['pos'] = (x, y) params['status'] = Status.record # right click to skip elif event == cv2.EVENT_RBUTTONDOWN: params['status'] = Status.skip # working variables params = {'status': Status.wait, 'pos': None} write_xml = False textstatus = "" dataQuality = 0 # 0 = good, >0 = bad/potentially bad # default right side (buttonside) if cfg.dual_mode: lens = Theta.Right trainer_points = {Theta.Right: {}, Theta.Left: {}} else: # both sides otherwise lens = Theta.Both trainer_points = {Theta.Both: {}} print "Minimum reflectors: {} | Ignore Negative xyz: {}".format( cfg.min_reflectors, cfg.check_negatives) # load video (again) in_vid = BuffSplitCap(args[1], crop=(0, 0, 0, 0), rotate=BuffSplitCap.r0, buff_max=cfg.buffer_size) in_vid.restrict(mark_in, mark_out) # load csv (with appropriate ratio) in_csv = Memset(args[2]) in_csv.restrict() in_csv.setRatio(cropped_total) # test for marker data if len(in_csv.row()) < 10: print "This CSV contains no marker data!\nAborting." return 1 # status print "" print "Writing to:", args[3] print "Number of clicks at:", max_clicks print "" cv2.namedWindow(window_name) cv2.setMouseCallback(window_name, on_mouse, params) # grab clicks (Process 2) while in_vid.isOpened(): frame = in_vid.frame(side=lens) sys.stdout.write(in_vid.status() + " | Clicks {} / {}\r".format( len(trainer_points[lens]), max_clicks)) sys.stdout.flush() # prepare CSV data, click data tx = float(in_csv.row()[2]) ty = float(in_csv.row()[3]) tz = float(in_csv.row()[4]) rx = float(in_csv.row()[5]) ry = float(in_csv.row()[6]) rz = float(in_csv.row()[7]) # data quality status visible = int(in_csv.row()[9]) max_visible = int(in_csv.row()[8]) # status text to write textrow = "VICON - x: {:.4f} y: {:.4f} z: {:.4f} | rx: {:.4f} ry: {:.4f} rz: {:.4f}".format( tx, ty, tz, rx, ry, rz) textquality = "Visible: {} , Max Visible: {}".format( visible, max_visible) textstatus = "{} | {}/{} clicks".format(in_vid.status(), len(trainer_points[lens]), max_clicks) if lens == Theta.Left: textstatus += " - back side" elif lens == Theta.Right: textstatus += " - button side" #else none, no lens split # if data is qualified bad, reduce timeout by one if dataQuality > 0: dataQuality -= 1 if dataQuality == 0: dataStatus = " - Good data!!" dataStatus_colour = (0, 255, 0) # green else: dataStatus = " - Potentially bad data (wait {})".format( dataQuality) dataStatus_colour = (0, 255, 255) # yellow # Data tests # values must be above 0 and minimum reflectors if (cfg.check_negatives and (tx <= 0 or ty <= 0 or tz <= 0)) \ or visible < cfg.min_reflectors: dataStatus = " - Bad data!!" dataStatus_colour = (0, 0, 255) # red if cfg.ignore_baddata: dataStatus += " Ignored." dataQuality = 1 + cfg.quality_delay # draw the trainer dot (if applicable) if in_vid.at() in trainer_points[lens]: cv2.circle(frame, trainer_points[lens][in_vid.at()][0], 1, cfg.dot_colour, 2) cv2.circle(frame, trainer_points[lens][in_vid.at()][0], 15, cfg.dot_colour, 1) # draw text and show displayText(frame, textrow, top=True) displayText(frame, textquality) displayText(frame, textstatus) displayText(frame, dataStatus, endl=True, colour=dataStatus_colour) cv2.imshow(window_name, frame) # pause for input while params['status'] == Status.wait: key = cv2.waitKey(10) if key == Key.esc: params['status'] = Status.stop elif key == Key.enter: write_xml = True params['status'] = Status.stop elif key == Key.right: params['status'] = Status.skip elif key == Key.left: params['status'] = Status.back elif key == Key.backspace: params['status'] = Status.remove elif Key.char(key, '1') and cfg.dual_mode: params['status'] = Status.still lens = Theta.Left elif Key.char(key, '2') and cfg.dual_mode: params['status'] = Status.still lens = Theta.Right # catch exit status if params['status'] == Status.stop: print "\nprocess aborted!" break # write data if params['status'] == Status.record \ and len(trainer_points[lens]) != max_clicks: # TODO: does this disable recording clicks on the last frame if dataQuality == 0: trainer_points[lens][in_vid.at()] = (params['pos'], in_csv.row()[2:5], in_csv.row()[8:10]) params['status'] = Status.skip # or remove it elif params['status'] == Status.remove \ and in_vid.at() in trainer_points[lens]: del trainer_points[lens][in_vid.at()] print "\nremoved dot" # load next csv frame if params['status'] == Status.skip: if in_vid.next(): in_csv.next() else: write_xml = True print "\nend of video: {}/{}".format(in_vid.at() - 1, mark_out - 1) break # or load previous csv frame elif params['status'] == Status.back: if in_vid.back(): in_csv.back() # reset status params['status'] = Status.wait # clean up cv2.destroyAllWindows() ## write xml if write_xml: out_xml = XMLWriter(args[3]) out_xml.declaration() doc = out_xml.start("TrainingSet") # source information out_xml.start("video", mark_in=str(mark_in), mark_out=str(mark_out)) out_xml.data(os.path.basename(args[1])) out_xml.end() out_xml.element("csv", os.path.basename(args[2])) # training point data for lens in trainer_points: if lens == Theta.Right: out_xml.start("buttonside", points=str(len(trainer_points[lens]))) elif lens == Theta.Left: out_xml.start("backside", points=str(len(trainer_points[lens]))) else: # non dualmode out_xml.start("frames", points=str(len(trainer_points[lens]))) for i in trainer_points[lens]: pos, row, markers = trainer_points[lens][i] x, y = pos out_xml.start("frame", num=str(i)) out_xml.element("plane", x=str(x), y=str(y)) out_xml.element("vicon", x=str(row[0]), y=str(row[1]), z=str(row[2])) out_xml.element("visibility", visibleMax=str(markers[0]), visible=str(markers[1])) out_xml.end() out_xml.end() # frames # clean up out_xml.close(doc) print "Data was written." else: print "No data was written" print "\nDone." return 0
def main(sysargs): args = EasyArgs(sysargs) cfg = EasyConfig(args.config, group="mapper") if "help" in args: usage() return 0 if ["calib", "trainer", "output"] not in args: print "Must specify: -calib, -trainer, -output files" usage() return 1 if len(args) == 1: print "Not enough input CSV files" usage() return 1 if len(args) > 2 and args.map_trainer_mode: print "Too many CSV for trainer-mapping mode" usage() return 1 if "force_side" in args: side = Theta.resolve(args.force_side) if side == Theta.NonDual: print "Invalid force_side argument:", args.force_side usage() return 1 # set side overrides force_button = (side == Theta.Buttonside) force_back = not force_button else: force_button = force_back = False # working vars csvs = {} frame_num = 0 # open source CSV datasets for i in range(1, len(args)): print args[i] csvs[i] = Memset(args[i]) # reel all the files up to their first flash for i in csvs: csvs[i].restrict() if len(csvs[i].row()) < 10: print "CSV file:", args[i], "contains no marker data!\nAborting." return 1 # override csv name if args.map_trainer_mode: csvs[1]._name = cfg.trainer_target # open calib files try: buttonside = Mapper(args.calib, args.trainer, cfg, Theta.Buttonside) backside = Mapper(args.calib, args.trainer, cfg, Theta.Backside) except Exception as e: print e.message return 1 count = {'bts':0, 'bks':0, 'rej':0} # open destination XML with open(args.output, "w") as xmlfile: w = XMLWriter(xmlfile) w.declaration() xmlfile.write("<!DOCTYPE dataset SYSTEM \"http://storage.gwillz.com.au/eagleeye_v2.dtd\">") doc = w.start("dataset") # main loop while True: w.start("frameInformation") w.element("frame", number=str(frame_num)) for i in csvs: c = csvs[i] # determine marker quality try: max_reflectors = int(c.row()[8]) visible_reflectors = int(c.row()[9]) except: print "Error in reading quality at row {}".format(i) return 1 try: # read VICON data x = float(c.row()[2]) y = float(c.row()[3]) z = float(c.row()[4]) # TODO: is this necessary? We never use the object's rotation rx = float(c.row()[5]) ry = float(c.row()[6]) rz = float(c.row()[7]) except: print "Error occurred when converting VICON data at row {}".format(i) return 1 # run projection/mapping on VICON data if backside.isVisible((x,y,z)): points = backside.reprojpts((x, y, z)) side = 'backside' count['bks'] += 1 elif buttonside.isVisible((x,y,z)): points = buttonside.reprojpts((x, y, z)) points[0] += 960 # add 960 to x for rightside points side = 'buttonside' count['bts'] += 1 # TODO don't write non visible dots? else: points = [0.,0.] count['rej'] += 1 # TODO: Change DTD and double check with Manjung w.start("object", id=str(i), name=c.name(), lens=Theta.name(side)) w.element("boxinfo", height="99", width="99", x=str(points[0]-50), y=str(points[1]-50)) w.element("centroid", x=str(points[0]), y=str(points[1]), rx=str(rx), ry=str(ry), rz=str(rz)) w.element("visibility", visible=str(visible_reflectors), visibleMax=str(max_reflectors)) w.end() w.end() # test end of files eofs = 0 for i in csvs: if csvs[i].eof(): eofs += 1 if len(csvs) == eofs: print "end of all datasets" break # load next frame frame_num += 1 for i in csvs: csvs[i].next() w.close(doc) print "\nbuttonside", count['bts'] print "backside", count['bks'] print "rejected", count['rej'] return 0