Esempio n. 1
0
 def __init__(self, allccs, indices):
     self.ccs = allccs
     self.indices = indices
     if len(indices) == 1:
         self.rect = Rect(allccs[indices[0]])
     else:
         self.rect = allccs[indices[0]].union_images([allccs[i] for i in indices])
Esempio n. 2
0
   def __init__(self, run):
      Rect.__init__(run)
      # The number of black pixels in the section
      self.area = 0
      # The average vertical thickness of all the runs in the section
      self.average_thickness = 0.0
      # The runs that make up the section.  Each run is a Rect object as
      # returned by the iterate_*_*_runs plugin method.
      self.runs = []
      # The center points of all the runs.  The points together make
      # up a line down the center of the section.
      self.center_points = []
      # The number of connected sections to the right
      self.right_connections = []
      # The number of connected sections to the left
      self.left_connections = []
      # Marked True by find_potential_stafflines if the section appears to be a thin, straight, horizontal line
      self.is_filament = False
      # Marked True by find_stafflines if the section is part of an evenly spaced set of sections
      self.is_staffline_marker = False
      # Marked True by remove_stafflines if the section is aligned with a recognized staffline
      self.is_staffline = False

      # Add the first run
      self.add_run(run)
   def __init__(self, run):
      Rect.__init__(self, run)
      # The number of black pixels in the section
      self.area = 0
      # The average vertical thickness of all the runs in the section
      self.average_thickness = 0.0
      # The runs that make up the section.  Each run is a Rect object as
      # returned by the iterate_*_*_runs plugin method.
      self.runs = []
      # The center points of all the runs.  The points together make
      # up a line down the center of the section.
      self.center_points = []
      # The number of connected sections to the right
      self.right_connections = []
      # The number of connected sections to the left
      self.left_connections = []
      # Marked True by find_potential_stafflines if the section appears to be a thin, straight, horizontal line
      self.is_filament = False
      # Marked True by find_stafflines if the section is part of an evenly spaced set of sections
      self.is_staffline_marker = False
      # Marked True by remove_stafflines if the section is aligned with a recognized staffline
      self.is_staffline = False

      # Add the first run
      self.add_run(run)
 def extend(self, Ex, Ey, img):
     ul_y = max(0, self.rect.ul_y - Ey)
     ul_x = max(0, self.rect.ul_x - Ex)
     lr_y = min(img.lr_y, self.rect.lr_y + Ey)
     lr_x = min(img.lr_x, self.rect.lr_x + Ex)
     nrows = lr_y - ul_y + 1
     ncols = lr_x - ul_x + 1
     self.rect = Rect(Point(ul_x, ul_y), Dim(ncols, nrows))
Esempio n. 5
0
   def get_staffpos(self, x=-1):
      """Returns the y-positions of all staff lines at a given x-position.
Can only be called *after* ``remove_staves``.

Signature:

  ``get_staffpos(x=0)``

Since the lines are modelled as connected sets of non-horizontal line segments,
*x* is relevant to the result.

The return value is a list of `StaffObj`__.

.. __: gamera.toolkits.musicstaves.musicstaves.StaffObj.html#staffobj
"""
      if self.stafflines is None:
         raise RuntimeError("You must call remove_staves before get_staffpos")

      result = []
      if x == -1:
         x = self.image.ncols / 2
      for i, staff in enumerate(self.stafflines.staves.values()):
         staff_result = StaffObj()
         staff_result.staffno = i
         for line in staff:
            staff_result.yposlist.append(self.stafflines.linear_interpolate(x, line))
         staff_result.staffrect = Rect(staff[0][0], staff[-1][-1])
         result.append(staff_result)
      return result
Esempio n. 6
0
 def __init__(self, allccs, indices):
     self.ccs = allccs
     self.indices = indices
     if len(indices) == 1:
         self.rect = Rect(allccs[indices[0]])
     else:
         self.rect = allccs[indices[0]].union_images([allccs[i] for i in indices])
