Ejemplo n.º 1
0
def savejob(id, data):
    job = session.query(Job).get(id)

    for path in job.paths:
        session.delete(path)
    for pi in job.predicate_instances:
        for pa in pi.predicate_annotations:
            session.delete(pa)
        session.delete(pi)
    for s in job.sentences:
        for sa in s.annotations:
            session.delete(sa)
        session.delete(s)
    session.commit()
    
    paths = readpaths(data["tracks"])
    for path in paths:
        job.paths.append(path)
    for pi in readpredicates(data["predicates"], paths):
        job.predicate_instances.append(pi)
    for s in readsentences(data['sentences']):
        job.sentences.append(s)
    
    session.add(job)
    session.commit()
Ejemplo n.º 2
0
def markcomplete(hitid, assignmentid, workerid):
    """
    Marks a job as complete. Usually this is called right before the
    MTurk form is submitted.
    """
    hit = session.query(models.HIT).filter(models.HIT.hitid == hitid).one()
    hit.markcompleted(workerid, assignmentid)
    session.add(hit)
    session.commit()
Ejemplo n.º 3
0
def savedonationstatus(hitid, donation):
    """
    Saves the donation statistics
    """
    hit = session.query(models.HIT).filter(models.HIT.hitid == hitid).one()
    hit.opt2donate = float(donation)
    hit.opt2donate = min(max(hit.opt2donate, 0), 1)

    session.add(hit)
    session.commit()
Ejemplo n.º 4
0
def makehomographydir(video):
    logger.debug("cwd: {0}".format(os.getcwd()))
    savedir = os.path.join(HOMOGRAPHY_DIR, video.slug)
    absdir = os.path.abspath(savedir)
    if not os.path.isdir(absdir):
        os.makedirs(absdir)
    video.homographylocation = absdir
    session.add(video)
    session.commit()
    return absdir
Ejemplo n.º 5
0
def saveeventlog(hitid, events):
    """
    Records the event log to database.
    """
    hit = session.query(models.HIT).filter(models.HIT.hitid == hitid).one()

    for timestamp, domain, message in events:
        timestamp = datetime.fromtimestamp(int(timestamp) / 1000)
        event = EventLog(hit=hit, domain=domain, message=message, timestamp=timestamp)
        session.add(event)
    session.commit()
Ejemplo n.º 6
0
def savejob(id, tracks):
    job = session.query(Job).get(id)

    for path in job.paths:
        session.delete(path)
    session.commit()
    for path in readpaths(tracks):
        job.paths.append(path)

    session.add(job)
    session.commit()
Ejemplo n.º 7
0
def savehomography(slug, homography):
    query = session.query(Video).filter(Video.slug == slug)
    if query.count() != 1:
        raise ValueError("Invalid video slug")
    video = query[0]

    savedir = video.homographylocation
    if savedir is None:
        savedir = makehomographydir(video)
    savelocation = os.path.join(savedir, "homography.npy")
    np.save(savelocation, np.array(homography))
    session.add(video)
    session.commit()
Ejemplo n.º 8
0
    def __call__(self, args):
        query = session.query(HIT)
        query = query.filter(HIT.useful == True)
        if args.hit:
            query = query.filter(HIT.hitid == args.id)
        else:
            worker = session.query(Worker).get(args.id)
            if not worker:
                print "Worker \"{0}\" not found".format(args.id)
                return
            if not args.no_block:
                worker.block("HIT was invalid.")
                print "Blocked worker \"{0}\"".format(args.id)
                session.add(worker)

            query = query.filter(HIT.workerid == args.id)

        for hit in query:
            replacement = hit.invalidate()
            session.add(hit)
            print "Invalidated {0}".format(hit.hitid)

            if replacement:
                session.add(replacement)
                if not args.no_publish:
                    session.commit()
                    replacement.publish()
                    session.add(replacement)
                    print "Respawned with {0}".format(replacement.hitid)
        session.commit()
Ejemplo n.º 9
0
def savejobstats(hitid, timeaccepted, timecompleted, environ):
    """
    Saves statistics for a job.
    """
    hit = session.query(models.HIT).filter(models.HIT.hitid == hitid).one()

    hit.timeaccepted = datetime.fromtimestamp(int(timeaccepted) / 1000)
    hit.timecompleted = datetime.fromtimestamp(int(timecompleted) / 1000)
    hit.timeonserver = datetime.now()

    hit.ipaddress = environ.get("HTTP_X_FORWARDED_FOR", None)
    hit.ipaddress = environ.get("REMOTE_ADDR", hit.ipaddress)

    session.add(hit)
    session.commit()
