Ejemplo n.º 1
0
def main(sysargs):
    args = EasyArgs(sysargs)
    cfg = EasyConfig(args.config, group="chessboard_extract")

    if "help" in args:
        usage()
        return 0

    # test args
    if len(args) <= 2:
        usage()
        return 1

    # video settings, etc
    window_name = "Chessboard Extractor"
    side = Theta.resolve(args.split)
    rotate = BuffSplitCap.r0
    crop = (0, 0, 0, 0)
    font = cv2.FONT_HERSHEY_SIMPLEX

    # image stuff
    image_path = os.path.join(args[2], args.prefix or 'frame_')
    if not os.path.exists(args[2]):
        os.makedirs(args[2])

    cv2.namedWindow(window_name)
    cap = BuffSplitCap(args[1],
                       side=side,
                       rotate=rotate,
                       crop=crop,
                       buff_max=cfg.buffer_size)

    # loop video file
    while cap.isOpened():
        frame = cap.frame()

        # display status
        textframe = frame.copy()
        displayText(textframe, cap.status(), top=True)
        cv2.imshow(window_name, textframe)

        # controls
        key = cv2.waitKey(0)
        if key == Key.right:
            cap.next()
        elif key == Key.left:
            cap.back()
        elif key == Key.enter:
            print "Snapped at: ", cap.at()
            cv2.imwrite("{}{:02d}.jpg".format(image_path, cap.at()), frame)
        elif key == Key.esc:
            print "Quitting."
            break

    # clean up
    cap.release()
    cv2.destroyAllWindows()

    print "\nDone."
    return 0
Ejemplo n.º 2
0
def main(sysargs):
    args = EasyArgs(sysargs)
    cfg = EasyConfig(args.config, group="chessboard_extract")
    
    if "help" in args:
        usage()
        return 0
    
    # test args
    if len(args) <= 2:
        usage()
        return 1
    
    # video settings, etc
    window_name = "Chessboard Extractor"
    side = Theta.resolve(args.split)
    rotate = BuffSplitCap.r0
    crop = (0,0,0,0)
    font = cv2.FONT_HERSHEY_SIMPLEX

    # image stuff
    image_path = os.path.join(args[2], args.prefix or 'frame_')
    if not os.path.exists(args[2]):
        os.makedirs(args[2])

    cv2.namedWindow(window_name)
    cap = BuffSplitCap(args[1], side=side, rotate=rotate, crop=crop, buff_max=cfg.buffer_size)

    # loop video file
    while cap.isOpened():
        frame = cap.frame()
        
        # display status
        textframe = frame.copy()
        displayText(textframe, cap.status(), top=True)
        cv2.imshow(window_name, textframe)
        
        # controls
        key = cv2.waitKey(0)
        if key == Key.right:
            cap.next()
        elif key == Key.left:
            cap.back()
        elif key == Key.enter:
            print "Snapped at: ", cap.at()
            cv2.imwrite("{}{:02d}.jpg".format(image_path, cap.at()), frame)
        elif key == Key.esc:
            print "Quitting."
            break

    # clean up
    cap.release()
    cv2.destroyAllWindows()

    print "\nDone."
    return 0
Ejemplo n.º 3
0
def writeCSV(frames, path):
    with open(path, "wb") as csvFile:
        c = csv.writer(csvFile)
        for f in frames.keys():
            for key in frames[f]:
                c.writerow([f,                              # frame number
                            frames[f][key]["map_x"],        # mapped centroid x
                            frames[f][key]["map_y"],        # mapped centroid y
                            frames[f][key]["ann_x"],        # annotated centroid x
                            frames[f][key]["ann_y"],        # annotated centroid y
                 Theta.name(frames[f][key]["lens"]),        # lens - {buttonside, backside, both}
                            frames[f][key]["err"]])         # reprojection error
Ejemplo n.º 4
0
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)
Ejemplo n.º 5
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")

        # 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