def parse_bbox(stringIn):
    from gamera.core import Rect
    from gamera.core import Point
    dimensions = stringIn.split()
    if not dimensions[0] == 'bbox' or not len(dimensions) == 5:
        raise ValueError('bounding box not in proper format: "%s"'%dimensions)
    a_rect = Rect(Point(int(dimensions[1]),int(dimensions[2])),Point(int(dimensions[3]),int(dimensions[4])))
    return (a_rect)#dimensions[1:])
Esempio n. 8
0
 def extend(self, Ex, Ey, img):
     ul_y = max(0, self.rect.ul_y - Ey)
     ul_x = max(0, self.rect.ul_x - Ex)
     lr_y = min(img.lr_y, self.rect.lr_y + Ey)
     lr_x = min(img.lr_x, self.rect.lr_x + Ex)
     nrows = lr_y - ul_y + 1
     ncols = lr_x - ul_x + 1
     self.rect = Rect(Point(ul_x, ul_y), Dim(ncols, nrows))
Esempio n. 9
0
 class Bbox:
     def __init__(self, allccs, indices):
         self.ccs = allccs
         self.indices = indices
         if len(indices) == 1:
             self.rect = Rect(allccs[indices[0]])
         else:
             self.rect = allccs[indices[0]].union_images([allccs[i] for i in indices])
     def extend(self, Ex, Ey, img):
         ul_y = max(0, self.rect.ul_y - Ey)
         ul_x = max(0, self.rect.ul_x - Ex)
         lr_y = min(img.lr_y, self.rect.lr_y + Ey)
         lr_x = min(img.lr_x, self.rect.lr_x + Ex)
         nrows = lr_y - ul_y + 1
         ncols = lr_x - ul_x + 1
         self.rect = Rect(Point(ul_x, ul_y), Dim(ncols, nrows))
     def merge(self, other):
         self.indices += other.indices
         self.rect.union(other.rect)
Esempio n. 10
0
def Fudge(o, amount=FUDGE_AMOUNT):
    # For rectangles, just return a new rectangle that is slightly larger
    if isinstance(o, Rect):
        return Rect(Point(int(o.ul_x - amount), int(o.ul_y - amount)),
                    Dim(int(o.ncols + amount * 2), int(o.nrows + amount * 2)))

    # For integers, return one of our "fudge number proxies"
    elif isinstance(o, int):
        return FudgeInt(o, amount)
    elif isinstance(o, float):
        return FudgeFloat(o, amount)