Ejemplo n.º 10
0
    def __call__(self, args):
        session = database.connect()

        acceptkeys = []
        rejectkeys = []
        warnkeys = []

        for f in args.accept:
            acceptkeys.extend(line.strip() for line in open(f))
        for f in args.reject:
            rejectkeys.extend(line.strip() for line in open(f))
        for f in args.warn:
            warnkeys.extend(line.strip() for line in open(f))

        try:
            query = session.query(HIT)
            query = query.filter(HIT.completed == True)
            query = query.filter(HIT.compensated == False)
            query = query.join(HITGroup)
            query = query.filter(HITGroup.offline == False)

            if args.limit:
                query = query.limit(args.limit)

            for hit in query:
                if not hit.check():
                    print "WARNING: {0} failed payment check, ignoring".format(hit.hitid)
                    continue
                try:
                    self.process(hit, acceptkeys, rejectkeys, warnkeys,
                        args.validated, args.default)
                    if hit.compensated:
                        if hit.accepted:
                            print "Accepted HIT {0}".format(hit.hitid)
                        else:
                            print "Rejected HIT {0}".format(hit.hitid)
                        session.add(hit)
                except CommunicationError as e:
                    hit.compensated = True
                    session.add(hit)
                    print "Error with HIT {0}: {1}".format(hit.hitid, e)
        finally:
            session.commit()
            session.close()
Ejemplo n.º 11
0
    def __call__(self, args, group):
        if args.number < 1:
            print "error: number must be >= 1"
            return

        for _ in range(args.number):
            job = Job(group = group)
            session.add(job)

            for activity in args.activities:
                activity = Activity(text = activity, job = job)
                session.add(activity)

        session.commit()

        if args.number == 1:
            print "Created 1 job."
        else:
            print "Created {0} jobs.".format(args.number)
Ejemplo n.º 12
0
    def __call__(self, args):
        session = database.connect()
        try:
            query = session.query(HIT)
            query = query.join(HITGroup)
            query = query.filter(HITGroup.offline == args.offline)
            query = query.filter(HIT.ready == True)
            if args.disable:
                if args.offline:
                    print "Cannot disable offline HITs."
                    return
                query = query.filter(HIT.published == True)
                query = query.filter(HIT.completed == False)
                if args.limit > 0:
                    query = query.limit(args.limit)

                for hit in query:
                    try:
                        hitid = hit.disable()
                        print "Disabled {0}".format(hitid)
                    except Exception as e:
                        print "Unable to disable HIT {0}!".format(hit.hitid)
                        print e
                    session.add(hit)
            else:
                query = query.filter(HIT.published == False)
                if args.limit > 0:
                    query = query.limit(args.limit)

                for hit in query:
                    if args.offline:
                        print hit.offlineurl(config.localhost)
                    else:
                        hit.publish()
                        print "Published {0}".format(hit.hitid)
                        session.add(hit)
                        session.commit()
        finally:
            session.commit()
            session.close()
Ejemplo n.º 13
0
def savejob1(id, data):
    # data contain comment, orientation, tracks
    job = session.query(Job).get(id)

    # seperate three parts
    #job.actionstart = data[0][0]
    #job.actionstop = data[1][0]
    #job.orientation = data[2][0]
    job.comment = data[3][0]
    if job.comment == "null":
        job.comment = "NULL"
    tracks = data[4]
    
    # delete old path in the database
    for path in job.paths:
        session.delete(path)
    session.commit()
    for path in readpaths(tracks):
        job.paths.append(path)

    session.add(job)
    session.commit()
Ejemplo n.º 14
0
def respawnjob(id):
    job = session.query(Job).get(id)

    replacement = job.markastraining()
    job.worker.verified = True
    session.add(job)
    session.add(replacement)
    session.commit()

    replacement.publish()
    session.add(replacement)
    session.commit()