Ejemplo n.º 6
0
def main(sysargs):
    args = EasyArgs(sysargs)
    global scale, img_h

    if 'help' in args:
        usage()
        return 0

    # arg sanity checks
    if len(args) < 3:
        usage()
        return 1

    # default args
    height = args.height or 3000  # milimetres
    width = args.width or 8000  # milimetres
    max_height = args.max_height or 400  # pixels
    cfg = EasyConfig(args.config, group="mapper")

    # working vars
    scale = float(max_height) / height
    img_h = int(height * scale)
    img_w = int(width * scale)

    # open window
    window_name = "Tracer"
    cv2.namedWindow(window_name)

    # settings
    font = cv2.FONT_HERSHEY_SIMPLEX
    text_size = 0.5
    colour = (255, 255, 255)

    # a frame to paste the trace on
    baseframe = np.zeros((img_h, img_w, 3), np.uint8)

    # load appropriate mappers
    if not args.singlemode:
        mappers = [
            Mapper(args[1], args[2], cfg, Theta.Buttonside),
            Mapper(args[1], args[2], cfg, Theta.Backside)
        ]
    else:
        mappers = [Mapper(args[1], args[2], cfg, Theta.NonDual)]

    for m in mappers:
        colour = (55 + random.random() * 200, 55 + random.random() * 200,
                  55 + random.random() * 200)

        # calculate world camera pos
        Rt = np.matrix(m.R).T
        tv = -Rt.dot(np.matrix(m.tv))
        dir = unit(cv2.Rodrigues(-Rt)[0])
        #dir = unit(-Rt.dot(np.array([[0.], [0.], [1.]])))

        unvis = 0
        pts = m.obj_pts

        for i in pts:
            # draw circle around it if not-visible
            x, y, z = i
            p = (int(x * scale), img_h - int(y * scale))
            cv2.circle(baseframe, p, 1, colour, 2)

            # circle the point if not visible
            if not m.isVisible((x, y, z)):
                unvis += 1
                cv2.circle(baseframe, p, 6, colour, 1)

        x, y, z = tv
        pt1 = (int(x * scale), img_h - int(y * scale))
        cv2.circle(baseframe, pt1, 1, colour, 2)
        cv2.circle(baseframe, pt1, 10, colour, 1)

        # draw direction of lens
        #draw_arrow(baseframe, tv, dir[0], colour)
        # and it's FOV
        #draw_arrow(baseframe, tv, dir.dot(m.half_fov), colour, length=375)
        #draw_arrow(baseframe, tv, dir.dot(-m.half_fov), colour, length=375)

        # and some text data stuff
        displayText(baseframe,
                    "{}: {}, {}, {}".format(Theta.name(m.mode), *tv),
                    colour=colour)
        displayText(baseframe,
                    " visible: {}/{}".format(len(pts) - unvis, len(pts)),
                    endl=True,
                    colour=colour)

    # clean up
    cv2.imshow(window_name, baseframe)
    cv2.waitKey(0)

    if args.export:
        cv2.imwrite(args.export, baseframe)

    cv2.destroyAllWindows()

    print "\ndone"
    return 0
Ejemplo n.º 7
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
Ejemplo n.º 8
0
def compareReproj(cvframe, vidframe_no, mapper_xml, trainer_xml, reprojerror_list, cfg):
    
    xmlframe_no = mapper_xml.at()
    sys.stdout.write("Reading Video Frame: {}".format(vidframe_no) + " | XML Frame number: {}\r".format(xmlframe_no))
    sys.stdout.flush()
    
    mapped_object = mapper_xml.data(xmlframe_no)[cfg.trainer_target]
    
    # Prepare Repojected Point
    pt1 = (int(float(mapped_object['box']['x'])), 
            int(float(mapped_object['box']['y'])))
    
    pt2 = (pt1[0] + int(float(mapped_object['box']['width'])), 
            pt1[1] + int(float(mapped_object['box']['height'])))
    
    centre = (int(float(mapped_object['centre']['x'])), 
                int(float(mapped_object['centre']['y'])))
    
    visible = int(mapped_object['visibility']['visible'])
    max_visible =  int(mapped_object['visibility']['visibleMax'])
    lens_side = mapped_object['lens']
    
    # Render Reprojected Point
    cv2.rectangle(cvframe, pt1, pt2, cfg.mapper_colour, 1)
    cv2.circle(cvframe, centre, 1, cfg.mapper_colour, 2)
    
    # Get trainer point if it exists at current frame
    vicon_txt = "VICON - x: ?, y: ?, z: ?"
    trainer_txt = "Trained Point: x: ?, y: ?"
    reprojErr_txt = "Reprojection Error: No Data"
    
    if vidframe_no in trainer_xml.data() and lens_side == trainer_xml.side:
        trainer_frame = trainer_xml.data()[vidframe_no]
        
        # fix buttonside trainer points
        rightside_offset = 960 if trainer_xml.side == Theta.Right else 0
        
        vicon_txt = "VICON - x: {:.4f}, y: {:.4f}, z: {:.4f}".format(
                            float(trainer_frame["vicon"]["x"]),
                            float(trainer_frame["vicon"]["y"]),
                            float(trainer_frame["vicon"]["z"]))
        trainer_txt = "Trained Point: x: {}, y: {}".format(
                            int(float(trainer_frame["plane"]["x"]) + rightside_offset),
                            int(float(trainer_frame["plane"]["y"])))
        
        # visualise trainer point
        trainer_pt = (int(float(trainer_frame["plane"]["x"]) + rightside_offset),
                        int(float(trainer_frame["plane"]["y"])))
        cv2.circle(cvframe, trainer_pt, 1, cfg.trainer_colour, 2)

        # Calculate Reprojection Error at this frame
        # Still display bad data reprojection error but not used in calculation of mean
        reprojErr = calReprojError(centre, trainer_pt)
        reprojErr_txt = "Reprojection Error: {} pixels".format(str(reprojErr))
        
        if cfg.ignore_baddata:
            if visible >= cfg.min_reflectors:
                reprojerror_list.update({vidframe_no: {
                                            "rms": reprojErr,
                                            "x1": trainer_pt[0],
                                            "y1": trainer_pt[1],
                                            "x2": pt1[0],
                                            "y2": pt1[1]}})
    
    # Display Object Info
    frameObj_Txt = "Frame: {} | Trained Object: {} | Comparing: {}".format(
                        vidframe_no, cfg.trainer_target, Theta.name(trainer_xml.side))
    reprojCentroid_txt = "Reprojected Centroid - x: {}, y: {}, on: {}".format(
                                                    centre[0], centre[1], Theta.name(lens_side))
    visibility_txt = "Visible: {} , Max Visible: {}".format(visible, max_visible)
    
    displayText(cvframe, frameObj_Txt, top=True)
    displayText(cvframe, reprojCentroid_txt)
    displayText(cvframe, visibility_txt)
    
    dataText = " - Good data!!"
    dataText_colour = (0, 255, 0) # green
    if visible < cfg.min_reflectors:           # for when there isn't a matching trainer
        dataText = " - Bad data!!"
        dataText_colour = (0, 0, 255) # red
        if cfg.ignore_baddata:
            dataText += " Ignored."
    
    displayText(cvframe, dataText, endl=True, colour=dataText_colour)
    displayText(cvframe, trainer_txt)
    displayText(cvframe, vicon_txt)
    displayText(cvframe, reprojErr_txt)
    
    return reprojerror_list
