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. 2
0
    def to_polygon(self, tolerance=0):
        """Converts to ``StafflinePolygon``.

The optional parameter *tolerance* is offered for compatibility to
``StafflineSkeleton``, but has no effect on the return value.
"""
        pg = StafflinePolygon()
        pg.vertices += [
            Point(self.left_x, self.average_y),
            Point(self.right_x, self.average_y)
        ]
        return pg
    def __call__(current, parameters, t_end, dt_end=0.0, direction=1):
        from gamera.core import Point
        fv = _skeleton_utilities.estimate_next_point(current, parameters,\
            t_end, dt_end, direction)
        p = Point(int(fv[0]), int(fv[1]))

        return [p, fv[2], fv[3]]
 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 __call__(array, offset=None):
     from gamera.plugins import _string_io
     from gamera.core import Point, Dim
     if offset is None:
         offset = Point(0, 0)
     pixel_type = from_numarray._check_input(array)
     return _string_io._from_raw_string(
         offset, Dim(array.shape[1], array.shape[0]), pixel_type, DENSE,
         array.tostring())
Esempio n. 6
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)
class estimate_next_point(PluginFunction):
    """Estimates the next point on a given parabola.

Arguments:
  *current*
    The current point, which has to lie on the parabola.

  *parameters*
    The parameters [ax, ay, bx, by, cx, cy] that describe a parametric
    parabola (see parabola_).

  *t_end*
    The distance of the current point to the first point (see parabola_ for
    a possible computation).

  *dt_end*
    The distance of the current point to the previous one. When set to
    the default value, it will be estimated automatically.

  *direction*
    The direction where to go. This option is not supported yet.

The return value is the vector [p, t_end, dt_end] where

  *p* is the estimated point,

  *t_end* is the distance of the estimated point to the first point,

  *dt_end* is the distance of the estimated point to the current point.

.. code:: Python

    # calculate the parameters of the parabola and estimate the following point
    parameters, t_end = parabola(points)
    next_point, t_new, dt_new = estimate_next_point(points[-1], parameters, t_end)
"""
    category = "MusicStaves/Skeleton_utilities"
    self_type = None
    args = Args([Point('current'), FloatVector('parameters'), Float('t_end'),\
            Float('dt_end', default=0.0), Int('direction', default=1)])
    return_type = FloatVector('ret_value')
    author = "Thomas Karsten"

    def __call__(current, parameters, t_end, dt_end=0.0, direction=1):
        from gamera.core import Point
        fv = _skeleton_utilities.estimate_next_point(current, parameters,\
            t_end, dt_end, direction)
        p = Point(int(fv[0]), int(fv[1]))

        return [p, fv[2], fv[3]]

    __call__ = staticmethod(__call__)
    def __call__(self, im_staffonly, ratio):
        from gamera.core import Image, RGBPixel, Point
        from gamera.toolkits.musicstaves.stafffinder import StafflineSkeleton
        im_full = self
        im_staffless = im_full.xor_image(im_staffonly)
        [first_x, last_x, stafflines,
         thickness] = find_stafflines_int(im_staffonly)

        # ratio=staffline_height/staffspace_height
        thickness = (stafflines[1] - stafflines[0]) / (1 / ratio + 1)
        im_newlines = Image(im_full.ul, im_full.size)

        # we just draw the lines ourselves
        for y in stafflines:
            im_newlines.draw_line(Point(first_x, y), Point(last_x, y),
                                  RGBPixel(255, 255, 255), thickness)

        # new full: lines OR symbols
        def_full = im_staffless.or_image(im_newlines)
        # new staffonly: lines AND NOT symbols
        def_staffonly = im_staffless.image_copy()
        def_staffonly.invert()
        def_staffonly.and_image(im_newlines, True)
        # staffless image doesn't change
        def_staffless = im_staffless.image_copy()

        # construct skeletons
        staffline_skel = []
        for y in stafflines:
            skel = StafflineSkeleton()
            skel.left_x = first_x
            # all stafflines are completely straight
            skel.y_list = (last_x - first_x + 1) * [y]
            staffline_skel.append(skel)

        return [def_full, def_staffonly, staffline_skel]
Esempio n. 9
0
 def __call__(image, offset=None):
     from gamera.plugins import _string_io
     from gamera.core import Dim, Point
     typecode = image.mode
     if offset is None:
         offset = Point(0, 0)
     if _inverse_modes.has_key(typecode):
         pixel_type = _inverse_modes[typecode]
     else:
         raise ValueError(
             "Only RGB and 8-bit Greyscale 'L' PIL image modes are supported."
         )
     return _string_io._from_raw_string(
         offset, Dim(image.size[0], image.size[1]), pixel_type, DENSE,
         image.tostring())
Esempio n. 10
0
 def __call__(image, offset=None):
     from gamera.plugins import _string_io
     from gamera.core import Dim, Point
     typecode = image.mode
     if offset is None:
         offset = Point(0, 0)
     if typecode in _inverse_modes:
         pixel_type = _inverse_modes[typecode]
     else:
         raise ValueError(
             "Only RGB and 8-bit Greyscale 'L' PIL image modes are supported."
         )
     try:
         return _string_io._from_raw_string(
             offset, Dim(image.size[0], image.size[1]), pixel_type,
             DENSE, image.tobytes())
     except Exception:
         # for compatibility with pil 1.1.7 and earlier
         return _string_io._from_raw_string(
             offset, Dim(image.size[0], image.size[1]), pixel_type,
             DENSE, image.tostring())