Ejemplo n.º 15
0
    def __call__(self, args, group):
        print "Checking integrity..."

        # read first frame to get sizes
        path = Video.getframepath(0, args.location)
        try:
            im = Image.open(path)
        except IOError:
            print "Cannot read {0}".format(path)
            return
        width, height = im.size

        print "Searching for last frame..."

        # search for last frame
        toplevel = max(int(x)
            for x in os.listdir(args.location))
        secondlevel = max(int(x)
            for x in os.listdir("{0}/{1}".format(args.location, toplevel)))
        maxframes = max(int(os.path.splitext(x)[0])
            for x in os.listdir("{0}/{1}/{2}"
            .format(args.location, toplevel, secondlevel))) + 1

        print "Found {0} frames.".format(maxframes)

        # can we read the last frame?
        path = Video.getframepath(maxframes - 1, args.location)
        try:
            im = Image.open(path)
        except IOError:
            print "Cannot read {0}".format(path)
            return

        # check last frame sizes
        if im.size[0] != width and im.size[1] != height:
            print "First frame dimensions differs from last frame"
            return

        if session.query(Video).filter(Video.slug == args.slug).count():
            print "Video {0} already exists!".format(args.slug)
            return

        if args.train_with:
            if args.for_training:
                print "A training video cannot require training"
                return
            print "Looking for training video..."
            trainer = session.query(Video)
            trainer = trainer.filter(Video.slug == args.train_with)
            if not trainer.count():
                print ("Training video {0} does not exist!"
                    .format(args.train_with))
                return
            trainer = trainer.one()
        else:
            trainer = None

        # create video
        video = Video(slug = args.slug,
                      location = os.path.realpath(args.location),
                      width = width,
                      height = height,
                      totalframes = maxframes,
                      skip = args.skip,
                      perobjectbonus = args.per_object_bonus,
                      completionbonus = args.completion_bonus,
                      trainwith = trainer,
                      isfortraining = args.for_training,
                      blowradius = args.blow_radius)

        if args.for_training:
            video.trainvalidator = qa.tolerable(args.for_training_overlap,
                                                args.for_training_tolerance,
                                                args.for_training_mistakes)
            print "Training validator is {0}".format(video.trainvalidator)

        session.add(video)

        print "Binding labels and attributes..."

        # create labels and attributes
        labelcache = {}
        attributecache = {}
        lastlabel = None
        for labeltext in args.labels:
            if labeltext[0] == "~":
                if lastlabel is None:
                    print "Cannot assign an attribute without a label!"
                    return
                labeltext = labeltext[1:]
                attribute = Attribute(text = labeltext)
                session.add(attribute)
                lastlabel.attributes.append(attribute)
                attributecache[labeltext] = attribute
            else:
                label = Label(text = labeltext)
                session.add(label)
                video.labels.append(label)
                labelcache[labeltext] = label
                lastlabel = label

        print "Creating symbolic link..."
        symlink = "public/frames/{0}".format(video.slug)
        try:
            os.remove(symlink)
        except:
            pass
        os.symlink(video.location, symlink)

        print "Creating segments..."
        # create shots and jobs

        if args.for_training:
                segment = Segment(video = video)
                if args.for_training_start:
                    segment.start = args.for_training_start
                    if segment.start < 0:
                        segment.start = 0
                else:
                    segment.start = 0
                if args.for_training_stop:
                    segment.stop = args.for_training_stop
                    if segment.stop > video.totalframes - 1:
                        segment.stop = video.totalframes - 1
                else:
                    segment.stop = video.totalframes - 1
                job = Job(segment = segment, group = group, ready = False)
                session.add(segment)
                session.add(job)
        elif args.use_frames:
            with open(args.use_frames) as useframes:
                for line in useframes:
                    ustart, ustop = line.split()
                    ustart, ustop = int(ustart), int(ustop)
                    validlength = float(ustop - ustart)
                    numsegments = math.ceil(validlength / args.length)
                    segmentlength = math.ceil(validlength / numsegments)

                    for start in range(ustart, ustop, int(segmentlength)):
                        stop = min(start + segmentlength + args.overlap + 1,
                                   ustop)
                        segment = Segment(start = start,
                                          stop = stop,
                                          video = video)
                        job = Job(segment = segment, group = group)
                        session.add(segment)
                        session.add(job)
        else:
            startframe = args.start_frame
            stopframe = args.stop_frame
            if not stopframe:
                stopframe = video.totalframes - 1
            for start in range(startframe, stopframe, args.length):
                stop = min(start + args.length + args.overlap + 1,
                           stopframe)
                segment = Segment(start = start,
                                    stop = stop,
                                    video = video)
                job = Job(segment = segment, group = group)
                session.add(segment)
                session.add(job)

        if args.per_object_bonus:
            group.schedules.append(
                PerObjectBonus(amount = args.per_object_bonus))
        if args.completion_bonus:
            group.schedules.append(
                CompletionBonus(amount = args.completion_bonus))

        session.add(group)

        if args.for_training and args.for_training_data:
            print ("Loading training ground truth annotations from {0}"
                        .format(args.for_training_data))
            with open(args.for_training_data, "r") as file:
                pathcache = {}
                for line in file:
                    (id, xtl, ytl, xbr, ybr,
                     frame, outside, occluded, generated,
                     label) = line.split(" ")

                    if int(generated):
                        continue

                    if id not in pathcache:
                        print "Imported new path {0}".format(id)
                        label = labelcache[label.strip()[1:-1]]
                        pathcache[id] = Path(job = job, label = label)

                    box = Box(path = pathcache[id])
                    box.xtl = int(xtl)
                    box.ytl = int(ytl)
                    box.xbr = int(xbr)
                    box.ybr = int(ybr)
                    box.frame = int(frame)
                    box.outside = int(outside)
                    box.occluded = int(occluded)
                    pathcache[id].boxes.append(box)

        session.commit()

        if args.for_training:
            if args.for_training and args.for_training_data:
                print "Video and ground truth loaded."
            else:
                print "Video loaded and ready for ground truth:"
                print ""
                print "\t{0}".format(job.offlineurl(config.localhost))
                print ""
                print "Visit this URL to provide training with ground truth."
        else:
            print "Video loaded and ready for publication."