Ejemplo n.º 9
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
Ejemplo n.º 10
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
Ejemplo n.º 11
0
def compareReproj(cvframe, vidframe_no, mapper_xml, trainer_xml,
                  reprojerror_list, cfg):

    xmlframe_no = mapper_xml.at()
    sys.stdout.write("Reading Video Frame: {}".format(vidframe_no) +
                     " | XML Frame number: {}\r".format(xmlframe_no))
    sys.stdout.flush()

    mapped_object = mapper_xml.data(xmlframe_no)[cfg.trainer_target]

    # Prepare Repojected Point
    pt1 = (int(float(mapped_object['box']['x'])),
           int(float(mapped_object['box']['y'])))

    pt2 = (pt1[0] + int(float(mapped_object['box']['width'])),
           pt1[1] + int(float(mapped_object['box']['height'])))

    centre = (int(float(mapped_object['centre']['x'])),
              int(float(mapped_object['centre']['y'])))

    visible = int(mapped_object['visibility']['visible'])
    max_visible = int(mapped_object['visibility']['visibleMax'])
    lens_side = mapped_object['lens']

    # Render Reprojected Point
    cv2.rectangle(cvframe, pt1, pt2, cfg.mapper_colour, 1)
    cv2.circle(cvframe, centre, 1, cfg.mapper_colour, 2)

    # Get trainer point if it exists at current frame
    vicon_txt = "VICON - x: ?, y: ?, z: ?"
    trainer_txt = "Trained Point: x: ?, y: ?"
    reprojErr_txt = "Reprojection Error: No Data"

    if vidframe_no in trainer_xml.data() and lens_side == trainer_xml.side:
        trainer_frame = trainer_xml.data()[vidframe_no]

        # fix buttonside trainer points
        rightside_offset = 960 if trainer_xml.side == Theta.Right else 0

        vicon_txt = "VICON - x: {:.4f}, y: {:.4f}, z: {:.4f}".format(
            float(trainer_frame["vicon"]["x"]),
            float(trainer_frame["vicon"]["y"]),
            float(trainer_frame["vicon"]["z"]))
        trainer_txt = "Trained Point: x: {}, y: {}".format(
            int(float(trainer_frame["plane"]["x"]) + rightside_offset),
            int(float(trainer_frame["plane"]["y"])))

        # visualise trainer point
        trainer_pt = (
            int(float(trainer_frame["plane"]["x"]) + rightside_offset),
            int(float(trainer_frame["plane"]["y"])))
        cv2.circle(cvframe, trainer_pt, 1, cfg.trainer_colour, 2)

        # Calculate Reprojection Error at this frame
        # Still display bad data reprojection error but not used in calculation of mean
        reprojErr = calReprojError(centre, trainer_pt)
        reprojErr_txt = "Reprojection Error: {} pixels".format(str(reprojErr))

        if cfg.ignore_baddata:
            if visible >= cfg.min_reflectors:
                reprojerror_list.update({
                    vidframe_no: {
                        "rms": reprojErr,
                        "x1": trainer_pt[0],
                        "y1": trainer_pt[1],
                        "x2": pt1[0],
                        "y2": pt1[1]
                    }
                })

    # Display Object Info
    frameObj_Txt = "Frame: {} | Trained Object: {} | Comparing: {}".format(
        vidframe_no, cfg.trainer_target, Theta.name(trainer_xml.side))
    reprojCentroid_txt = "Reprojected Centroid - x: {}, y: {}, on: {}".format(
        centre[0], centre[1], Theta.name(lens_side))
    visibility_txt = "Visible: {} , Max Visible: {}".format(
        visible, max_visible)

    displayText(cvframe, frameObj_Txt, top=True)
    displayText(cvframe, reprojCentroid_txt)
    displayText(cvframe, visibility_txt)

    dataText = " - Good data!!"
    dataText_colour = (0, 255, 0)  # green
    if visible < cfg.min_reflectors:  # for when there isn't a matching trainer
        dataText = " - Bad data!!"
        dataText_colour = (0, 0, 255)  # red
        if cfg.ignore_baddata:
            dataText += " Ignored."

    displayText(cvframe, dataText, endl=True, colour=dataText_colour)
    displayText(cvframe, trainer_txt)
    displayText(cvframe, vicon_txt)
    displayText(cvframe, reprojErr_txt)

    return reprojerror_list
