Example #1
0
def extract_candidate_groups(segmentation,
                             min_aspect=0.1,
                             max_aspect=1.8,
                             maxgap=2,
                             maxrange=3):
    """Select a basic collection of candidate components.  Aspect ratios <1 are tall and skinny,
    >1 are wide.  `maxgap` is the maximum gap between bounding boxes.  `maxrange` gives the
    maximum number of compponents to be combined."""
    assert morph.ordered_by_xcenter(
        segmentation), "call morph.sort_by_xcenter first"
    boxes = [None] + morph.find_objects(segmentation)
    n = len(boxes)
    result = []
    for i in range(1, n):
        for r in range(1, maxrange + 1):
            if i + r > n: continue
            if r > 1 and max_boxgap(boxes[i:i + r]) > maxgap:
                continue
            box = box_union(boxes[i:i + r])
            a = sl.aspect(box)
            if r > 1 and 1.0 / a > max_aspect: continue
            if 1.0 / a < min_aspect: continue
            assert sum(segmentation[box]) > 0
            j = i + r - 1
            seg = segmentation[box] * (segmentation[box] >=
                                       i) * (segmentation[box] <= j)
            result.append(Segment(first=i, last=j, bbox=box))
    return result
Example #2
0
def extract_candidate_groups(segmentation, min_aspect=0.1, max_aspect=1.8, maxgap=2, maxrange=3):
    """Select a basic collection of candidate components.  Aspect ratios <1 are tall and skinny,
    >1 are wide.  `maxgap` is the maximum gap between bounding boxes.  `maxrange` gives the
    maximum number of compponents to be combined."""
    assert morph.ordered_by_xcenter(segmentation), "call morph.sort_by_xcenter first"
    boxes = [None] + morph.find_objects(segmentation)
    n = len(boxes)
    result = []
    for i in range(1, n):
        for r in range(1, maxrange + 1):
            if i + r > n:
                continue
            if r > 1 and max_boxgap(boxes[i : i + r]) > maxgap:
                continue
            box = box_union(boxes[i : i + r])
            a = sl.aspect(box)
            if r > 1 and 1.0 / a > max_aspect:
                continue
            if 1.0 / a < min_aspect:
                continue
            assert sum(segmentation[box]) > 0
            j = i + r - 1
            seg = segmentation[box] * (segmentation[box] >= i) * (segmentation[box] <= j)
            result.append(Segment(first=i, last=j, bbox=box))
    return result
Example #3
0
 def setImageMasked(self, image, mask=None, lo=None, hi=None):
     """Set the image to be iterated over.  This should be an RGB image,
         ndim==3, dtype=='B'.  This picks a subset of the segmentation to iterate
         over, using a mask and lo and hi values.
     """
     # print("$$ setImageMasked: image=%s mask=%s lo=%s hi=%s" % (
     #     desc(image), hexs(mask), hexs(lo), hexs(hi)))
     assert image.dtype == dtype('B') or image.dtype == dtype(
         'i'), "image must be type B or i"
     if image.ndim == 3:
         image = rgb2int(image)
     imageDescribe("image", image)
     assert image.ndim == 2, "wrong number of dimensions"
     self.image = image
     labels = image
     if lo is not None:
         labels[labels < lo] = 0
     if hi is not None:
         labels[labels > hi] = 0
     if mask is not None:
         labels = bitwise_and(labels, mask)
     imageDescribe("labels", labels)
     labels, correspondence = morph.renumber_labels_ordered(
         labels, correspondence=1)
     self.labels = labels
     self.correspondence = correspondence
     self.objects = [None] + morph.find_objects(labels)
     # print("$$ setImageMasked: objects=%d" % len(self.objects))
     sizes = [o for o in self.objects]
     sizes.sort(key=lambda u: -sliceSize(u))
     for i, o in enumerate(sizes[:20]):
         print("%5d: %s %s %d" % (i, o, sliceDims(o), sliceSize(o)))