Ejemplo n.º 16
0
def savejob(id, tracks):
    job = session.query(Job).get(id)

    # Update current job
    for path in job.paths:
        session.delete(path)
    session.commit()

    for path in readpaths(tracks):
        logger.info(path)
        job.paths.append(path)

    session.add(job)
    session.commit()

    # Update neigboring segments
    video = job.segment.video
    prevseg, nextseg = video.getsegmentneighbors(job.segment)

    mergesegments = [s for s in [prevseg, job.segment, nextseg] if s is not None]
    updatesegments = [s for s in [prevseg, nextseg] if s is not None]

    # Create list of merged boxes with given label and userid
    labeledboxes = []
    for boxes, paths in merge.merge(mergesegments, threshold=0.8):
        path = paths[0]
        for p in paths:
            if p.job.segmentid == job.segmentid:
                path = p
                break
        labeledboxes.append((path.label, path.userid, boxes))

    # Remove paths in neighboring segments
    for segment in updatesegments:
        for path in segment.paths:
            session.delete(path)
    session.commit()

    # Add merged paths to neighboring segments
    for label, userid, boxes in labeledboxes:
        frames = sorted([box.frame for box in boxes])
        for segment in updatesegments:
            for job in segment.jobs:
                path = Path()
                path.label = label
                path.userid = userid
                addedbox = False
                for box in boxes:
                    if segment.start <= box.frame <= segment.stop:
                        newbox = Box(path=path)
                        newbox.frombox(box)
                        if not box.lost:
                            addedbox = True

                # Some segments and paths might not overlap
                if addedbox:
                    # Add in first frame if it's missing
                    if (frames[0] < segment.start < frames[-1]
                            and segment.start not in frames):
                        newbox = Box(path=path)
                        newbox.generated = False
                        newbox.frombox(
                            [box for box in LinearFill(boxes)
                            if box.frame == segment.start][0]
                        )

                    job.paths.append(path)

                session.add(job)
    session.commit()
Ejemplo n.º 17
0
 def __call__(self, args):
     if args.load:
         for data in pickle.load(open(args.load)):
             worker = Worker.lookup(data[0])
             worker.numsubmitted = data[1]
             worker.numacceptances = data[2]
             worker.numrejections = data[3]
             worker.blocked = data[4]
             worker.donatedamount = data[5]
             worker.bonusamount = data[6]
             worker.verified = data[7]
             print "Loaded {0}".format(worker.id)
             session.add(worker)
         session.commit()
     elif args.dump:
         data = []
         for worker in session.query(Worker):
             data.append((worker.id,
                          worker.numsubmitted,
                          worker.numacceptances,
                          worker.numrejections,
                          worker.blocked,
                          worker.donatedamount,
                          worker.bonusamount,
                          worker.verified))
             print "Dumped {0}".format(worker.id)
         pickle.dump(data, open(args.dump, "w"))
     elif args.block:
         worker = Worker.lookup(args.block)
         worker.block("Poor quality work.")
         session.add(worker)
         session.commit()
         print "Blocked {0}".format(args.block)
     elif args.unblock:
         worker = Worker.lookup(args.unblock)
         worker.unblock("Continue working.")
         session.add(worker)
         session.commit()
         print "Unblocked {0}".format(args.unblock)
     elif args.search:
         query = session.query(Worker)
         query = query.filter(Worker.id.like(args.search + "%"))
         if query.count():
             print "Matches:"
             for worker in query:
                 print worker.id
         else:
             print "No matches."
     elif args.summary:
         query = session.query(Worker)
         query = query.filter(Worker.id == args.summary)
         if query.count():
             worker = query.one()
             print "Submitted: {0}".format(worker.numsubmitted)
             print "Accepted: {0}".format(worker.numacceptances)
             print "Rejected: {0}".format(worker.numrejections)
             print "Bonuses: {0}".format(worker.bonusamount)
             print "Donated: {0}".format(worker.donatedamount)
             print "Verified: {0}".format(worker.verified)
             print "Blocked: {0}".format(worker.blocked)
             if args.location:
                 print "Locations: {0}".format(", ".join(set(x.country for x in worker.locations)))
         else:
             print "No matches."
     else:
         workers = session.query(Worker)
         workers = workers.order_by(Worker.numacceptances)
         for worker in workers:
             extra = ""
             if worker.blocked:
                 extra = "BLOCKED"
             if args.location:
                 locs = set(x.country for x in worker.locations)
                 if locs:
                     locs = ", ".join(locs)
                     extra += " " + locs
             extra = extra.strip()
             data = (worker.id,
                     worker.numsubmitted,
                     worker.numacceptances,
                     worker.numrejections,
                     extra)
             print "{0:<15} {1:>5} jobs {2:>5} acc {3:>5} rej     {4}".format(*data)
