Beispiel #1
0
    def add_image(self, *a, **k):
        """upload and associate a dropzone image with a record"""
        # k contains FieldStorage object containing filename and data
        from StringIO import StringIO
        from utils import Record
        dummy = Record(
            filename='dummy.png',
            file=StringIO('test'),
        )

        # put the uploaded image data in a bucket
        path = os.path.join(system.site.data_path, 'buckets')
        bucket = Bucket(path)
        f = k.get('file', dummy)
        name = f.filename
        data = f.file.read()
        item_id = bucket.put(data)

        # create an attachment record for this bucket
        c = self.collection
        field_name = k.get('field_name', 'unknown')
        field_value = k.get('field_value', 'unknown')
        attachment = Attachment(
            record_kind=c.store.kind,
            field_name=field_name,
            field_value=field_value,
            attachment_id=item_id,
            attachment_size=len(data),
            attachment_name=name,
        )
        attachments = store(Attachment)
        attachments.put(attachment)

        return item_id
Beispiel #2
0
def getValues():
    record = Record(timestamp=request.json.get('timestamp'),
                    download=request.json.get('download'),
                    upload=request.json.get('upload'),
                    ping=request.json.get('ping'),
                    key=request.json.get('api'),
                    username=request.json.get('username'),
                    ip=request.json.get('ip'),
                    provider=request.json.get('provider'))

    # print record.timestamp, record.download, record.upload, record.ping, record.key, record.username

    # Save into the DB
    result = saveToDatabase(record)

    # Return the response code depending on result
    if result:
        return '', result
    else:
        return 404
def cseg_chars(files,suffix="gt",segmenter=None,grouper=None,has_gt=1,verbose=0):
    """Iterate through the characters contained in a cseg file.
    Argument should be a list of image files.  Given "line.png",
    uses "line.cseg.gt.png" and "line.gt.txt" if suffix="gt".
    Returns an iterator of raw,mask,cls. Attempts to align
    with ground truth unless has_gt=0."""
    # also accept individual files
    if type(files)==type(""):
        files = [files]
    # if no grouper is given, just instantiate a simple grouper
    if not grouper:
        grouper = ocropus.make_IGrouper("SimpleGrouper")
        grouper.pset("maxrange",1)
    # allow empty suffix as a special case
    if suffix is None:
        suffix = ""
    if suffix!="":
        suffix = "."+suffix
    # now iterate through all the image files
    for file in files:
        if verbose:
            print "# loading",file
        try:
            # load the text line
            image = iulib.bytearray()
            iulib.read_image_gray(image,file)
            base = re.sub("\.png$","",file)
            # load segmentation ground truth
            cseg_file = base+".cseg"+suffix+".png"
            print file,cseg_file
            cseg = iulib.intarray()
            if not os.path.exists(cseg_file):
                raise IOError(cseg_file)
            iulib.read_image_packed(cseg,cseg_file)
            ocropus.make_line_segmentation_black(cseg)
            # load text
            if has_gt:
                text_file = base+suffix+".txt"
                text = open(text_file).read()
                if text[-1]=="\n": text = text[:-1]
                if len(text)>iulib.max(cseg):
                    text = re.sub(r'\s+','',text)
                utext = iulib.ustrg()
                utext.assign(text) # FIXME should do UTF8 or u""
                if utext.length()!=iulib.max(cseg):
                    raise BadTranscript("mismatch transcript %d maxseg %d"%(utext.length(),iulib.max(cseg)))
                if verbose:
                    print "#",utext.length(),iulib.max(cseg)
            # perform the segmentation
            segmentation = iulib.intarray()
            if segmenter:
                segmenter.charseg(segmentation,image)
                ocropus.make_line_segmentation_black(segmentation)
                iulib.renumber_labels(segmentation,1)
            else:
                segmentation.copy(cseg)

            # invert the image, since that's the way we're doing
            # all the remaining processing
            iulib.sub(255,image)

            # set the segmentation in preparation for loading
            if has_gt:
                grouper.setSegmentationAndGt(segmentation,cseg,utext)
            else:
                grouper.setSegmentation(segmentation)

            # now iterate through the segments of the line
            for i in range(grouper.length()):
                cls = None
                if has_gt:
                    cls = grouper.getGtClass(i)
                    if cls==-1:
                        cls = ""
                    else:
                        cls = chr(cls)
                raw = iulib.bytearray()
                mask = iulib.bytearray()
                grouper.extractWithMask(raw,mask,image,i,1)
                # print "component",i,N(segments),amax(N(raw)),raw.dim(0),raw.dim(1)
                # imshow(NI(raw)); gray(); show()
                yield Record(raw=raw,mask=mask,cls=cls,index=i,
                             bbox=grouper.boundingBox(i))
        except IOError,e:
            raise e
        except:
Beispiel #4
0
    def addTrainingLine(self, rseg, image_, transcription):
        """Add a line of text plus its transcription to the line recognizer as
        training data. This also returns the raw segmentation in its first
        argument (an intarray)."""
        # rseg = ocropy.intarray()

        # make a copy of the input image
        image = ocropy.bytearray()
        image.copy(image_)

        # now run the recognizer
        lattice = ocropy.make_OcroFST()
        self.recognizeLineSeg(lattice, rseg, image)
        print "bestpath", bestpath(lattice)

        # compute the alignment
        print "gt", transcription
        lmodel = fstutils.make_line_fst([transcription])
        r = ocropy.compute_alignment(lattice, rseg, lmodel)
        result = r.output
        cseg = r.cseg
        costs = r.costs.numpy()
        tcost = sum(costs)
        if tcost > 10000.0: raise Exception("cost too high")
        mcost = mean(costs)
        if mcost > 10.0: raise RejectException("mean cost too high")
        if tcost > 100.0: raise RejectException("total cost too high")
        print "alignment", mcost, tcost

        # this is a special case of ocropus-extract-csegs...

        # find all the aligned characters
        ocropy.sub(255, image)
        utext = ocropy.ustrg()
        # utext.assign(text)
        utext.assign(r.output)
        self.grouper.setSegmentationAndGt(rseg, cseg, utext)
        chars = []
        for i in range(self.grouper.length()):
            cls = self.grouper.getGtClass(i)
            if cls == -1:
                continue  # ignore missegmented characters (handled separately below)
            cls = chr(cls)
            raw = ocropy.bytearray()
            mask = ocropy.bytearray()
            self.grouper.extractWithMask(raw, mask, image, i, 1)
            chars.append(
                Record(raw=raw,
                       mask=mask,
                       cls=cls,
                       index=i,
                       bbox=self.grouper.boundingBox(i)))

        # find all the non-aligned groups and add them as nonchars
        bboxes = [rect(c.bbox) for c in chars]
        self.grouper.setSegmentation(rseg)
        nonchars = []
        for i in range(self.grouper.length()):
            bbox = self.grouper.boundingBox(i)
            fractions = [
                min(bbox.fraction_covered_by(c.bbox),
                    c.bbox.fraction_covered_by(bbox)) for c in chars
            ]
            covered = max(fractions)
            assert covered > 1e-5
            if covered > self.maxoverlap: continue
            assert rect(bbox) not in bboxes
            raw = ocropy.bytearray()
            mask = ocropy.bytearray()
            self.grouper.extractWithMask(raw, mask, image, i, 1)
            nonchars.append(
                Record(raw=raw,
                       mask=mask,
                       cls=cls,
                       index=i,
                       bbox=self.grouper.boundingBox(i)))

        # finally add them to the character model
        for c in chars:
            self.new_model.cadd(floatimage(c.raw), c.cls)
        for c in nonchars:
            self.new_model.cadd(floatimage(c.raw), "~")

        self.chars = chars
        self.nonchars = nonchars
        print "#chars", len(chars), "#nonchars", len(nonchars)