Example #4
0
def bbox(image):
    """Compute the bounding box for the pixels in the image."""
    assert len(image.shape)==2,"wrong shape: "+str(image.shape)
    image = array(image!=0,'uint32')
    cs = morph.find_objects(image)
    if len(cs)<1: return None
    c = cs[0]
    return (c[0].start,c[1].start,c[0].stop,c[1].stop)
Example #5
0
def bbox(image):
    """Compute the bounding box for the pixels in the image."""
    assert len(image.shape) == 2, "wrong shape: " + str(image.shape)
    image = array(image != 0, 'uint32')
    cs = morph.find_objects(image)
    if len(cs) < 1: return None
    c = cs[0]
    return (c[0].start, c[1].start, c[0].stop, c[1].stop)
Example #6
0
def extract_csegs(segmentation,aligned=None):
    """Given a segmentation, extracts a list of segment objects."""
    if aligned is None: aligned = []
    def get(c): return aligned[c] if c<len(aligned) else ""
    boxes = morph.find_objects(segmentation)
    # n = len(boxes)
    result = [Segment(first=i+1,last=i+1,bbox=box,out=[(get(i),0.0)],
                      img=1*(segmentation[:,box[1]]==i+1)) \
                      for i,box in enumerate(boxes) if box is not None]
    return result
Example #7
0
 def setImageMasked(self,image,mask=None,lo=None,hi=None):
     """Set the image to be iterated over.  This should be an RGB image,
     ndim==3, dtype=='B'.  This picks a subset of the segmentation to iterate
     over, using a mask and lo and hi values.."""
     assert image.dtype==dtype('B') or image.dtype==dtype('i'),"image must be type B or i"
     if image.ndim==3: image = rgb2int(image)
     assert image.ndim==2,"wrong number of dimensions"
     self.image = image
     labels = image
     if lo is not None: labels[labels<lo] = 0
     if hi is not None: labels[labels>hi] = 0
     if mask is not None: labels = bitwise_and(labels,mask)
     labels,correspondence = morph.renumber_labels_ordered(labels,correspondence=1)
     self.labels = labels
     self.correspondence = correspondence
     self.objects = [None]+morph.find_objects(labels)
Example #8
0
def compute_lines(segmentation, scale):
    """Given a line segmentation map, computes a list
    of tuples consisting of 2D slices and masked images."""
    lobjects = morph.find_objects(segmentation)
    lines = []
    for i, o in enumerate(lobjects):
        if o is None: continue
        if sl.dim1(o) < 2 * scale or sl.dim0(o) < scale: continue
        mask = (segmentation[o] == i + 1)
        if amax(mask) == 0: continue
        result = record()
        result.label = i + 1
        result.bounds = o
        result.mask = mask
        lines.append(result)
    return lines
Example #9
0
def compute_lines(segmentation,scale):
    """Given a line segmentation map, computes a list
    of tuples consisting of 2D slices and masked images."""
    lobjects = morph.find_objects(segmentation)
    lines = []
    for i,o in enumerate(lobjects):
        if o is None: continue
        if sl.dim1(o)<2*scale or sl.dim0(o)<scale: continue
        mask = (segmentation[o]==i+1)
        if amax(mask)==0: continue
        result = record()
        result.label = i+1
        result.bounds = o
        result.mask = mask
        lines.append(result)
    return lines
Example #10
0
def seg_boxes(seg,math=0):
    """Given a color segmentation, return a list of bounding boxes.
    Bounding boxes are returned as tuples (y0,y1,x0,x1).  With
    math=0, raster coordinates are used, with math=1, Postscript
    coordinates are used (however, the order of the values in the
    tuple doesn't change)."""
    seg = array(seg,'uint32')
    slices = morph.find_objects(seg)
    h = seg.shape[0]
    result = []
    for i in range(len(slices)):
        if slices[i] is None: continue
        (ys,xs) = slices[i]
        if math:
            result += [(h-ys.stop-1,h-ys.start-1,xs.start,xs.stop)]
        else:
            result += [(ys.start,ys.stop,xs.start,xs.stop)]
    return result