Ejemplo n.º 18
0
Archivo: cli.py Proyecto: mmisono/vatic
    def __call__(self, args):
        video = session.query(Video).filter(Video.slug == args.slug)
        if video.count() == 0:
            print "Video {0} does not exist!".format(args.slug)
            raise SystemExit()
        video = video.one()

        print "Parsing text data"
        data = {}
        if args.json:
            data = self.getdatajson(args.labelfile)
        else:
            data = self.getdatatext(args.labelfile, video.totalframes)

        scale = args.scale
        if args.dimensions or args.original_video or args.original_frame:
            print "Computing scale"
            if args.original_video:
                w, h = ffmpeg.extract(args.original_video).next().size
            elif args.original_frame:
                w, h = Image.open(args.original_frame).size
            else:
                w, h = args.dimensions.split("x")
            w = float(w)
            h = float(h)
            s = float(video.width) / w
            if s * h > video.height:
                s = float(video.height) / h
            scale = s
            print "Scale = {0}".format(scale)

        segmentcount = 1
        for segment in video.segments:
            print "Segment {0} of {1}".format(segmentcount, len(video.segments))
            segmentcount += 1
            for job in segment.jobs:
                for boxid in data:
                    label = data[boxid]['label']
                    boxes = data[boxid]['boxes']

                    query = session.query(Label).filter(Label.videoid == video.id).filter(Label.text == label)
                    if query.count() == 0:
                        continue
                    label = query.one()
 
                    newpath = Path(label=label)
                    visible = False
                    for frame, boxdata in boxes.iteritems():
                        frame = int(frame)
                        if frame < segment.start or segment.stop <= frame or (frame % video.blowradius != 0):
                            continue
                        newbox = Box(path=newpath)
                        #newbox.xtl = max(boxdata['xtl'], 0)
                        #newbox.ytl = max(boxdata['ytl'], 0)
                        #newbox.xbr = max(boxdata['xbr'], 0)
                        #newbox.ybr = max(boxdata['ybr'], 0)
                        newbox.xtl = boxdata['xtl']
                        newbox.ytl = boxdata['ytl']
                        newbox.xbr = boxdata['xbr']
                        newbox.ybr = boxdata['ybr']

                        newbox.occluded = boxdata['occluded']
                        newbox.outside = boxdata['outside']
                        newbox.generated = boxdata['generated']
                        newbox.frame = frame

                        scalebox = newbox.getbox()
                        scalebox = scalebox.transform(scale)
                        newbox.xtl = scalebox.xtl
                        newbox.ytl = scalebox.ytl
                        newbox.xbr = scalebox.xbr
                        newbox.ybr = scalebox.ybr

                        if not newbox.outside:
                            visible = True

                    if visible:
                        job.paths.append(newpath)

                session.add(job)
        session.commit()
