def init_tables(self):
		db = self.db
		# person group table
		pgSchema = [Field('gid', 'CHAR(255)', True, True, None),
					Field('name', 'TEXT', True, False, None),
					Field('user_data', 'TEXT', False, False, None)]
		self.tables['PersonGroup'] = Table(db, 'PersonGroup', pgSchema)

		# person table
		pSchema =  [Field('pid', 'CHAR(255)', True, True, None),
					Field('name', 'TEXT', True, False, None),
					Field('alias', 'TEXT', True, False, None),
					Field('gid', 'CHAR(255)', True, False, ForeignKey(self.tables['PersonGroup'].name, 'gid'))]
		self.tables['Person'] = Table(db, 'Person', pSchema)

		# face table
		fSchema =  [Field('fid', 'CHAR(255)', True, True, None),
					Field('image', 'TEXT', True, False, None),
					Field('pid', 'CHAR(255)', True, False, ForeignKey(self.tables['Person'].name, 'pid'))]
		self.tables['Face'] = Table(db, 'Face', fSchema)

		# event table
		eSchema = [Field('name', 'TEXT', True, False, None),
					Field('description', 'TEXT', True, False, None),
					Field('timestamp', 'BIGINT', True, False, None)]
		self.tables['Event'] = Table(db, 'Event', eSchema)

		# clockin table
		cSchema =  [Field('timestamp', 'BIGINT', True, False, None),
					Field('eid', 'INT', True, False, ForeignKey(self.tables['Event'].name, 'id')),
					Field('pid', 'CHAR(255)', True, False, ForeignKey(self.tables['Person'].name, 'pid'))]
		self.tables['ClockIn'] = Table(db, 'ClockIn', cSchema)
예제 #2
0
class Label(Model, CRUDMixin):
    __tablename__ = "labels"

    id = Column(Integer, primary_key=True)
    text = Column(String(250))
    videoid = Column(Integer, ForeignKey(Video.id))
    video = relationship(Video,
                         backref=backref("labels", cascade="all,delete"))
예제 #3
0
class AttributeAnnotation(Model, CRUDMixin):
    __tablename__ = "attribute_annotations"

    id = Column(Integer, primary_key=True)
    pathid = Column(Integer, ForeignKey(Path.id))
    path = relationship(Path,
                        backref=backref("attributes", cascade="all,delete"))
    attributeid = Column(Integer, ForeignKey(Attribute.id))
    attribute = relationship(Attribute)
    frame = Column(Integer)
    value = Column(Boolean, default=False)

    def __repr__(self):
        return ("AttributeAnnotation(pathid = {0}, "
                "attributeid = {1}, "
                "frame = {2}, "
                "value = {3})").format(self.pathid, self.attributeid,
                                       self.frame, self.value)
예제 #4
0
class Attribute(Model, CRUDMixin):
    __tablename__ = "attributes"

    id = Column(Integer, primary_key=True)
    text = Column(String(250))
    labelid = Column(Integer, ForeignKey(Label.id))
    label = relationship(Label,
                         backref=backref("attributes", cascade="all,delete"))

    def __str__(self):
        return self.text
예제 #5
0
class Document(TableBase):
    """An object refer to an actual plugin-managed document.

    Every actual document is not only saved in plugins' table, but also has an entry here, so that we can easily get all documents belong to a specific user."""

    __tablename__ = 'document'

    def __init__(self, plugin_name: str, doc: PluginDocument):
        super().__init__()
        self.owner = doc.owner
        self.plugin_name = plugin_name
        self.plugin_document_id = doc.id

    document_id = Column(Integer(), primary_key=True)
    owner = Column(Integer(), ForeignKey('user.id'))
    plugin_name = Column(String(256))
    plugin_document_id = Column(Integer())