Example #11
0
def seg_boxes(seg, math=0):
    """Given a color segmentation, return a list of bounding boxes.
    Bounding boxes are returned as tuples (y0,y1,x0,x1).  With
    math=0, raster coordinates are used, with math=1, Postscript
    coordinates are used (however, the order of the values in the
    tuple doesn't change)."""
    seg = array(seg, 'uint32')
    slices = morph.find_objects(seg)
    h = seg.shape[0]
    result = []
    for i in range(len(slices)):
        if slices[i] is None: continue
        (ys, xs) = slices[i]
        if math:
            result += [(h - ys.stop - 1, h - ys.start - 1, xs.start, xs.stop)]
        else:
            result += [(ys.start, ys.stop, xs.start, xs.stop)]
    return result
Example #12
0
def extract_chars(segmentation,h=32,w=32,f=0.5,minscale=0.5):
    """Extract all the characters from the segmentation and yields them
    as an interator.  Also yields a forward and a backwards transformation."""
    bin = (segmentation>0)
    if amax(bin)==0: raise ocrolib.RecognitionError("empty segmentation")
    ls,ly,lx = vertical_stddev(bin)
    boxes = morph.find_objects(segmentation)
    for i,b in enumerate(boxes):
        sub = (segmentation==i+1)
        if amax(sub)==amin(sub): continue
        cs,cy,cx = vertical_stddev(sub)
        # limit the character sigma to be at least minscale times the
        # line sigma (this causes dots etc. not to blow up ridiculously large)
        scale = f*h/(4*max(cs,minscale*ls))
        m = diag([1.0/scale,1.0/scale])
        offset = array([cy,cx])-dot(m,array([h/2,w/2]))
        def transform(image,m=m,offset=offset):
            return interpolation.affine_transform(1.0*image,m,offset=offset,order=1,output_shape=(h,w))
        def itransform_add(result,image,m=m,cx=cx,cy=cy):
            im = inv(m)
            ioffset = array([h/2,w/2])-dot(im,array([cy,cx]))
            result += interpolation.affine_transform(1.0*image,im,offset=ioffset,order=1,output_shape=segmentation.shape)
        cimage = transform(sub)
        yield cimage,transform,itransform_add
Example #13
0
def extract_chars(segmentation, h=32, w=32, f=0.5, minscale=0.5):
    """Extract all the characters from the segmentation and yields them
    as an interator.  Also yields a forward and a backwards transformation."""
    bin = (segmentation > 0)
    if amax(bin) == 0: raise ocrolib.RecognitionError("empty segmentation")
    ls, ly, lx = vertical_stddev(bin)
    boxes = morph.find_objects(segmentation)
    for i, b in enumerate(boxes):
        sub = (segmentation == i + 1)
        if amax(sub) == amin(sub): continue
        cs, cy, cx = vertical_stddev(sub)
        # limit the character sigma to be at least minscale times the
        # line sigma (this causes dots etc. not to blow up ridiculously large)
        scale = f * h / (4 * max(cs, minscale * ls))
        m = diag([1.0 / scale, 1.0 / scale])
        offset = array([cy, cx]) - dot(m, array([h / 2, w / 2]))

        def transform(image, m=m, offset=offset):
            return interpolation.affine_transform(1.0 * image,
                                                  m,
                                                  offset=offset,
                                                  order=1,
                                                  output_shape=(h, w))

        def itransform_add(result, image, m=m, cx=cx, cy=cy):
            im = inv(m)
            ioffset = array([h / 2, w / 2]) - dot(im, array([cy, cx]))
            result += interpolation.affine_transform(
                1.0 * image,
                im,
                offset=ioffset,
                order=1,
                output_shape=segmentation.shape)

        cimage = transform(sub)
        yield cimage, transform, itransform_add
Example #14
0
def binary_objects(binary):
    labels, n = morph.label(binary)
    objects = morph.find_objects(labels)
    return objects
Example #15
0
def binary_objects(binary):
    labels,n = morph.label(binary)
    objects = morph.find_objects(labels)
    return objects