Ejemplo n.º 19
0
    def __call__(self, args, group):
        print "Checking integrity..."

        # read first frame to get sizes
        path = Video.getframepath(0, args.location)
        try:
            im = Image.open(path)
        except IOError:
            print "Cannot read {0}".format(path)
            return
        width, height = im.size

        print "Searching for last frame..."

        # search for last frame
        toplevel = max(int(x)
            for x in os.listdir(args.location))
        secondlevel = max(int(x)
            for x in os.listdir("{0}/{1}".format(args.location, toplevel)))
        maxframes = max(int(os.path.splitext(x)[0])
            for x in os.listdir("{0}/{1}/{2}"
            .format(args.location, toplevel, secondlevel))) + 1

        print "Found {0} frames.".format(maxframes)

        # can we read the last frame?
        path = Video.getframepath(maxframes - 1, args.location)
        try:
            im = Image.open(path)
        except IOError:
            print "Cannot read {0}".format(path)
            return

        # check last frame sizes
        if im.size[0] != width and im.size[1] != height:
            print "First frame dimensions differs from last frame"
            return

        if session.query(Video).filter(Video.slug == args.slug).count():
            print "Video {0} already exists!".format(args.slug)
            return

        if args.train_with:
            if args.for_training:
                print "A training video cannot require training"
                return
            print "Looking for training video..."
            trainer = session.query(Video)
            trainer = trainer.filter(Video.slug == args.train_with)
            if not trainer.count():
                print ("Training video {0} does not exist!"
                    .format(args.train_with))
                return
            trainer = trainer.one()
        else:
            trainer = None

        # create video
        video = Video(slug = args.slug,
                      location = os.path.realpath(args.location), 
                      width = width,
                      height = height,
                      totalframes = maxframes,
                      skip = args.skip,
                      perobjectbonus = args.per_object_bonus,
                      completionbonus = args.completion_bonus,
                      trainwith = trainer,
                      isfortraining = args.for_training,
                      blowradius = args.blow_radius,
                      action = args.action,
                      pose = args.pose)

        if args.for_training:
            video.trainvalidator = qa.tolerable(args.for_training_overlap,
                                                args.for_training_tolerance,
                                                args.for_training_mistakes)
            print "Training validator is {0}".format(video.trainvalidator)

        session.add(video)

        print "Binding labels and attributes..."

        # create labels and attributes
        labelcache = {}
        attributecache = {}
        lastlabel = None
        for labeltext in args.labels:
            if labeltext[0] == "~":
                if lastlabel is None:
                    print "Cannot assign an attribute without a label!"
                    return
                labeltext = labeltext[1:]
                attribute = Attribute(text = labeltext)
                session.add(attribute)
                lastlabel.attributes.append(attribute)
                attributecache[labeltext] = attribute
            else:
                label = Label(text = labeltext)
                session.add(label)
                video.labels.append(label)
                labelcache[labeltext] = label
                lastlabel = label

        print "Creating symbolic link..."
        symlink = "public/frames/{0}".format(video.slug)
        try:
            os.remove(symlink)
        except:
            pass
        os.symlink(video.location, symlink)

        print "Creating segments..."
        # create shots and jobs
       
        if args.for_training:
                segment = Segment(video = video)
                if args.for_training_start:
                    segment.start = args.for_training_start
                    if segment.start < 0:
                        segment.start = 0
                else:
                    segment.start = 0
                if args.for_training_stop:
                    segment.stop = args.for_training_stop
                    if segment.stop > video.totalframes - 1:
                        segment.stop = video.totalframes - 1
                else:
                    segment.stop = video.totalframes - 1
                job = Job(segment = segment, group = group, ready = False)
                session.add(segment)
                session.add(job)
        elif args.use_frames:
            with open(args.use_frames) as useframes:
                for line in useframes:
                    ustart, ustop = line.split()
                    ustart, ustop = int(ustart), int(ustop)
                    validlength = float(ustop - ustart)
                    numsegments = math.ceil(validlength / args.length)
                    segmentlength = math.ceil(validlength / numsegments)

                    for start in range(ustart, ustop, int(segmentlength)):
                        stop = min(start + segmentlength + args.overlap + 1,
                                   ustop)
                        segment = Segment(start = start,
                                          stop = stop, 
                                          video = video)
                        job = Job(segment = segment, group = group)
                        session.add(segment)
                        session.add(job)
        else:
            startframe = args.start_frame
            stopframe = args.stop_frame
            if not stopframe:
                stopframe = video.totalframes - 1
            for start in range(startframe, stopframe, args.length):
                stop = min(start + args.length + args.overlap + 1,
                           stopframe)
                segment = Segment(start = start,
                                    stop = stop,
                                    video = video)
                job = Job(segment = segment, group = group)
                session.add(segment)
                session.add(job)

        if args.per_object_bonus:
            group.schedules.append(
                PerObjectBonus(amount = args.per_object_bonus))
        if args.completion_bonus:
            group.schedules.append(
                CompletionBonus(amount = args.completion_bonus))

        session.add(group)

        if args.for_training and args.for_training_data:
            print ("Loading training ground truth annotations from {0}"
                        .format(args.for_training_data))
            with open(args.for_training_data, "r") as file:
                pathcache = {}
                for line in file:
                    (id, xtl, ytl, xbr, ybr,
                     frame, outside, occluded, generated,
                     label) = line.split(" ")

                    if int(generated):
                        continue

                    if id not in pathcache:
                        print "Imported new path {0}".format(id)
                        label = labelcache[label.strip()[1:-1]]
                        pathcache[id] = Path(job = job, label = label)

                    box = Box(path = pathcache[id])
                    box.xtl = int(xtl)
                    box.ytl = int(ytl)
                    box.xbr = int(xbr)
                    box.ybr = int(ybr)
                    box.frame = int(frame)
                    box.outside = int(outside)
                    box.occluded = int(occluded)
                    pathcache[id].boxes.append(box)

        session.commit()

        if args.for_training:
            if args.for_training and args.for_training_data:
                print "Video and ground truth loaded."
            else:
                print "Video loaded and ready for ground truth:"
                print ""
                print "\t{0}".format(job.offlineurl(config.localhost))
                print ""
                print "Visit this URL to provide training with ground truth."
        else:
            print "Video loaded and ready for publication."