Esempio n. 11
0
        class Bbox:
            def __init__(self, allccs, indices):
                self.ccs = allccs
                self.indices = indices
                if len(indices) == 1:
                    self.rect = Rect(allccs[indices[0]])
                else:
                    self.rect = allccs[indices[0]].union_images([allccs[i] for i in indices])

            def extend(self, Ex, Ey, img):
                ul_y = max(0, self.rect.ul_y - Ey)
                ul_x = max(0, self.rect.ul_x - Ex)
                lr_y = min(img.lr_y, self.rect.lr_y + Ey)
                lr_x = min(img.lr_x, self.rect.lr_x + Ex)
                nrows = lr_y - ul_y + 1
                ncols = lr_x - ul_x + 1
                self.rect = Rect(Point(ul_x, ul_y), Dim(ncols, nrows))

            def merge(self, other):
                self.indices += other.indices
                self.rect.union(other.rect)
   def __init__(self, filament):
      Rect.__init__(self, filament)

      self.is_staffline_marker = False
    def __call__(self,im_staffonly, n_gap, p_gap, n_shift, random_seed=0, add_noshift=False ):
        from gamera.core import RGBPixel,Point,FloatPoint,Rect
        from gamera.toolkits.musicstaves.stafffinder import StafflineSkeleton
        seed(random_seed)
        bnp_gap=binomial(n_gap,p_gap)
        bnp_shift=binomial(n_shift,0.5)
        im_full=self.image_copy()
        im_staffless=im_full.xor_image(im_staffonly)
        im_staffonly=im_staffonly.image_copy()
        il_shifts=[im_staffless,im_staffonly,im_full]
        il_breaks=il_shifts
        if add_noshift:
            ns_full=im_full.image_copy()
            ns_staffonly=im_staffonly.image_copy()
            il_breaks=[im_staffless,im_staffonly,im_full,ns_full,ns_staffonly]
        
        #find stafflines
        [first_x, last_x, stafflines, thickness]=find_stafflines_int(im_staffonly)

        #find breaks (where are the symbols?)
        stafflinedist=stafflines[1]-stafflines[0]
        staffline_skel=[]
        for sl in range(len(stafflines)):
            if sl==0 or stafflines[sl]-stafflines[sl-1]>3*stafflinedist:
                #first staffline of a system
                first_line=stafflines[sl]
                lines_per_system=0

            lines_per_system=lines_per_system+1

            if sl==len(stafflines)-1 or stafflines[sl+1]-stafflines[sl]>3*stafflinedist:
                #last staffline of a system
                last_line=stafflines[sl]
                # a hoizontal projection of the symbols helps us to find the x positions of the symbols.
                syst=im_staffless.subimage(Point(0,max((0,first_line-3*stafflinedist))),Point(im_staffless.width,min((last_line+3*stafflinedist,im_full.lr_y-1))))
                symbolcols=syst.projection_cols()

                # collect the breaks, i.e. the mid of the white spaces between two symbols
                breaks=[]
                whiterun=False
                for col in range(len(symbolcols)):
                    if (not whiterun) and symbolcols[col]==0:
                        whiterun=True
                        runbegin=col
                    else:
                        if whiterun and symbolcols[col]>0:
                            whiterun=False
                            br=[(runbegin+col)/2,col-runbegin]
                            if br[0]>=first_x:
                                breaks.append(br)

                # replace the first break (before the first symbol) with a break at the beginning of the stafflines
                breaks[0]=[first_x,1]
                # and append a break after the last symbol
                if whiterun:
                    breaks.append([(last_x+runbegin)/2,last_x-runbegin])
                else:
                    breaks.append([last_x,1])

                # draw white lines at the breaks
                new_breaks=[]
                for br in breaks:
                    w=bnp_gap.random()
                    # draw line if it fits only
                    if w<br[1]:
                        for im in il_breaks:
                            im.draw_line(FloatPoint(br[0],first_line-stafflinedist),
                                         FloatPoint(br[0],last_line+stafflinedist),
                                         RGBPixel(0,0,0),
                                         w)
                        new_breaks.append(br)
                breaks=new_breaks
                skeleton=[]

                # do the vertical shift by making a temporary copy (orig_type), white them out (draw_filled_rect) and "or" them again in with a new y-position
                for t in range(len(breaks)-1):
                    vertical_shift=bnp_shift.random()-n_shift/2
                    typerect=Rect(Point(breaks[t][0],max((first_line-3*stafflinedist,0))),
                                  Point(breaks[t+1][0],min((last_line+3*stafflinedist,im_full.lr_y))))
                    moveto=Rect(Point(typerect.ul_x,
                                      typerect.ul_y+vertical_shift),
                                typerect.size)
                    if moveto.ul_y<0:
                        typerect.ul_y=typerect.ul_y-moveto.ul_y
                        moveto.ul_y=0
                    if moveto.lr_y>im_full.lr_y:
                        typerect.lr_y=typerect.lr_y-(moveto.lr_y-im_full.lr_y)
                        moveto.lr_y=im_full.lr_y

                    for im in il_shifts:
                        orig_type=im.subimage(typerect)
                        orig_type=orig_type.image_copy()
                        im.draw_filled_rect(typerect,RGBPixel(0,0,0))
                        im.subimage(moveto).or_image(orig_type,True)

                    # collect data for later construction of the skeletons
                    for line in range(lines_per_system):
                        if len(skeleton)<=line:
                            skeleton.append([])
                        st_line=stafflines[sl-lines_per_system+1+line]
                        y=st_line+vertical_shift
                        skeleton[line].append(Point(typerect.ul_x,y))
                        skeleton[line].append(Point(typerect.ur_x,y))

                # now construct the skeletons
                for sk in skeleton:
                    x=sk[0].x
                    y=sk[0].y
                    left_x=x
                    y_list=[]
                    i=1
                    while i<len(sk):
                        y_list.append(y)
                        if x>=sk[i].x:
                            y=sk[i].y
                            i=i+1
                        x=x+1
                    o=StafflineSkeleton()
                    o.left_x=left_x
                    o.y_list=y_list
                    staffline_skel.append(o)

        if add_noshift:
            return [im_full,im_staffonly,staffline_skel,ns_full,ns_staffonly]
        else:
            return [im_full,im_staffonly,staffline_skel]