예제 #6
0
class FeatureOfficial(TableBase):
    __tablename__ = 'parts_seq_features'

    feature_id = Column(INTEGER(11), primary_key=True)
    feature_type = Column(VARCHAR(200))
    start_pos = Column(INTEGER(11))
    end_pos = Column(INTEGER(11))
    label = Column(VARCHAR(200))
    part_id = Column(INTEGER(11), ForeignKey('parts.part_id'))
    type = Column(VARCHAR(200))
    label2 = Column(VARCHAR(200))
    mark = Column(INTEGER(11))
    old = Column(INTEGER(11))
    reverse = Column(INTEGER(11))

    def __set_by_kwargs__(self, **kwargs):
        for k, v in kwargs.items():
            setattr(self, k, v)
예제 #7
0
class Box(Model, CRUDMixin):
    __tablename__ = "boxes"

    id = Column(Integer, primary_key=True)
    pathid = Column(Integer, ForeignKey(Path.id))
    path = relationship(Path, backref=backref("boxes", cascade="all,delete"))
    xtl = Column(Integer)
    ytl = Column(Integer)
    xbr = Column(Integer)
    ybr = Column(Integer)
    frame = Column(Integer)
    occluded = Column(Boolean, default=False)
    outside = Column(Boolean, default=False)
    generated = Column(Boolean, default=False)

    def frombox(self, box):
        self.xtl = box.xtl
        self.xbr = box.xbr
        self.ytl = box.ytl
        self.ybr = box.ybr
        self.frame = box.frame
        self.occluded = box.occluded
        self.outside = box.lost
        self.generated = box.generated

    def getbox(self):
        vb = vision.Box(self.xtl,
                        self.ytl,
                        self.xbr,
                        self.ybr,
                        self.frame,
                        self.outside,
                        self.occluded,
                        0,
                        generated=self.generated)
        #        print 'frame id: {}, generated: {}'.format(vb.frame, vb.generated)
        return vb
예제 #8
0
class Segment(Model, CRUDMixin):
    __tablename__ = "segments"

    id = Column(Integer, primary_key=True)
    videoid = Column(Integer, ForeignKey(Video.id))
    video = relationship(Video,
                         backref=backref("segments", cascade="all,delete"))
    start = Column(Integer)
    stop = Column(Integer)

    @property
    def paths(self):
        paths = []
        for job in self.jobs:
            if job.useful:
                paths.extend(job.paths)
        return paths

    @property
    def cost(self):
        cost = 0
        for job in self.jobs:
            cost += job.cost
        return cost
예제 #9
0
class Video(Model, CRUDMixin):
    __tablename__ = "videos"

    id = Column(Integer, primary_key=True)
    slug = Column(String(250), index=True)
    width = Column(Integer)
    height = Column(Integer)
    totalframes = Column(Integer)
    location = Column(String(250))
    skip = Column(Integer, default=0, nullable=False)
    perobjectbonus = Column(Float, default=0)
    completionbonus = Column(Float, default=0)
    trainwithid = Column(Integer, ForeignKey(id))
    trainwith = relationship("Video", remote_side=id)
    isfortraining = Column(Boolean, default=False)
    blowradius = Column(Integer, default=5)
    homographylocation = Column(String(250), nullable=True, default=None)
    pointmode = Column(Boolean, default=False)

    orig_file_path = Column(String(550))
    extract_path = Column(String(550))

    # many to one
    owner_id = Column(Integer, ForeignKey("users.id"))

    # many to many
    # classifier_id = Column(Integer, ForeignKey("classifiers.id"))

    # many to many
    evaluation_sets = relationship(
        "EvaluationSet",
        secondary=video_evaluation_association_table,
        back_populates='videos')

    def __getitem__(self, frame):
        path = Video.getframepath(frame, self.location)
        return Image.open(path)

    @classmethod
    def getframepath(cls, frame, base=None):
        l1 = frame / 10000
        l2 = frame / 100
        path = "{0}/{1}/{2}.jpg".format(l1, l2, frame)
        if base is not None:
            path = "{0}/{1}".format(base, path)
        return path

    @property
    def cost(self):
        cost = 0
        for segment in self.segments:
            cost += segment.cost
        return cost

    @property
    def numjobs(self):
        count = 0
        for segment in self.segments:
            for job in segment.jobs:
                count += 1
        return count

    @property
    def numcompleted(self):
        count = 0
        for segment in self.segments:
            for job in segment.jobs:
                if job.completed:
                    count += 1
        return count

    def gethomography(self):
        if self.homographylocation is not None:
            path = os.path.join(self.homographylocation, "homography.npy")
            if os.path.exists(path):
                return np.load(path)
        return None

    def nextid(self):
        userids = [
            path.userid for segment in self.segments for path in segment.paths
        ]
        if len(userids) == 0:
            return 0
        return max(userids) + 1

    def getsegmentneighbors(self, segment):
        start, stop = segment.start, segment.stop
        prevseg, nextseg = None, None
        for seg in self.segments:
            if start <= seg.stop < stop:
                prevseg = seg
            elif start < seg.start <= stop:
                nextseg = seg
        return prevseg, nextseg