Beispiel #5
0
    def recognizeLineSeg(self, lattice, rseg, image):
        """Recognize a line.
        
        lattice: result of recognition
        rseg: intarray where the raw segmentation will be put
        image: line image to be recognized"""

        if self.debug: print "starting"

        ## increase segmentation scale for large lines
        h = image.dim(1)
        s = max(2.0, h / 15.0)
        try:
            self.segmenter.pset("cost_smooth", s)
            if s > 2.0: print "segmentation scale", s
        except:
            pass

        ## compute the raw segmentation
        if self.debug: print "segmenting"
        self.segmenter.charseg(rseg, image)
        if self.debug: print "done"
        ocropus.make_line_segmentation_black(rseg)
        if self.debug:
            print "here"
            clf()
            subplot(4, 1, 1)
            show_segmentation(rseg)
            draw()
            print "there"
        iulib.renumber_labels(rseg, 1)
        self.grouper.setSegmentation(rseg)

        # compute the median segment height
        heights = []
        for i in range(self.grouper.length()):
            bbox = self.grouper.boundingBox(i)
            heights.append(bbox.height())
        mheight = median(array(heights))
        self.mheight = mheight

        # invert the input image (make a copy first)
        old = image
        image = iulib.bytearray()
        image.copy(old)
        iulib.sub(255, image)

        # allocate working arrays
        segs = iulib.intarray()
        raw = iulib.bytearray()
        mask = iulib.bytearray()

        # now iterate through the characters and collect candidates
        inputs = []
        for i in range(self.grouper.length()):
            # get the bounding box for the character (used later)
            bbox = self.grouper.boundingBox(i)
            aspect = bbox.height() * 1.0 / bbox.width()

            # extract the character image (and optionally display it)
            self.grouper.extractWithMask(raw, mask, image, i, 1)
            char = NI(raw)
            char = char / float(amax(char))
            if self.debug:
                subplot(4, 1, 2)
                print i, (bbox.x0, bbox.y0, bbox.x1, bbox.y1)
                cla()
                imshow(char, cmap=cm.gray)
                draw()
                print "hit RETURN to continue"
                raw_input()
            inputs.append(FI(char))

        # classify the candidates (using multithreading, where available)
        results = utils.omp_classify(self.cmodel, inputs)

        # now convert the classified outputs into a list of candidate records
        candidates = []
        for i in range(len(inputs)):
            # compute the classifier output for this character
            # print self.cmodel.info()
            raw = inputs[i]
            char = NI(raw)
            bbox = self.grouper.boundingBox(i)
            outputs = results[i]
            outputs = [(x[0], -log(x[1])) for x in outputs]
            candidates.append(
                Record(index=i,
                       image=char,
                       raw=raw,
                       outputs=outputs,
                       bbox=bbox))

        # keep the characters around for debugging (used by ocropus-showlrecs)
        self.chars = candidates

        # update the per-character costs based on a text line model
        if self.linemodel is not None:
            self.linemodel.linecosts(candidates, image)

        # compute a list of space costs for each candidate character
        spacecosts = self.spacemodel.spacecosts(candidates, image)

        for c in candidates:
            i = c.index
            raw = c.raw
            char = c.image
            outputs = c.outputs

            # Add a skip transition with the pixel width as cost.
            # This ensures that the lattice is at least connected.
            # Note that for typical character widths, this is going
            # to be much larger than any per-charcter cost.
            self.grouper.setClass(i, ocropus.L_RHO,
                                  self.rho_scale * raw.dim(0))

            # add the top classes to the lattice
            outputs.sort(key=lambda x: x[1])
            s = iulib.ustrg()
            for cls, cost in outputs[:self.best]:
                # don't add the reject class (written as "~")
                if cls == "~": continue

                # don't add anything with a cost higher than the reject cost
                if cost > self.reject_cost: continue

                # for anything else, just add the classified character to the grouper
                s = iulib.unicode2ustrg(cls)
                self.grouper.setClass(i, s, min(cost, self.maxcost))

                # add the computed space costs to the grouper as well
                self.grouper.setSpaceCost(i, spacecosts[i][0],
                                          spacecosts[i][1])

        # extract the recognition lattice from the grouper
        self.grouper.getLattice(lattice)

        # return the raw segmentation as a result
        return rseg
Beispiel #6
0
    def recognizeLineSeg(self,lattice,rseg,image):
        """Recognize a line.
        lattice: result of recognition
        rseg: intarray where the raw segmentation will be put
        image: line image to be recognized"""

        ## compute the raw segmentation
        self.segmenter.charseg(rseg,image)
        ocropus.make_line_segmentation_black(rseg)
        if self.debug: show_segmentation(rseg)
        iulib.renumber_labels(rseg,1)
        self.grouper.setSegmentation(rseg)

        # compute the median segment height
        heights = []
        for i in range(self.grouper.length()):
            bbox = self.grouper.boundingBox(i)
            heights.append(bbox.height())
        mheight = median(array(heights))
        self.mheight = mheight

        # invert the input image (make a copy first)
        old = image; image = iulib.bytearray(); image.copy(old)
        iulib.sub(255,image)

        # allocate working arrays
        segs = iulib.intarray()
        raw = iulib.bytearray()
        mask = iulib.bytearray()

        # this holds the list of recognized characters if keep!=0
        self.chars = []
        
        # now iterate through the characters
        for i in range(self.grouper.length()):
            # get the bounding box for the character (used later)
            bbox = self.grouper.boundingBox(i)
            aspect = bbox.height()*1.0/bbox.width()

            # extract the character image (and optionally display it)
            self.grouper.extractWithMask(raw,mask,image,i,1)
            char = NI(raw)
            char = char / float(amax(char))
            if self.debug:
                imshow(char)
                raw_input()

            # Add a skip transition with the pixel width as cost.
            # This ensures that the lattice is at least connected.
            # Note that for typical character widths, this is going
            # to be much larger than any per-charcter cost.
            self.grouper.setClass(i,ocropus.L_RHO,self.rho_scale*raw.dim(0))

            # compute the classifier output for this character
            # print self.cmodel.info()
            outputs = self.cmodel.coutputs(FI(char))
            outputs = [(x[0],-log(x[1])) for x in outputs]
            self.chars.append(Record(index=i,image=char,outputs=outputs))
            
            # add the top classes to the lattice
            outputs.sort(key=lambda x:x[1])
            s = iulib.ustrg()
            for cls,cost in outputs[:self.best]:
                # don't add the reject class (written as "~")
                if cls=="~": continue

                # letters are never small, so we skip small bounding boxes that
                # are categorized as letters; this is an ugly special case, but
                # it is quite common
                ucls = cls
                if type(cls)==str: ucls = unicode(cls,"utf-8")
                category = unicodedata.category(ucls[0])
                if bbox.height()<self.min_height*mheight and category[0]=="L":
                    # add an empty transition to allow skipping junk
                    # (commented out right now because I'm not sure whether
                    # the grouper can handle it; FIXME)
                    # self.grouper.setClass(i,"",1.0)
                    continue

                # for anything else, just add the classified character to the grouper
                s.assign(cls)
                self.grouper.setClass(i,s,min(cost,self.maxcost))
                # FIXME better space handling
                self.grouper.setSpaceCost(i,0.5,0.0)

        # extract the recognition lattice from the grouper
        self.grouper.getLattice(lattice)

        # return the raw segmentation as a result
        return rseg