Esempio n. 14
0
def expand_ccs(image,ccs,Ex,Ey):
    # two helper functions for merging rectangles
    def find_intersecting_rects(glyphs, index):
        g = glyphs[index]
        inter = []
        for i in range(len(glyphs)):
            if i == index:
                continue
            if g.intersects(glyphs[i]):
                inter.append(i)
        return inter
    def list_union_rects(big_rects):
        current = 0
        rects = big_rects
        while(1):
            inter = find_intersecting_rects(rects, current)
            if len(inter):
                g = rects[current]
                new_rects = [g]
                for i in range(len(rects)):
                    if i == current:
                        continue
                    if i in inter:
                        g.union(rects[i])
                    else:
                        new_rects.append(rects[i])
                rects = new_rects
                current = 0
            else:
                current += 1
            if(current >= len(rects)):
                break
        return rects

    # the actual plugin
    from gamera.core import Dim, Rect, Point, Cc
    from gamera.plugins.image_utilities import union_images
    page = image

    # extend CC bounding boxes
    big_rects = []
    for c in ccs:
        ul_y = max(0, c.ul_y - Ey)
        ul_x = max(0, c.ul_x - Ex)
        lr_y = min(page.lr_y, c.lr_y + Ey)
        lr_x = min(page.lr_x, c.lr_x + Ex)
        nrows = lr_y - ul_y + 1
        ncols = lr_x - ul_x + 1
        big_rects.append(Rect(Point(ul_x, ul_y), Dim(ncols, nrows)))
    extended_segs = list_union_rects(big_rects)

    # build new merged CCs
    tmplist = ccs[:]
    dellist = []
    seg_ccs = []
    seg_cc = []
    if(len(extended_segs) > 0):
        label = 1
        for seg in extended_segs:
            label += 1
            for cc in tmplist:
                if(seg.intersects(cc)):
                    # mark original image with segment label
                    #self.highlight(cc, label)
                    seg_cc.append(cc)
                    dellist.append(cc)
            if len(seg_cc) == 0:
                continue
            seg_rect = seg_cc[0].union_rects(seg_cc)
            new_seg = Cc(image, label, seg_rect.ul, seg_rect.lr)
            seg_cc = []
            for item in dellist:
                tmplist.remove(item)
            dellist = []
            seg_ccs.append(new_seg)
    return seg_ccs
Esempio n. 15
0
   def __init__(self, filament):
      Rect.__init__(filament)

      self.is_staffline_marker = False
Esempio n. 16
0
def generateCCsFromHocr(parser, image):
    from gamera.core import Point, Cc, Rect
    extended_segs = []
    for span in parser.spans:
        ##                print "line_span found:", span
        boxes = span.split(';')[0].split()
        point1 = Point(int(boxes[1]), int(boxes[2]))
        point2 = Point(int(boxes[3]), int(boxes[4]))
        try:
            extended_segs.append(Rect(point1, point2))
        except RuntimeError as e:
            #TODO we should do something here
            print e
            print "failed to make Cc from Hocr box: "
            print boxes
            pass
    page = image.image_copy()
    ccs = page.cc_analysis()
    #The following copied from bbox_merging. Simply making Ccs with
    #the appropriate dimensions does not seem to work, but did in a
    #previous version...
    #extended_segs are the line bboxes; ccs are the glyphs
    #found by page analysis
    # build new merged CCs
    tmplist = ccs[:]
    dellist = []
    seg_ccs = []
    seg_cc = []
    if (len(extended_segs) > 0):
        label = 1
        for seg in extended_segs:
            label += 1
            #        print "new line!"
            for cc in tmplist:
                #changed in this revision; the divisor used to be seg.height, that is, the line's height
                #avoid divbyzero error
                if cc.height > 0:
                    descender = (float(cc.lr_y - seg.lr_y) / float(cc.height))
                else:
                    descender = float(0)