예제 #10
0
class Path(Model, CRUDMixin):
    __tablename__ = "paths"

    id = Column(Integer, primary_key=True)
    jobid = Column(Integer, ForeignKey(Job.id))
    job = relationship(Job, backref=backref("paths", cascade="all,delete"))
    labelid = Column(Integer, ForeignKey(Label.id))
    label = relationship(Label, cascade="none", backref="paths")
    userid = Column(Integer, default=0)
    done = Column(Boolean, default=False)

    interpolatecache = None

    def getboxes(self,
                 interpolate=False,
                 bind=False,
                 label=False,
                 groundplane=False):
        result = [x.getbox() for x in self.boxes]
        result.sort(key=lambda x: x.frame)

        if groundplane:
            homography = None
            with open(
                    os.path.join(self.job.segment.video.homographylocation,
                                 "homography.npy"), "r") as f:
                homography = np.load(f)

            for i in range(len(result)):
                t = homography.dot(np.array([result[i].xbr, result[i].ybr, 1]))
                result[i].xbr = float(t[0]) / t[2]
                result[i].ybr = float(t[1]) / t[2]
                result[i].xtl = result[i].xbr - 5
                result[i].ytl = result[i].ybr - 5

        if interpolate:
            if not self.interpolatecache:
                self.interpolatecache = LinearFill(result)
            result = self.interpolatecache

        if bind:
            result = Path.bindattributes(self.attributes, result)

        if label:
            for box in result:
                box.attributes.insert(0, self.label.text)

        return result

    @classmethod
    def bindattributes(cls, attributes, boxes):
        attributes = sorted(attributes, key=lambda x: x.frame)

        byid = {}
        for attribute in attributes:
            if attribute.attributeid not in byid:
                byid[attribute.attributeid] = []
            byid[attribute.attributeid].append(attribute)

        for attributes in byid.values():
            for prev, cur in zip(attributes, attributes[1:]):
                if prev.value:
                    for box in boxes:
                        if prev.frame <= box.frame < cur.frame:
                            if prev.attribute not in box.attributes:
                                box.attributes.append(prev.attribute)
            last = attributes[-1]
            if last.value:
                for box in boxes:
                    if last.frame <= box.frame:
                        if last.attribute not in box.attributes:
                            box.attributes.append(last.attribute)

        return boxes

    def __repr__(self):
        return "<Path {0}>".format(self.id)
