def __call__(self, minimum_y_threshold=10, num_searches=4, negative_bound=10, postive_bound=10, thickness_above=0, thickness_below=0): from gamera.core import RGBPixel # Do analysis. result = lyric_extractor_helper.extract_lyric_ccs( self, minimum_y_threshold, num_searches, negative_bound, postive_bound, thickness_above, thickness_below) # Check color input. neumeColour = RGBPixel(0, 255, 0) lyricColour = RGBPixel(255, 0, 0) # Prepare output image. returnImage = self.to_rgb() # Do highlighting. for cc in set(result[0]) - set(result[1]): returnImage.highlight(cc, lyricColour) for cc in set(result[1]): returnImage.highlight(cc, neumeColour) return returnImage
def without(self): """ Create an image where text and classified are whited out""" ret = self.color_segment(other_color=RGBPixel(0, 0, 0), text_color=RGBPixel(255, 255, 255), instaff_color=RGBPixel(0, 0, 0), classified_color=RGBPixel(255, 255, 255)) return ret
def __call__(self, other): from gamera.core import RGBPixel result = self.to_rgb() diff = self.subtract_images(other) result.highlight(diff, RGBPixel(255, 64, 64)) diff = other.subtract_images(self) result.highlight(diff, RGBPixel(64, 255, 64)) return result
def __doc_example1__(images): image = images[ONEBIT] ccs = image.cc_analysis() voronoi = image.voronoi_from_labeled_image() voronoi_cells = voronoi.color_ccs() voronoi_cells.highlight(image, RGBPixel(0, 0, 0)) voronoi_edges = voronoi.labeled_region_edges() voronoi_cells.highlight(voronoi_edges, RGBPixel(255, 255, 255)) return [image, voronoi_cells]
def __doc_example1__(images): from random import randint from gamera.core import Image, Dim image = Image((0, 0), Dim(100, 100), RGB, DENSE) points = [(randint(0, 100), randint(0, 100)) for x in range(4)] image.draw_bezier(*tuple(list(points) + [RGBPixel(255, 0, 0), 0.1])) image.draw_marker(points[0], 7, 0, RGBPixel(0, 0, 255)) image.draw_marker(points[1], 7, 1, RGBPixel(0, 255, 0)) image.draw_marker(points[2], 7, 1, RGBPixel(0, 255, 0)) image.draw_marker(points[3], 7, 0, RGBPixel(0, 0, 255)) return image
def __call__(self, im_staffonly, angle): from gamera.core import RGBPixel from gamera.toolkits.musicstaves.stafffinder import StafflineSkeleton im_full = self im_staffless = im_full.xor_image(im_staffonly) # let someone else do the work for us # we use -angle because rotate() uses the wrong direction rot_staffonly = im_staffonly.rotate(-angle, RGBPixel(0, 0, 0)) rot_full = im_full.rotate(-angle, RGBPixel(0, 0, 0)) def apply_transformation(mat, pt): return [ pt[0] * mat[0] + pt[1] * mat[1] + mat[2], pt[0] * mat[3] + pt[1] * mat[4] + mat[5] ] # find offset by which the image is moved while rotating it m = [ cos(angle * pi / 180), sin(angle * pi / 180), 0, -sin(angle * pi / 180), cos(angle * pi / 180), 0 ] pts_orig = [[0, 0], [im_full.width - 1, 0], [0, im_full.height - 1], [im_full.width - 1, im_full.height - 1]] pts = [apply_transformation(m, p) for p in pts_orig] m[2] = -min([p[0] for p in pts]) m[5] = -min([p[1] for p in pts]) # find the stafflines in the original image [first_x, last_x, stafflines, thickness] = find_stafflines_int(im_staffonly) # rotate/move them and wrap them inside a list of StafflineSkeleton objects staffline_skel = [] for y in stafflines: startpt = apply_transformation(m, [first_x, y]) endpt = apply_transformation(m, [last_x, y]) # swap point, if the rotation was so hard, that what was left is now right (ie. angle>90 or <-90) if startpt[0] > endpt[0]: tempswap = startpt startpt = endpt endpt = tempswap o = StafflineSkeleton() o.left_x = startpt[0] o.y_list = [startpt[1]] ty = startpt[1] dy = (endpt[1] - startpt[1]) / (endpt[0] - startpt[0]) for n in range(int(round(endpt[0] - startpt[0]))): ty = ty + dy o.y_list.append(ty) staffline_skel.append(o) return [rot_full, rot_staffonly, staffline_skel]
def color_segment(self,text_color=RGBPixel(255,255,0),\ instaff_color=RGBPixel(0,255,0),\ other_color=RGBPixel(100,100,100), classified_color=None, classified_box=False): """ Segment image in three with colors Segment the image into three parts: - text - inside staff - Others/relevant for Classifier Keyword arguments: text_color --- What color to use for text ccs instaff_color --- The color to use for in-staff ccs other_color --- The color of the rest. classified_color --- If set we will try to classify stuff in the image and give them the given color classified_box --- If set we will try to classify and but instead of highlight I will box them. """ ret = self.to_rgb().to_onebit().to_rgb() classify = False if not (classified_color is None and classified_box is None): classify = True if classified_color is None: classified_color = RGBPixel(255, 0, 0) text, instaff, other, classified = self.segment(classify=classify) # Painting inside staff things green for c in instaff: ret.highlight(c, instaff_color) # Painting relevant ccs' red. for c in other: ret.highlight(c, other_color) for c in classified: if classified_box: outline(ret, c, width=2.0, color=classified_color) else: ret.highlight(c, classified_color) # Painting text yellow for c in text: ret.highlight(c, text_color) return ret
def __call__(self, im_staffonly, alpha, n, p=0.5, random_seed=0): from gamera.core import RGBPixel, FloatPoint from gamera.toolkits.musicstaves.stafffinder import StafflineSkeleton seed(random_seed) im_full = self im_staffless = im_full.xor_image(im_staffonly) def_staffonly = im_staffonly.image_copy() [first_x, last_x, stafflines, thickness] = find_stafflines_int(im_staffonly) bnp = binomial(n, p) # walk along all pixels of all stafflines for y in stafflines: for x in range(first_x, last_x): # now do the russian roulette if random() < alpha: w = bnp.random() if w > 0: def_staffonly.draw_filled_rect( FloatPoint(x - w / 2, y - thickness), FloatPoint(x + w / 2 + w % 2 - 1, y + thickness), RGBPixel(0, 0, 0)) def_full = im_staffless.or_image(def_staffonly) # construct skeletons (in fact they didn't change) 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]
def __doc_example1__(images): from random import randint, seed from gamera.core import Image, Dim seed(0) image = Image((0, 0), Dim(320, 300), RGB, DENSE) # These are some various Unicode encoded names of different # languages (from the wikipedia.org front page). Just a quick way # to test Unicode support. I use the long encoding here so this # source file iteself will be portable. names = [ '\xd0\x91\xd1\x8a\xd0\xbb\xd0\xb3\xd0\xb0\xd1\x80\xd1\x81\xd0\xba\xd0\xb8', '\xd7\xa2\xd7\x91\xd7\xa8\xd7\x99\xd7\xaa', '\xd8\xa7\xd9\x84\xd8\xb9\xd8\xb1\xd8\xa8\xd9\x8a\xd8\xa9', '\xc4\x8cesk\xc3\xa1', 'Rom\xc3\xa2n\xc4\x83', '\xe1\x83\xa5\xe1\x83\x90\xe1\x83\xa0\xe1\x83\x97\xe1\x83\xa3\xe1\x83\x9a\xe1\x83\x98', '\xd0\x9c\xd0\xb0\xd0\xba\xd0\xb5\xd0\xb4\xd0\xbe\xd0\xbd\xd1\x81\xd0\xba\xd0\xb8', '\xc3\x8dslenska', 'Lietuvi\xc5\xb3', 'T\xc3\xbcrk\xc3\xa7e' ] try: for i, name in enumerate(names): image.draw_text((160, i * 30), name, RGBPixel(randint(0, 255), randint(0, 255), randint(0, 255)), 20, halign=1) except Exception: pass return image
class rotate(PluginFunction): """ Rotates an image. *angle* The angle of rotation (in degrees) *bgcolor* The color to use for pixels outside of the original image bounds. When *bgcolor* is ``None``, white is used. *order* The order of the spline used for interpolation. Must be between 1 - 3. """ category = "Transformation" self_type = ImageType(ALL) return_type = ImageType(ALL) args = Args([Float("angle"), Pixel("bgcolor", default=NoneDefault), Int("order", range=(1,3), default=1)]) args.list[0].rng = (-180,180) doc_examples = [(RGB, 32.0, RGBPixel(255, 255, 255), 3), (COMPLEX, 15.0, 0.0j, 3)] author = u"Michael Droettboom (With code from VIGRA by Ullrich K\u00f6the)" def __call__(self, angle, bgcolor=None, order=1): if (bgcolor == None): bgcolor = self.white() return _transformation.rotate(self, angle, bgcolor, order) __call__ = staticmethod(__call__)
def highlight_words(self): ret = self._orig.to_rgb() img = self.without_insidestaves_info().image_copy() ccs = img.cc_analysis() words = self._text()._words(img, ccs) [ret.draw_hollow_rect(c, RGBPixel(255, 0, 0)) for c in words] return ret
def __doc_example1__(images): from random import randint from gamera.core import Image, Dim image = Image((0, 0), Dim(100, 100), RGB, DENSE) for i in range(10): image.draw_circle((randint(0, 100), randint(0, 100)), randint(0, 100), RGBPixel(randint(0, 255), randint(0, 255), randint(0, 255)), 1.0, 0.1) return image
def __doc_example1__(images): from gamera.core import Image from gamera.core import Point as P img = Image((0, 0), (90, 90)) points = [ P(10, 10), P(20, 30), P(32, 22), P(85, 14), P(40, 70), P(80, 85) ] for p in points: img.draw_filled_rect((p.x - 2, p.y - 2), (p.x + 1, p.y + 1), 1) r = img.max_empty_rect() rgb = img.to_rgb() rgb.draw_hollow_rect(r, RGBPixel(255, 0, 0)) rgb.highlight(img, RGBPixel(0, 0, 0)) return [rgb]
def highlight_possible_text(self, image=None): if image is None: ret = self._orig.to_rgb() else: ret = image spikes = self._text()._possible_text_areas() [ ret.draw_hollow_rect((0,s['start']),(ret.width-1,s['stop']),RGBPixel(255,0,0))\ for s in spikes ] return ret
def __doc_example1__(images): from random import randint, seed from gamera.core import Image, Dim seed(0) image = Image((0, 0), Dim(100, 100), RGB, DENSE) for i in range(10): image.draw_filled_rect((randint(0, 100), randint(0, 100)), (randint(0, 100), randint(0, 100)), RGBPixel(randint(0, 255), randint(0, 255), randint(0, 255))) return image
def __call__(self, im_staffonly, min, max, c=0.5, random_seed=0): from gamera.core import Image, RGBPixel from gamera.toolkits.musicstaves.stafffinder import StafflineSkeleton seed(random_seed) im_full = self im_staffless = im_full.xor_image(im_staffonly) [first_x, last_x, stafflines, thickness] = find_stafflines_int(im_staffonly) def_staffonly = Image(im_full.ul, im_full.size) # state machine for the thickness states = states_mh(max - min + 1, c) # draw the deformed stafflines in a blank image last_thickness = 0 even_shift = 0 for l in range(len(stafflines)): y = stafflines[l] for x in range(first_x, last_x + 1): thickness = states.next() + min y_st = y - thickness / 2 if thickness % 2 == 0: if thickness != last_thickness: if random() < 0.5: even_shift = 1 else: even_shift = 0 y_st = y_st + even_shift if thickness > 0: def_staffonly.draw_line((x, y_st), (x, y_st + thickness - 1), RGBPixel(255, 255, 255)) last_thickness = thickness # stafflines = stafflines AND NOT symbols im_staffless_invert = im_staffless.image_copy() im_staffless_invert.invert() def_staffonly.and_image(im_staffless_invert, True) # full = symbols OR stafflines def_full = im_staffless.image_copy() def_full.or_image(def_staffonly, True) # construct skeletons (in fact they didn't change) 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]
def with_row_projections(self, color=RGBPixel(200, 50, 50), image=None, ret=None, fac=None): if ret is None: ret = self._orig.to_rgb() if image is None: image = self.without_insidestaves_info() p = image.projection_rows() # l = [ (v,i) for i,v in enumerate(p) ] #[ ret.draw_line( (0,i[1]), (i[0],i[1]),color) for i in l] self.draw_y_proj(p, image=ret, color=color, fac=None) return ret
def __call__(image, ccs, colors=None, method=1, unique=False): if colors == None: from gamera.core import RGBPixel colors = [ RGBPixel(150, 0, 0), RGBPixel(0, 250, 0), RGBPixel(0, 0, 255), RGBPixel(250, 0, 255), RGBPixel(50, 150, 50), #RGBPixel(120, 120, 120), #RGBPixel(250, 250, 0), RGBPixel(0, 190, 255), RGBPixel(230, 190, 20), ] return _geometry.graph_color_ccs(image, ccs, colors, method, unique)
def draw_y_proj(self, rl, image=None, color=RGBPixel(255, 0, 0), norm=True, side="left", fac=None): """ Draw projections on the y-axis on top of an image *rl*: the projection data. One value for each y-value in the image *image*: The image to draw upon. Defaults to use this image in rgb edition *color*: The color to draw with. *norm*: Should the projections be normalized so that the longest value is a page wide?. Defaults to true. *side*: Unused for now. From which side should the projections be drawn. Left/Right. default left. *fac*: Factor to normalize by. """ if image is None: image = self.to_rgb() assert len(rl) == image.nrows if norm: if fac is None: fac = int(image.ncols / max(rl)) elif fac < 1: fac = int((image.ncols / max(rl)) * fac) rl = [fac * r for r in rl] l = [(v, i) for i, v in enumerate(rl)] [image.draw_line((0, i[1]), (i[0], i[1]), color) for i in l] return image
def highlight_text_by_hist(self, bc=5, f=lambda c: c.aspect_ratio()[0]): import matplotlib.pyplot as plt from random import randint ret = self._orig.to_rgb() ccs = self._text().possible_text_ccs() l = [f(c) for c in ccs] n, bins, patches = plt.hist(l, bc) colors = [RGBPixel(255, c, c) for c in xrange(0, 255, int(255 / bc))] nv = [(v, i) for i, v in enumerate(n)] nv.sort(reverse=True) nv = [(v, origi, colors[i]) for i, (v, origi) in enumerate(nv)] for v, i, color in nv: [ ret.highlight(c,color) for c in ccs \ if f(c) >= bins[i] and f(c) <= bins[i+1] ] i = 0 [ ret.draw_hollow_rect(c, colors[0]) for c in ccs if f(c) >= bins[i] and f(c) <= bins[i + 1] ]
def __call__(self, im_staffonly, maxdiff, c=0.5, random_seed=0): from gamera.core import Image, RGBPixel from gamera.toolkits.musicstaves.stafffinder import StafflineSkeleton seed(random_seed) im_full = self im_staffless = im_full.xor_image(im_staffonly) [first_x, last_x, stafflines, thickness] = find_stafflines_int(im_staffonly) def_staffonly = Image(im_full.ul, im_full.size) states = states_mh(2 * maxdiff + 1, c) m = (thickness - 1) / 2 if (thickness and 1) == 1: p = m else: p = m + 1 staffline_skel = [] for l in range(len(stafflines)): y = stafflines[l] - maxdiff skel = StafflineSkeleton() skel.left_x = first_x skel.y_list = (last_x - first_x + 1) * [y] for x in range(first_x, last_x + 1): y_l = y + states.next() skel.y_list[x - first_x] = y_l def_staffonly.draw_line((x, y_l - m), (x, y_l + p), RGBPixel(255, 255, 255)) staffline_skel.append(skel) im_staffless_invert = im_staffless.image_copy() im_staffless_invert.invert() def_staffonly.and_image(im_staffless_invert, True) def_staffless = im_staffless.image_copy() def_full = im_staffless.image_copy() def_full.or_image(def_staffonly, True) return [def_full, def_staffonly, staffline_skel]
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]
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 highlight_ccs(self, ccs, color=RGBPixel(0, 255, 0)): bla = self.to_rgb() [bla.highlight(c, color) for c in ccs] return bla
def _split(self, image, pos, dim): theta = self.rotation # image properties cols, rows = image.ncols, image.nrows i_ul = image.ul_x, image.ul_y cp = self._get_center_of_image(image) # center point # rotated image properties r_image = self._rotate_image(image, theta) r_cols, r_rows = r_image.ncols, r_image.nrows rcp = self._get_center_of_image(r_image) # rotated center point # rotated image points r_p1 = (pos, r_rows) if dim is 'x' else (0, pos) # left / bottom r_p2 = (pos, 0) if dim is 'x' else (r_cols, pos) # top / right # print r_p1, r_p2 # # show rotated cuts # r_image.draw_line(r_p1, r_p2, RGBPixel(255, 255, 255), 2.0) # r_image.save_PNG('./output/rcut_' + str(datetime.datetime.now().time()).replace(':', '.') + '.png') # relate points from ul to center of rotated image r_p1 = self._translate_point(r_p1, (0, 0), rcp) r_p2 = self._translate_point(r_p2, (0, 0), rcp) # print r_p1, r_p2 # rotate points around origin p1 = self._rotate_point_around_origin(r_p1, -theta) p2 = self._rotate_point_around_origin(r_p2, -theta) # print p1, p2 # relate points from center of image to ul point p1 = self._translate_point(p1, cp, (0, 0)) p2 = self._translate_point(p2, cp, (0, 0)) # print p1, p2 m = (p2[1] - p1[1]) / (p2[0] - p1[0]) # print m b1 = p1[1] - (m * p1[0]) b2 = p2[1] - (m * p2[0]) # print('b1', b1), ('b2', b2) def f_x(x): return m * x + b1 # DRAW on normal image draw_p1, draw_p2 = (0, f_x(0)), (image.ncols, f_x(image.ncols)) draw_p1 = self._translate_point(draw_p1, i_ul, (0, 0)) draw_p2 = self._translate_point(draw_p2, i_ul, (0, 0)) cut_image = image.image_copy() cut_image.draw_line(draw_p1, draw_p2, RGBPixel(0, 0, 0), 3) # cut glyph with white line # show cuts if self.save_cuts: rgb = image.to_rgb() rgb.draw_line(draw_p1, draw_p2, RGBPixel(255, 0, 0), 1) rgb.save_PNG('./output/cut_' + str(self.cut_number + 1) + '.png') if self.dont_cut: return [cut_image] splits = [x.image_copy() for x in cut_image.cc_analysis()] # for s in splits: # s = self._trim_image(s) self.cut_number += 1 return splits
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
def outline(rgb_img, cc, width=2.0, color=RGBPixel(255, 0, 0)): rgb_img.draw_hollow_rect((cc.offset_x, cc.offset_y), (cc.offset_x + cc.ncols, cc.offset_y + cc.nrows), color, width)
def __doc_example1__(images): image = images[ONEBIT] ccs = image.cc_analysis() rgb = image.to_rgb() rgb.highlight(ccs[0], RGBPixel(255, 0, 128)) return rgb
def remove_staves(self, crossing_symbols='all', num_lines=5, adj_ratio=2.5, noise_size=5, alpha=10.0, beta=0.1, angle_threshold=3, string_join_factor=0.25, debug=False): """Detects and removes staff lines from a music/tablature image. Signature: ``remove_staves(crossing_symbols='all', num_lines=5, adj_ratio=2.5, noise_size=5, alpha=10.0, beta=0.1, angle_threshold=3.0, string_join_factor=0.25)`` with *crossing_symbols*: Ignored. *num_lines*: The number of stafflines in each staff. (Autodetection of number of stafflines not yet implemented). It is unlikely one would need to provide the arguments below: *adj_ratio* The maximum ratio between adjacent vertical runs in order to be considered part of the same section. Higher values of this number will result in fewer, larger sections. *noise_size* The maximum size of a section that will be considered noise. *alpha* The minimum aspect ratio of a potential staffline section. *beta* The minimum \"straightness\" of a potential staffline section (as given by the gamma fittness function of a least-squares fit line). *angle_threshold* The maximum distance from the mean angle a section may be to be considered as a potential staffline (in degrees). *string_join_factor* The threshold for joining filaments together into filament strings. *debug* When True, returns a tuple of images to help debug each stage of the algorithm. Times for each stages are also displayed. The tuples elements are: *result* The normal result, with stafflines removed. *sections* Shows the segmentation by LAG. Use display_ccs to show the segments differently coloured. *potential_stafflines* Shows the sections that are potentially part of stafflines *filament_strings* Shows how the vertically aligned potential stafflines are grouped into filament_strings *staffline_chunks* The filament strings believed to be part of stafflines *stafflines* Draws the modelled lines on top of the image. """ if num_lines <= 0: num_lines = 5 t = time.clock() sections = self._make_line_adjacency_graph(self.image, adj_ratio) if debug: print ("Line adjacency graph time: %.04f, num sections: %d" % (time.clock() - t, len(sections))) sections_image = Image(self.image) for i, section in enumerate(sections): section.i = i for run in section.runs: sections_image.subimage(run).fill(i+1) t = time.clock() sections = self._remove_noise(sections, noise_size) if debug: print ("Remove noise time: %.04f, num sections: %d" % (time.clock() - t, len(sections))) t = time.clock() self._calculate_features(sections) if debug: print "Calculate features time: %.04f" % (time.clock() - t) t = time.clock() filaments = self._find_potential_stafflines(sections, alpha, beta, angle_threshold) if debug: print ("Find potential stafflines time: %.04f, num filaments: %d" % (time.clock() - t, len(filaments))) filaments_image = Image(self.image) for i, section in enumerate(filaments): if section.is_filament: for run in section.runs: filaments_image.subimage(run).fill(i+1) t = time.clock() strings = self._create_filament_strings(filaments, string_join_factor) if debug: print ("Create filament strings time: %.04f, num strings: %d" % (time.clock() - t, len(strings))) strings_image = Image(self.image) for i, string in enumerate(strings): for filament in string.filaments: for run in filament.runs: strings_image.subimage(run).fill(i+1) del filaments t = time.clock() staffline_strings = self._find_stafflines(strings, num_lines) if debug: print ("Find stafflines time: %.04f num staffline fragments: %d" % (time.clock() - t, len(staffline_strings))) staffline_image = Image(self.image) staffline_model_image = self.image.to_rgb() for i, staffline in enumerate(staffline_strings): for section in staffline.filaments: for run in section.runs: staffline_image.subimage(run).fill(i+1) if len(staffline_strings) == 0: return self.image t = time.clock() line_groupings = self._trace_stafflines(sections, staffline_strings, angle_threshold) if debug: print ("Trace stafflines time: %.04f" % (time.clock() - t)) t = time.clock() self._remove_stafflines(sections) if debug: print ("Remove stafflines time: %.04f" % (time.clock() - t)) t = time.clock() self.stafflines = self._make_line_models(line_groupings) if debug: print ("Make line models time: %.04f" % (time.clock() - t)) for y, staffline in self.stafflines.stafflines: last_point = staffline[0] for point in staffline[1:]: staffline_model_image.draw_line(last_point, point, RGBPixel(255, 0, 0)) last_point = point return (self.image, sections_image, filaments_image, strings_image, staffline_image, staffline_model_image) else: return self.image
def _get_background(self, image): # returns a white canvas of the original image size output = image.image_copy() output.fill(RGBPixel(0, 0, 0)) return output