#                       print "desc: ", str(descender), " downness: ", str(downness), " ccheight: ", str(cc.height)
#for more closed texts:
#this matches if:
# 1. 	the character's bottom is above the lines, or;
# 2.  	if the character is higher than half the line height
#		AND the portion of the character that goes below the line is less
#		than 20% of its total height.

#if(seg.intersects(cc) and ((cc.lr_y < seg.lr_y) or ((float(cc.height) > float(seg.height)/2.0) and (descender  < 0.2) )):
#for more open texts:
#if(seg.intersects(cc) and ((cc.lr_y < seg.lr_y) or (descender < 0.4)) ):
# mark original image with segment label

#new, experimental universal solution:

#This matches if:
#1. the character's bottom is above the line, or;
#2. The character's bottom is below the line, and the amount of the character that is below the line is less than 40% of its height
                if (seg.intersects(cc)
                        and ((cc.lr_y <= seg.lr_y) or ((cc.lr_y > seg.lr_y) and
                                                       (descender < 0.3)))):
                    #			  print "\tpassed"
                    image.highlight(cc, label)
                    seg_cc.append(cc)
                    dellist.append(cc)
            if len(seg_cc) == 0:
                #continue
                #try to output, rather than ignore, empty line
                #this should make alignment easier, but is it wise?
                seg_rect = seg
            else:
                seg_rect = seg_cc[0].union_rects(seg_cc)
            #TODO fix these errors, caused by new_seg being beyond the bounds of the image, I believe
            #They seem to appear with tesseract hocr output
            try:
                new_seg = Cc(image, label, seg_rect.ul, seg_rect.lr)
                seg_ccs.append(new_seg)
            except RuntimeError as e:
                print "HOCR ERROR -- failed to append segment"
                print e
            seg_cc = []
            for item in dellist:
                tmplist.remove(item)
            dellist = []
            #seg_ccs.append(new_seg)

    return seg_ccs