예제 #11
0
class Job(Model, CRUDMixin):
    __tablename__ = "jobs"
    __mapper_args__ = {"polymorphic_identity": "jobs"}

    id = Column(Integer, primary_key=True)
    segmentid = Column(Integer, ForeignKey(Segment.id))
    segment = relationship(Segment,
                           backref=backref("jobs", cascade="all,delete"))
    istraining = Column(Boolean, default=False)
    hitid = Column(String(30))
    assignmentid = Column(String(30))
    ready = Column(Boolean, default=True, index=True)
    published = Column(Boolean, default=False, index=True)
    completed = Column(Boolean, default=False, index=True)
    compensated = Column(Boolean, default=False, index=True)
    accepted = Column(Boolean, default=False, index=True)
    validated = Column(Boolean, default=False, index=True)
    useful = Column(Boolean, default=True)

    def publish(self):
        if self.published:
            raise RuntimeError("HIT cannot be published because it has already"
                               " been published.")
        # resp = api.server.createhit(
        #     title = self.group.title,
        #     description = self.group.description,
        #     amount = self.group.cost,
        #     duration = self.group.duration,
        #     lifetime = self.group.lifetime,
        #     keywords = self.group.keywords,
        #     height = self.group.height,
        #     minapprovedamount = self.group.minapprovedamount,
        #     minapprovedpercent = self.group.minapprovedpercent,
        #     countrycode = self.group.countrycode,
        #     page = self.getpage())


#        resp = api.server.createhit(
#            title = 'title',
#            description = 'description',
#            amount = None,
#            duration = None,
#            lifetime = None,
#            page = self.getpage())
#        self.hitid = resp.hitid
        self.hitid = 'offline'
        self.published = True
        logger.debug("Published HIT {0}".format(self.hitid))

    ## TODO get page
    def getpage(self):
        page = '/index.html'
        return "{0}?id={1}".format(page, self.id)

    def markastraining(self):
        """
        Marks this job as the result of a training run. This will automatically
        swap this job over to the training video and produce a replacement.
        """
        replacement = Job(segment=self.segment, group=self.group)
        self.segment = self.segment.video.trainwith.segments[0]
        self.group = self.segment.jobs[0].group
        self.istraining = True

        logger.debug("Job is now training and replacement built")

        return replacement

    def invalidate(self):
        """
        Invalidates this path because it is poor work. The new job will be
        respawned automatically for different workers to complete.
        """
        self.useful = False
        # is this a training task? if yes, we don't want to respawn
        if not self.istraining:
            return Job(segment=self.segment, group=self.group)

    def check(self):
        if len(self.paths) > config.maxobjects:
            raise RuntimeError("Job {0} has too many objects to process "
                               "payment. Please verify this is not an "
                               "attempt to hack us and increase the "
                               "limit in config.py".format(self.id))
        return True

    def offlineurl(self, localhost):
        return "{0}{1}&hitId=offline".format(localhost, self.getpage())

    @property
    def trainingjob(self):
        return self.segment.video.trainwith.segments[0].jobs[0]

    @property
    def cost(self):
        if not self.completed:
            return 0
        return self.bonusamount + self.group.cost + self.donatedamount

    def __iter__(self):
        return self.paths
예제 #12
0
import numpy as np
import vision
from PIL import Image
from database import Column, Integer, Float, String, Boolean
from database import Model, CRUDMixin, ForeignKey, Table
from database import relationship, backref
from vision.track.interpolation import LinearFill
from meta_table import video_evaluation_association_table

import config

logger = logging.getLogger("vatic.models")

boxes_attributes = Table(
    "boxes2attributes", Column("box_id", Integer, ForeignKey("boxes.id")),
    Column("attribute_id", Integer, ForeignKey("attributes.id")))


class Video(Model, CRUDMixin):
    __tablename__ = "videos"

    id = Column(Integer, primary_key=True)
    slug = Column(String(250), index=True)
    width = Column(Integer)
    height = Column(Integer)
    totalframes = Column(Integer)
    location = Column(String(250))
    skip = Column(Integer, default=0, nullable=False)
    perobjectbonus = Column(Float, default=0)
    completionbonus = Column(Float, default=0)