Ejemplo n.º 20
0
    def __call__(self, args, group):
        print "Checking integrity..."

        # read first frame to get sizes
        path = Video.getframepath(0, args.location)
        try:
            im = Image.open(path)
        except IOError:
            print "Cannot read {0}".format(path)
            return
        width, height = im.size

        print "Searching for last frame..."

        # search for last frame
        toplevel = max(int(x) for x in os.listdir(args.location))
        secondlevel = max(
            int(x)
            for x in os.listdir("{0}/{1}".format(args.location, toplevel)))
        maxframes = max(
            int(os.path.splitext(x)[0])
            for x in os.listdir("{0}/{1}/{2}".format(args.location, toplevel,
                                                     secondlevel))) + 1

        print "Found {0} frames.".format(maxframes)

        # can we read the last frame?
        path = Video.getframepath(maxframes - 1, args.location)
        try:
            im = Image.open(path)
        except IOError:
            print "Cannot read {0}".format(path)
            return

        # check last frame sizes
        if im.size[0] != width and im.size[1] != height:
            print "First frame dimensions differs from last frame"
            return

        if session.query(Video).filter(Video.slug == args.slug).count():
            print "Video {0} already exists!".format(args.slug)
            return

        if args.train_with:
            if args.for_training:
                print "A training video cannot require training"
                return
            print "Looking for training video..."
            trainer = session.query(Video)
            trainer = trainer.filter(Video.slug == args.train_with)
            if not trainer.count():
                print("Training video {0} does not exist!".format(
                    args.train_with))
                return
            trainer = trainer.one()
        else:
            trainer = None

        # create video
        video = Video(slug=args.slug,
                      location=os.path.realpath(args.location),
                      width=width,
                      height=height,
                      totalframes=maxframes,
                      skip=args.skip,
                      perobjectbonus=args.per_object_bonus,
                      completionbonus=args.completion_bonus,
                      trainwith=trainer,
                      isfortraining=args.for_training,
                      blowradius=args.blow_radius)

        if args.for_training:
            video.trainvalidator = qa.tolerable(args.for_training_overlap,
                                                args.for_training_tolerance,
                                                args.for_training_mistakes)
            print "Training validator is {0}".format(video.trainvalidator)

        session.add(video)

        print "Binding labels and attributes..."

        # create labels and attributes
        labelcache = {}
        attributecache = {}
        lastlabel = None
        for labeltext in args.labels:
            if labeltext[0] == "~":
                if lastlabel is None:
                    print "Cannot assign an attribute without a label!"
                    return
                labeltext = labeltext[1:]
                attribute = Attribute(text=labeltext)
                session.add(attribute)
                lastlabel.attributes.append(attribute)
                attributecache[labeltext] = attribute
            else:
                label = Label(text=labeltext)
                session.add(label)
                video.labels.append(label)
                labelcache[labeltext] = label
                lastlabel = label

        print "Creating symbolic link..."
        symlink = "public/frames/{0}".format(video.slug)
        try:
            os.remove(symlink)
        except:
            pass
        os.symlink(video.location, symlink)

        print "Creating segments..."
        # create shots and jobs

        job_list = []
        segment_list = []

        if args.for_training:
            segment = Segment(video=video)
            if args.for_training_start:
                segment.start = args.for_training_start
                if segment.start < 0:
                    segment.start = 0
            else:
                segment.start = 0
            if args.for_training_stop:
                segment.stop = args.for_training_stop
                if segment.stop > video.totalframes - 1:
                    segment.stop = video.totalframes - 1
            else:
                segment.stop = video.totalframes - 1
            job = Job(segment=segment, group=group, ready=False)
            job_list.append(job)
            segment_list.append(segment)
            session.add(segment)
            session.add(job)
        elif args.use_frames:
            with open(args.use_frames) as useframes:
                for line in useframes:
                    ustart, ustop = line.split()
                    ustart, ustop = int(ustart), int(ustop)
                    validlength = float(ustop - ustart)
                    numsegments = math.ceil(validlength / args.length)
                    segmentlength = math.ceil(validlength / numsegments)

                    for start in range(ustart, ustop, int(segmentlength)):
                        stop = min(start + segmentlength + args.overlap + 1,
                                   ustop)
                        segment = Segment(start=start, stop=stop, video=video)
                        job = Job(segment=segment, group=group)
                        job_list.append(job)
                        segment_list.append(segment)

                        session.add(segment)
                        session.add(job)
        else:
            startframe = args.start_frame
            stopframe = args.stop_frame
            if not stopframe:
                stopframe = video.totalframes - 1
            for start in range(startframe, stopframe, args.length):
                stop = min(start + args.length + args.overlap + 1, stopframe)
                segment = Segment(start=start, stop=stop, video=video)
                job = Job(segment=segment, group=group)
                job_list.append(job)
                segment_list.append(segment)

                session.add(segment)
                session.add(job)

        if args.per_object_bonus:
            group.schedules.append(
                PerObjectBonus(amount=args.per_object_bonus))
        if args.completion_bonus:
            group.schedules.append(
                CompletionBonus(amount=args.completion_bonus))

        session.add(group)

        if args.for_training and args.for_training_data:
            print("Loading training ground truth annotations from {0}".format(
                args.for_training_data))
            with open(args.for_training_data, "r") as file:
                pathcache = {}
                for line in file:
                    (id, xtl, ytl, xbr, ybr, frame, outside, occluded,
                     generated, label) = line.split(" ")

                    if int(generated):
                        continue

                    if id not in pathcache:
                        print "Imported new path {0}".format(id)
                        label = labelcache[label.strip()[1:-1]]
                        pathcache[id] = Path(job=job, label=label)

                    box = Box(path=pathcache[id])
                    box.xtl = int(xtl)
                    box.ytl = int(ytl)
                    box.xbr = int(xbr)
                    box.ybr = int(ybr)
                    box.frame = int(frame)
                    box.outside = int(outside)
                    box.occluded = int(occluded)
                    pathcache[id].boxes.append(box)

        session.commit()

        # Save the annotated file in the database
        if args.annot is not None:
            with open(args.annot, 'r') as annot_file:
                annotated_tracks = json.load(annot_file)

            # Scale annotations if annot-video-height is given as argument
            annot_scalar = 1.0
            if args.annot_video_height is not None:
                annot_scalar = video.height / float(
                    args.annot_video_height) * 1.5
                print('Scale factor: {}'.format(annot_scalar))

            # Scale bboxes and convert labels
            converted_tracks = []
            for a_labels, a_tracks, a_attribs in annotated_tracks:
                scaled_a_tracks = {}
                keep_tracks = a_tracks.keys()

                # Blow-radius for annotations
                if args.annot_blow_radius > 0:
                    keep_tracks = sorted(map(int, keep_tracks))
                    prev_frame_id = keep_tracks[0]
                    blown_tracks = [keep_tracks[0]]
                    for frame_id in keep_tracks:
                        if frame_id > prev_frame_id + args.annot_blow_radius:
                            prev_frame_id = frame_id
                            blown_tracks.append(frame_id)
                    keep_tracks = map(unicode, blown_tracks)

                # Conversion
                for track_id, track_data in a_tracks.iteritems():
                    if track_id in keep_tracks:
                        scaled_track = [
                            x * annot_scalar for x in track_data[:4]
                        ]
                        scaled_track.extend(track_data[4:])
                        scaled_a_tracks[track_id] = scaled_track
                converted_tracks.append(
                    [labelcache[a_labels].id, scaled_a_tracks, a_attribs])
            for j, s in zip(job_list, segment_list):
                job_data = []
                for a_labels, a_tracks, a_attribs in converted_tracks:
                    # Sort by track number
                    sorted_a_tracks = natural_sort(a_tracks.keys())
                    sorted_a_attribs = natural_sort(a_attribs.keys())

                    job_tracks = {}
                    job_attribs = {k.id: {} for k in attributecache.values()}
                    for track_id in sorted_a_tracks:
                        track_data = a_tracks[track_id]
                        track_id = int(track_id)
                        if s.start <= track_id <= s.stop:
                            job_tracks[track_id] = track_data
                        if track_id > s.stop:
                            break
                    for track_id in sorted_a_attribs:
                        attrib_data = a_attribs[track_id]
                        track_id = int(track_id)
                        if s.start <= track_id <= s.stop:
                            for k in job_attribs.keys():
                                job_attribs[k][track_id] = 0
                            job_attribs[
                                attributecache[attrib_data].id][track_id] = 1
                        if track_id > s.stop:
                            break
                    job_data.append([a_labels, job_tracks, job_attribs])
                savejob(j.id, job_data)

        if args.for_training:
            if args.for_training and args.for_training_data:
                print "Video and ground truth loaded."
            else:
                print "Video loaded and ready for ground truth:"
                print ""
                print "\t{0}".format(job.offlineurl(config.localhost))
                print ""
                print "Visit this URL to provide training with ground truth."
        else:
            print "Video loaded and ready for publication."