Esempio n. 17
0
    def __call__(self,
                 im_staffonly,
                 n_gap,
                 p_gap,
                 n_shift,
                 random_seed=0,
                 add_noshift=False):
        from gamera.core import RGBPixel, Point, FloatPoint, Rect
        from gamera.toolkits.musicstaves.stafffinder import StafflineSkeleton
        seed(random_seed)
        bnp_gap = binomial(n_gap, p_gap)
        bnp_shift = binomial(n_shift, 0.5)
        im_full = self.image_copy()
        im_staffless = im_full.xor_image(im_staffonly)
        im_staffonly = im_staffonly.image_copy()
        il_shifts = [im_staffless, im_staffonly, im_full]
        il_breaks = il_shifts
        if add_noshift:
            ns_full = im_full.image_copy()
            ns_staffonly = im_staffonly.image_copy()
            il_breaks = [
                im_staffless, im_staffonly, im_full, ns_full, ns_staffonly
            ]

        #find stafflines
        [first_x, last_x, stafflines,
         thickness] = find_stafflines_int(im_staffonly)

        #find breaks (where are the symbols?)
        stafflinedist = stafflines[1] - stafflines[0]
        staffline_skel = []
        for sl in range(len(stafflines)):
            if sl == 0 or stafflines[sl] - stafflines[sl -
                                                      1] > 3 * stafflinedist:
                #first staffline of a system
                first_line = stafflines[sl]
                lines_per_system = 0

            lines_per_system = lines_per_system + 1

            if sl == len(stafflines) - 1 or stafflines[
                    sl + 1] - stafflines[sl] > 3 * stafflinedist:
                #last staffline of a system
                last_line = stafflines[sl]
                # a hoizontal projection of the symbols helps us to find the x positions of the symbols.
                syst = im_staffless.subimage(
                    Point(0, max((0, first_line - 3 * stafflinedist))),
                    Point(
                        im_staffless.width,
                        min((last_line + 3 * stafflinedist,
                             im_full.lr_y - 1))))
                symbolcols = syst.projection_cols()

                # collect the breaks, i.e. the mid of the white spaces between two symbols
                breaks = []
                whiterun = False
                for col in range(len(symbolcols)):
                    if (not whiterun) and symbolcols[col] == 0:
                        whiterun = True
                        runbegin = col
                    else:
                        if whiterun and symbolcols[col] > 0:
                            whiterun = False
                            br = [(runbegin + col) / 2, col - runbegin]
                            if br[0] >= first_x:
                                breaks.append(br)

                # replace the first break (before the first symbol) with a break at the beginning of the stafflines
                breaks[0] = [first_x, 1]
                # and append a break after the last symbol
                if whiterun:
                    breaks.append([(last_x + runbegin) / 2, last_x - runbegin])
                else:
                    breaks.append([last_x, 1])

                # draw white lines at the breaks
                new_breaks = []
                for br in breaks:
                    w = bnp_gap.random()
                    # draw line if it fits only
                    if w < br[1]:
                        for im in il_breaks:
                            im.draw_line(
                                FloatPoint(br[0], first_line - stafflinedist),
                                FloatPoint(br[0], last_line + stafflinedist),
                                RGBPixel(0, 0, 0), w)
                        new_breaks.append(br)
                breaks = new_breaks
                skeleton = []

                # do the vertical shift by making a temporary copy (orig_type), white them out (draw_filled_rect) and "or" them again in with a new y-position
                for t in range(len(breaks) - 1):
                    vertical_shift = bnp_shift.random() - n_shift / 2
                    typerect = Rect(
                        Point(breaks[t][0],
                              max((first_line - 3 * stafflinedist, 0))),
                        Point(
                            breaks[t + 1][0],
                            min((last_line + 3 * stafflinedist,
                                 im_full.lr_y))))
                    moveto = Rect(
                        Point(typerect.ul_x, typerect.ul_y + vertical_shift),
                        typerect.size)
                    if moveto.ul_y < 0:
                        typerect.ul_y = typerect.ul_y - moveto.ul_y
                        moveto.ul_y = 0
                    if moveto.lr_y > im_full.lr_y:
                        typerect.lr_y = typerect.lr_y - (moveto.lr_y -
                                                         im_full.lr_y)
                        moveto.lr_y = im_full.lr_y

                    for im in il_shifts:
                        orig_type = im.subimage(typerect)
                        orig_type = orig_type.image_copy()
                        im.draw_filled_rect(typerect, RGBPixel(0, 0, 0))
                        im.subimage(moveto).or_image(orig_type, True)

                    # collect data for later construction of the skeletons
                    for line in range(lines_per_system):
                        if len(skeleton) <= line:
                            skeleton.append([])
                        st_line = stafflines[sl - lines_per_system + 1 + line]
                        y = st_line + vertical_shift
                        skeleton[line].append(Point(typerect.ul_x, y))
                        skeleton[line].append(Point(typerect.ur_x, y))

                # now construct the skeletons
                for sk in skeleton:
                    x = sk[0].x
                    y = sk[0].y
                    left_x = x
                    y_list = []
                    i = 1
                    while i < len(sk):
                        y_list.append(y)
                        if x >= sk[i].x:
                            y = sk[i].y
                            i = i + 1
                        x = x + 1
                    o = StafflineSkeleton()
                    o.left_x = left_x
                    o.y_list = y_list
                    staffline_skel.append(o)

        if add_noshift:
            return [
                im_full, im_staffonly, staffline_skel, ns_full, ns_staffonly
            ]
        else:
            return [im_full, im_staffonly, staffline_skel]
 def __init__(self):
    Rect.__init__(self)
Esempio n. 19
0
 def rspikes(self, width, height_threshold=None):
     return [ Rect((0,s['start']),(width,s['stop'])) \
             for s in self.spikes(height_threshold)
            ]
Esempio n. 20
0
 def __init__(self):
    Rect.__init__(self)