Esempio n. 11
0
    def __call__(image, offset=None):
        from gamera.plugins import _string_io
        from gamera.core import Dim, Point, RGBPixel

        if offset is None:
            offset = Point(0, 0)
        if isinstance(image, cv.cvmat):
            imgcv = cv.CloneMat(image)
            cv.CvtColor(image, imgcv, cv.CV_BGR2RGB)
            return _string_io._from_raw_string(offset,
                                               Dim(imgcv.cols, imgcv.rows),
                                               RGB, DENSE, imgcv.tostring())
        elif isinstance(image, cv.iplimage):
            imgcv = cv.CreateImage(cv.GetSize(image), image.depth,
                                   image.channels)
            cv.CvtColor(image, imgcv, cv.CV_BGR2RGB)
            return _string_io._from_raw_string(offset,
                                               Dim(imgcv.width, imgcv.height),
                                               RGB, DENSE, imgcv.tostring())
        else:
            raise TypeError("Image must be of type cv.cvmat or cv.iplimage")
Esempio n. 12
0
 def get_control(self, parent, locals=None):
     from gamera.core import Point
     default = Point(self.default)
     self.control = wx.BoxSizer(wx.HORIZONTAL)
     self.control.Add(wx.StaticText(parent, -1, "x:"))
     self.control_x = wx.SpinCtrl(parent,
                                  -1,
                                  value=str(default.x),
                                  min=-DEFAULT_MAX_ARG_NUMBER,
                                  max=DEFAULT_MAX_ARG_NUMBER,
                                  initial=default.x)
     self.control_x.SetValidator(_IntValidator(name=self.name))
     self.control.Add(self.control_x, 1, wx.EXPAND | wx.LEFT | wx.RIGHT, 5)
     self.control.Add(wx.StaticText(parent, -1, "y:"))
     self.control_y = wx.SpinCtrl(parent,
                                  -1,
                                  value=str(default.y),
                                  min=-DEFAULT_MAX_ARG_NUMBER,
                                  max=DEFAULT_MAX_ARG_NUMBER,
                                  initial=default.y)
     self.control_y.SetValidator(_IntValidator(name=self.name))
     self.control.Add(self.control_y, 1, wx.EXPAND | wx.LEFT, 5)
     return self
Esempio n. 13
0
 def set_stafflines(self, stafflines):
    new_rect = self.union_rects(stafflines)
    self.rect_set(Point(new_rect.ul_x, new_rect.ul_y), Dim(new_rect.ncols, new_rect.nrows))
    self.stafflines = stafflines
    for staffline in stafflines:
       staffline.set_as_staffline()
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 get(self):
     from gamera.core import Point
     return Point(int(self.control_x.GetValue()),
                  int(self.control_y.GetValue()))
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]
Esempio n. 18
0
    def show_result(self, highlight_groups=True):
        """Returns an RGB image with the found staff lines highlighted.

Parameters:

  *highlight_groups*:
    when *True* (default), each stave system is underlayed in a different
    color. When false, only the edge points are marked in different colors,
    which is less visible for skeleton or average staff line representation.
"""
        rgb = Image(self.image, RGB)
        if highlight_groups:
            # highlight staff systems
            for staffno, staff in enumerate(self.linelist):
                if not staff:
                    continue
                staffcolor = RGBPixel(190 + (11*staffno) % 66, \
                                      190 + (31*(staffno + 1)) % 66, \
                                      190 + (51*(staffno + 2)) % 66)
                topline = staff[0].to_average()
                botline = staff[-1].to_average()
                leftx = min([topline.left_x, botline.left_x])
                rightx = max([topline.right_x, botline.right_x])
                topy = topline.average_y
                boty = botline.average_y
                border = max(
                    [self.staffspace_height / 2, self.staffline_height * 4])
                if leftx - border > 0:
                    leftx -= border
                if rightx + border < rgb.ncols:
                    rightx += border
                if topy - border > 0:
                    topy -= border
                if boty + border < rgb.nrows:
                    boty += border
                rgb.draw_filled_rect((leftx, topy), (rightx, boty), staffcolor)

        # draw original image
        rgb.highlight(self.image, RGBPixel(0, 0, 0))

        for staffno, staff in enumerate(self.linelist):
            if not staff:
                continue
            if highlight_groups:
                staffcolor = RGBPixel(255, 0, 0)
            else:
                staffcolor = RGBPixel((53*(staffno)) % 256,\
                                      (111*(staffno+1)) % 256,\
                                      (111*(staffno+2)) % 256)

            for line in staff:
                if isinstance(line, StafflinePolygon):
                    lastp = None
                    for p in line.vertices:
                        rgb.draw_marker(p,self.staffline_height*2,3,\
                                        staffcolor)
                        if lastp:
                            rgb.draw_line(lastp, p, RGBPixel(255, 0, 0))
                        lastp = p
                elif isinstance(line, StafflineAverage):
                    rgb.draw_line(Point(0,line.average_y),\
                                  Point(rgb.ncols,line.average_y),\
                                  RGBPixel(255,0,0))
                    rgb.draw_marker(Point(line.left_x,line.average_y),\
                                    self.staffline_height*2,3,\
                                    staffcolor)
                    rgb.draw_marker(Point(line.right_x,line.average_y),\
                                    self.staffline_height*2,3,\
                                    staffcolor)
                elif isinstance(line, StafflineSkeleton):
                    # doing this in Python might be too slow,
                    # implement it in C++ later
                    x = line.left_x
                    for y in line.y_list:
                        rgb.set(Point(x, y), RGBPixel(255, 0, 0))
                        x += 1
                    if len(line.y_list) > 0:
                        rgb.draw_marker(Point(line.left_x,line.y_list[0]),\
                                        self.staffline_height*2,3,\
                                        staffcolor)
                        rgb.draw_marker(Point(x-1,line.y_list[-1]),\
                                        self.staffline_height*2,3,\
                                        staffcolor)
        return rgb