예제 #13
0
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from database import Column, Integer, Float, String, Boolean
from database import Model, ForeignKey, Table
from database import relationship, backref

video_evaluation_association_table = Table(
    'video_evaluation_association',
    Column('evaluation_sets_id', Integer, ForeignKey('evaluation_sets.id')),
    Column('videos_id', Integer, ForeignKey('videos.id')))

classifier_evaluation_association_table = Table(
    'classifier_evaluation_association',
    Column('evaluation_sets_id', Integer, ForeignKey('evaluation_sets.id')),
    Column('classifiers_id', Integer, ForeignKey('classifiers.id')))

video_classifier_association_table = Table(
    'video_classifier_association',
    Column('videos_id', Integer, ForeignKey('videos.id')),
    Column('classifiers_id', Integer, ForeignKey('classifiers.id')))
예제 #14
0
class BiobrickUser(TableBase):
    __tablename__ = 'parts_by_user'

    part_id = Column(INTEGER(11), primary_key=True)
    ok = Column(TINYINT(1))
    part_name = Column(VARCHAR(255))
    short_desc = Column(VARCHAR(100))
    description = Column(LONGTEXT)
    part_type = Column(VARCHAR(20))
    author = Column(VARCHAR(200))
    owning_group_id = Column(INTEGER(11))
    status = Column(VARCHAR(20))
    dominant = Column(TINYINT(1))
    informational = Column(TINYINT(1))
    discontinued = Column(INTEGER(11))
    part_status = Column(VARCHAR(40))
    sample_status = Column(VARCHAR(40))
    p_status_cache = Column(VARCHAR(1000))
    s_status_cache = Column(VARCHAR(1000))
    creation_date = Column(DATE)
    m_datetime = Column(DATETIME)
    m_user_id = Column(INTEGER(11))
    uses = Column(INTEGER(11))
    doc_size = Column(INTEGER(11))
    works = Column(VARCHAR(10))
    favorite = Column(INTEGER(4))
    specified_u_list = Column(LONGTEXT)
    deep_u_list = Column(LONGTEXT)
    deep_count = Column(INTEGER(11))
    ps_string = Column(LONGTEXT)
    scars = Column(VARCHAR(20))
    default_scars = Column(VARCHAR(20))
    owner_id = Column(INTEGER(11))
    group_u_list = Column(LONGTEXT)
    has_barcode = Column(TINYINT(1))
    notes = Column(LONGTEXT)
    sources = Column(TEXT)
    nickname = Column(VARCHAR(10))
    categories = Column(VARCHAR(500))
    sequence = Column(LONGTEXT)
    sequence_sha1 = Column(BINARY(20))
    sequence_update = Column(INTEGER(11))
    seq_edit_cache = Column(LONGTEXT)
    review_result = Column(DOUBLE(12, 0))
    review_count = Column(INTEGER(4))
    review_total = Column(INTEGER(4))
    flag = Column(INTEGER(4))
    sequence_length = Column(INTEGER(11))
    temp_1 = Column(INTEGER(11))
    temp_2 = Column(INTEGER(11))
    temp_3 = Column(INTEGER(11))
    temp4 = Column(INTEGER(11))
    rating = Column(INTEGER(11))

    owner = Column(Integer, ForeignKey('user.user_id'))

    def __set_by_kwargs__(self, **kwargs):
        for k, v in kwargs.items():
            setattr(self, k, v)

    def __get_info__(self):
        values = {}
        for k in dir(self):
            if k.startswith('_'):
                continue
            values[k] = getattr(self, k)
        features = []
        for feature in session.query(BioBrickFeature).filter(
                BioBrickFeature.part_id == self):
            features.append({})
            for k in dir(feature):
                if k.startswith('_'):
                    continue
                features[-1][k] = getattr(feature, k)
        values['features'] = features
        return values
 def owner(cls):
     return Column(Integer(), ForeignKey('user.id'))