def main(args):
    env = make_env(args)
    system = env.system
    control = env.control

    x = system.reset()
    uvar = control.reset()

    record = Record()

    args.ts = np.arange(0, args.t_final, args.t_step)
    for t in tqdm(args.ts, mininterval=1):
        # get q control input
        u = control.get_inputs(t, x, uvar)

        # steps
        next_x = system.step(t, x, u)
        next_uvar = control.step(t, x, uvar)

        record.append('time', t)
        record.append('state', x)
        record.append('input', u)
        record.append('reference_model', uvar.xr)
        record.append('what', uvar.what.ravel())
        record.append('w', system.unc.parameter(t).ravel())
        record.append('basissum', uvar.basissum)
        record.append('phif', uvar.phif)
        record.append('z', uvar.z)
        record.append('e', x - uvar.xr)
        record.append('q', uvar.q)
        record.append('p', uvar.p)
        record.append('best_basissum', uvar.best_basissum)

        x = next_x
        uvar = next_uvar

    args.update(**record)

    return env
Beispiel #8
0
def cc_statistics(image,dpi,min_pt,max_pt,verbose=0):
    w = image.dim(0)
    h = image.dim(1)

    ## compute connected component widths and heights
    components = iulib.intarray()
    components.copy(image)
    iulib.sub(iulib.max(components),components)
    iulib.label_components(components)
    boxes = iulib.rectarray()
    iulib.bounding_boxes(boxes,components)
    n = boxes.length()
    widths = array([boxes.at(i).width() for i in range(1,n)])
    heights = array([boxes.at(i).height() for i in range(1,n)])

    ## we consider "normal" components that are between 1/3 of the 
    ## size of the minimum sized font and the full size of the 
    ## maxmimum sized font; to compute this, we need to convert from
    ## font sizes in pt to pixel sizes, using the given dpi
    maxs = maximum(widths,heights)
    min_px_em = min_pt*dpi/72.0
    min_px = (1.0/3.0) * min_px_em
    max_px = max_pt*dpi/72.0

    ## compute the total page area covered by bounding boxes of connected
    ## components (we don't bother to try to avoid double counts in overlapping boxes)
    covered = sum(widths*heights)*1.0/w/h

    ## small components are those whose maximum dimension is smaller that the min size
    small = (maxs<min_px)

    ## large components have at least one dimension better than the max size
    large = (maxs>max_px)

    ## biggish components have both dimensions bigger than the small size (this
    ## excludes "." and "-" and is used for aspect ratio computations)
    biggish = ((widths>min_px)&(heights>min_px))

    ## normal boxes are those that are neither small nor large
    normal = ~(small|large)

    ## absolute density of characters per square inch
    density = n*dpi**2*1.0/w/h

    ## relative density of characters per em
    h_density = n/(w/min_px_em)

    ## print some information
    if verbose:
        alert("# min",min_px,"max",max_px)
        alert("# normal",sum(normal),"small",sum(small),"large",sum(large))
        alert("# density",density)
        alert("# h_density",h_density)
        alert("# covered",covered)


    ## compute aspect ratio statistics; we're using a right-trimmed mean of
    ## biggish components; this means that we exclude characters like "-"
    ## from the computation (because they are not biggish), and we also exclude
    ## large connected components such as rules (since they are trimmed off)
    ## the remaining mean should represent the mean of connected components that
    ## make up the bulk of the text on the page
    aspect = heights*1.0/widths
    aspect = aspect[biggish]
    a_mean = mean(trim1(aspect,0.1,tail='right'))

    result = Record(
        biggish = sum(biggish),
        normal = sum(normal),
        small = sum(small),
        large = sum(large),
        density = density,
        h_density = h_density,
        a_mean = a_mean,
        covered=covered,
    )

    return result