Ejemplo n.º 12
0
def main(sysargs):
    args = EasyArgs(sysargs)
    global scale, img_h
    
    if 'help' in args:
        usage()
        return 0
    
    # arg sanity checks
    if len(args) < 3:
        usage()
        return 1
    
    # default args
    height = args.height or 3000        # milimetres
    width = args.width or 8000          # milimetres
    max_height = args.max_height or 400  # pixels
    cfg = EasyConfig(args.config, group="mapper")
    
    # working vars
    scale = float(max_height) / height
    img_h = int(height * scale)
    img_w = int(width * scale)
    
    # open window
    window_name = "Tracer"
    cv2.namedWindow(window_name)
    
    # settings
    font = cv2.FONT_HERSHEY_SIMPLEX
    text_size = 0.5
    colour = (255,255,255)
    
    # a frame to paste the trace on
    baseframe = np.zeros((img_h,img_w,3), np.uint8)
    
    # load appropriate mappers
    if not args.singlemode:
        mappers = [Mapper(args[1], args[2], cfg, Theta.Buttonside),
                   Mapper(args[1], args[2], cfg, Theta.Backside)]
    else:
        mappers = [Mapper(args[1], args[2], cfg, Theta.NonDual)]

    for m in mappers:
        colour = (55+random.random()*200,
                  55+random.random()*200,
                  55+random.random()*200)
        
        # calculate world camera pos
        Rt = np.matrix(m.R).T
        tv = -Rt.dot(np.matrix(m.tv))
        dir = unit(cv2.Rodrigues(-Rt)[0])
        #dir = unit(-Rt.dot(np.array([[0.], [0.], [1.]])))
        
        unvis = 0
        pts = m.obj_pts
        
        for i in pts:
            # draw circle around it if not-visible
            x, y, z = i
            p = (int(x*scale), img_h-int(y*scale))
            cv2.circle(baseframe, p, 1, colour, 2)
            
            # circle the point if not visible
            if not m.isVisible((x,y,z)):
                unvis += 1
                cv2.circle(baseframe, p, 6, colour, 1)
        
        x, y, z = tv
        pt1 = (int(x*scale), img_h-int(y*scale))
        cv2.circle(baseframe, pt1, 1, colour, 2)
        cv2.circle(baseframe, pt1, 10, colour, 1)
        
        # draw direction of lens
        #draw_arrow(baseframe, tv, dir[0], colour)
        # and it's FOV
        #draw_arrow(baseframe, tv, dir.dot(m.half_fov), colour, length=375)
        #draw_arrow(baseframe, tv, dir.dot(-m.half_fov), colour, length=375)
        
        # and some text data stuff
        displayText(baseframe, "{}: {}, {}, {}".format(Theta.name(m.mode), *tv), colour=colour)
        displayText(baseframe, " visible: {}/{}".format(len(pts)-unvis, len(pts)), endl=True, colour=colour)

    # clean up
    cv2.imshow(window_name, baseframe)
    cv2.waitKey(0)

    if args.export:
        cv2.imwrite(args.export, baseframe)

    cv2.destroyAllWindows()

    print "\ndone"
    return 0