def test_io(self): # Circle... temp = tempfile.TemporaryFile('w+b') before = self.make_circle() ply2.write(temp, before.as_dict()) temp.seek(0) after = LineGraph() after.from_dict(ply2.read(temp)) self.identical(before, after) temp.close() # Grid... temp = tempfile.TemporaryFile('w+b') before = self.make_grid() ply2.write(temp, before.as_dict()) temp.seek(0) after = LineGraph() after.from_dict(ply2.read(temp)) self.identical(before, after) temp.close() # Squares... temp = tempfile.TemporaryFile('w+b') before = self.make_squares() ply2.write(temp, before.as_dict()) temp.seek(0) after = LineGraph() after.from_dict(ply2.read(temp)) self.identical(before, after) temp.close() # Text... temp = tempfile.TemporaryFile('w+b') before = self.make_text() ply2.write(temp, before.as_dict()) temp.seek(0) after = LineGraph() after.from_dict(ply2.read(temp)) self.identical(before, after) temp.close()
def __open_lg(self, widget): dialog = Gtk.FileChooserDialog('Select a line graph...', self, Gtk.FileChooserAction.OPEN, (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OPEN, Gtk.ResponseType.OK)) filter_image = Gtk.FileFilter() filter_image.set_name('Line graph') filter_image.add_pattern('*.line_graph') dialog.add_filter(filter_image) filter_all = Gtk.FileFilter() filter_all.set_name('All files') filter_all.add_pattern('*') dialog.add_filter(filter_all) dialog.set_filename(os.path.join(os.path.abspath('.'), '.*')) response = dialog.run() if response==Gtk.ResponseType.OK: fn = dialog.get_filename() print 'Openning %s...'%fn lg = LineGraph() lg.from_dict(ply2.read(fn)) self.line.set_line(lg) self.overlay.set_line(lg) self.viewer.reset_view() self.viewer.queue_draw() # Report back... print 'File(s) loaded' dialog.destroy()
def __init__(self, adjStats = string.ascii_letters + ' ', noisy = False): # Load it... if noisy: print 'Reading in ply2 corpus file...' data = read(os.path.join(os.path.dirname(__file__),'corpus.ply2')) # Convert contents into a list of blocks... self.blocks = [] t_arr = data['element']['document']['text'] a_arr = data['element']['document']['attribution'] if noisy: print 'Creating blocks...' for i in xrange(t_arr.shape[0]): b = Block(t_arr[i], a_arr[i]) self.blocks.append(b) # Construct all statistics - this gets complicated for reasons of efficiency... if noisy: print 'Collecting statistics...' self.counts = numpy.zeros(256, dtype=numpy.int32) self.adj = numpy.zeros((len(adjStats),len(adjStats)), dtype=numpy.int32) self.adj_index = adjStats for b in self.blocks: b.stats(self.counts, self.adj, self.adj_index)
def __init__(self): # Do the basic window setup... Gtk.Window.__init__(self, title='Image Viewer') self.connect('delete-event', Gtk.main_quit) self.set_default_size(1024, 576) # Setup the viewing area... self.viewer = Viewer() self.viewer.set_bg(1.0, 1.0, 1.0) self.viewer.set_on_move(self.__on_move) # The line graph layers... self.line = LineLayer() self.viewer.add_layer(self.line) self.overlay = LineOverlayLayer() self.viewer.add_layer(self.overlay) # If a file name is provied load the line graph... if len(sys.argv)>1: lg = LineGraph() lg.from_dict(ply2.read(sys.argv[1])) self.line.set_line(lg) self.overlay.set_line(lg) self.viewer.reset_view() self.viewer.queue_draw() # Fetch the menu and set it up - this is mostly exported to another method because it gets messy... self.uimanager = self.__create_uimanager() self.add_accel_group(self.uimanager.get_accel_group()) menu_bar = self.uimanager.get_widget('/menu_bar') # Layout the parts... vertical = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) vertical.pack_start(menu_bar, False, False, 0) vertical.pack_start(self.viewer, True, True, 0) self.add(vertical)
def __init__(self): # Do the basic window setup... Gtk.Window.__init__(self, title='Image Viewer') self.connect('delete-event', Gtk.main_quit) self.set_default_size(1024, 576) # Setup the viewing area... self.viewer = Viewer() self.viewer.set_bg(1.0, 1.0, 1.0) self.viewer.set_on_move(self.__on_move) # The line graph layers... self.line = LineLayer() self.viewer.add_layer(self.line) self.overlay = LineOverlayLayer() self.viewer.add_layer(self.overlay) # If a file name is provied load the line graph... if len(sys.argv) > 1: lg = LineGraph() lg.from_dict(ply2.read(sys.argv[1])) self.line.set_line(lg) self.overlay.set_line(lg) self.viewer.reset_view() self.viewer.queue_draw() # Fetch the menu and set it up - this is mostly exported to another method because it gets messy... self.uimanager = self.__create_uimanager() self.add_accel_group(self.uimanager.get_accel_group()) menu_bar = self.uimanager.get_widget('/menu_bar') # Layout the parts... vertical = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) vertical.pack_start(menu_bar, False, False, 0) vertical.pack_start(self.viewer, True, True, 0) self.add(vertical)
def __open_lg(self, widget): dialog = Gtk.FileChooserDialog( 'Select a line graph...', self, Gtk.FileChooserAction.OPEN, (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OPEN, Gtk.ResponseType.OK)) filter_image = Gtk.FileFilter() filter_image.set_name('Line graph') filter_image.add_pattern('*.line_graph') dialog.add_filter(filter_image) filter_all = Gtk.FileFilter() filter_all.set_name('All files') filter_all.add_pattern('*') dialog.add_filter(filter_all) dialog.set_filename(os.path.join(os.path.abspath('.'), '.*')) response = dialog.run() if response == Gtk.ResponseType.OK: fn = dialog.get_filename() print 'Openning %s...' % fn lg = LineGraph() lg.from_dict(ply2.read(fn)) self.line.set_line(lg) self.overlay.set_line(lg) self.viewer.reset_view() self.viewer.queue_draw() # Report back... print 'File(s) loaded' dialog.destroy()
if len(lg_fn) == 0: print 'Failed to find any line graphs in the given directory' sys.exit(1) print 'Found %i line graphs' % len(lg_fn) # Load and process each in turn, to create a big database of feature/class... train = [] for fn_num, fn in enumerate(lg_fn): print 'Processing %s: (%i of %i)' % (fn, fn_num + 1, len(lg_fn)) # Load line graph... print ' Loading...' f = open(fn, 'r') data = ply2.read(f) f.close() lg = LineGraph() lg.from_dict(data) lg.segment() # Extract features... print ' Extracting features...' fv = lg.features(**feat_param) # Extract labels, to match the features... segs = lg.get_segs() def seg_to_label(seg): tags = lg.get_tags(seg)
def add(self, fn): """Given the filename for a LineGraph file this loads it in and splits it into Glyphs, which it dumps into the db. Does nothing if the file is already loaded. returns the number of glyphs added.""" if fn in self.fnl: return 0 self.fnl.append(fn) # Load the LineGraph from the given filename, and get the homography... f = open(fn, 'r') data = ply2.read(f) f.close() lg = LineGraph() lg.from_dict(data) lg.segment() hg = data['element']['homography']['v'].reshape((3, 3)) texture = os.path.normpath( os.path.join(os.path.dirname(fn), data['meta']['image'])) # Create a line bias object to be used in the next step... bias = gen_bias(lg, hg) # First pass - create each glyph object... glyphs = [] for s in xrange(lg.segments): g = Glyph(lg, s, hg, bias=bias) glyphs.append(g if '_' not in map(lambda t: t[0], g.lg.get_tags()) else None) # Second pass - fill in the connectivity information supported by adjacency... link_glyphs = [] for seg, glyph in enumerate(glyphs): if glyph == None: continue if glyph.key == None: continue # Brute force search to find a left partner... if glyph.left == None: best = None for g in glyphs: # Check it satisfies the conditions... if g == None: continue if g.key == None: continue if id(g) == id(glyph): continue if g.offset_y != glyph.offset_y: continue if (g.right_x - g.offset_x) > (glyph.right_x - glyph.offset_x): continue # Check its better than the current best... if best == None or (best.right_x - best.offset_x) < ( g.right_x - g.offset_x): best = g if best != None: glyph.left = (best, []) # Brute force search to find a right partner... if glyph.right == None: best = None for g in glyphs: # Check it satisfies the conditions... if g == None: continue if g.key == None: continue if id(g) == id(glyph): continue if g.offset_y != glyph.offset_y: continue if (g.left_x - g.offset_x) < (glyph.left_x - glyph.offset_x): continue # Check its better than the current best... if best == None or (best.left_x - best.offset_x) > ( g.left_x - g.offset_x): best = g if best != None: glyph.right = (best, []) # Now we have the best matches find common glyphs to link them, and record them... for other, out in [ g for g in [glyph.left, glyph.right] if g != None ]: shared_seg = set([a[1] for a in glyph.adjacent]) & set( [a[1] for a in other.adjacent]) for seg in shared_seg: g = glyphs[seg] if g == None: continue # We have a linking glyph - extract the information... glyph_vert = [a[0] for a in glyph.adjacent if a[1] == seg] other_vert = [a[0] for a in other.adjacent if a[1] == seg] link_glyph = [ a[0] for a in g.adjacent if a[1] == glyph.seg ] link_other = [ a[0] for a in g.adjacent if a[1] == other.seg ] # Check if we have a multi-link scenario - if so choose links... if len(glyph_vert) > 1 or len(other_vert) > 1: gv_y = map(lambda v: glyph.lg.get_vertex(v)[1], glyph_vert) ov_y = map(lambda v: other.lg.get_vertex(v)[1], other_vert) if (max(gv_y) - min(ov_y)) > (max(ov_y) - min(gv_y)): glyph_vert = glyph_vert[numpy.argmax(gv_y)] other_vert = other_vert[numpy.argmin(ov_y)] else: glyph_vert = glyph_vert[numpy.argmin(gv_y)] other_vert = other_vert[numpy.argmax(ov_y)] lg_y = map(lambda v: g.lg.get_vertex(v)[1], link_glyph) lo_y = map(lambda v: g.lg.get_vertex(v)[1], link_other) if (max(lg_y) - min(lo_y)) > (max(lo_y) - min(lg_y)): link_glyph = link_glyph[numpy.argmax(lg_y)] link_other = link_other[numpy.argmin(lo_y)] else: link_glyph = link_glyph[numpy.argmin(lg_y)] link_other = link_other[numpy.argmax(lo_y)] else: # Simple scenario... glyph_vert = glyph_vert[0] other_vert = other_vert[0] link_glyph = link_glyph[0] link_other = link_other[0] # Recreate the link as a simple path - its the only way to be safe!.. try: g = g.clone() nlg = LineGraph() link_glyph, link_other = nlg.from_path( g.lg, link_glyph, link_other) g.lg = nlg link_glyphs.append(g) except: continue # Line is broken in the centre - don't use it. # Add the tuple to the storage... out.append( (g, glyph_vert, other_vert, link_glyph, link_other)) # Third pass - enforce consistancy... for glyph in glyphs: if glyph == None: continue if glyph.left != None: if glyph.left[0].right == None or id( glyph.left[0].right[0]) != id(glyph): # Inconsistancy - break it... glyph.left[0].right = None glyph.left = None if glyph.right != None: if glyph.right[0].left == None or id( glyph.right[0].left[0]) != id(glyph): # Inconsistancy - break it... glyph.right[0].left = None glyph.right = None # Forth pass - add filename tags and add to db (Count and return the glyph count)... count = 0 for glyph in (glyphs + link_glyphs): if glyph == None: continue glyph.lg.add_tag(0, 0.1, 'file:%s' % fn) glyph.lg.add_tag(0, 0.2, 'texture:%s' % texture) glyph.lg.add_tag( 0, 0.3, 'link:left:%s' % ('n' if glyph.left == None else ('g' if len(glyph.left[1]) == 0 else 'l'))) glyph.lg.add_tag( 0, 0.4, 'link:right:%s' % ('n' if glyph.right == None else ('g' if len(glyph.right[1]) == 0 else 'l'))) glyph.lg.add_tag(0, 0.5, 'source:x:%f' % glyph.source[0]) glyph.lg.add_tag(0, 0.6, 'source:y:%f' % glyph.source[1]) if glyph.key != None: count += 1 if glyph.key in self.db: self.db[glyph.key].append(glyph) else: self.db[glyph.key] = [glyph] glyph.code = len(self.by_code) glyph.lg.add_tag(0, 0.5, 'code:%i' % glyph.code) self.by_code.append(glyph) return count
in_fn, in_ext = os.path.splitext(args.in_file) cm_fn, cm_ext = os.path.splitext(os.path.basename(args.map_file)) if args.out_file=='': args.out_file = '%s_%s%s'%(in_fn, cm_fn, in_ext) args.mask_file = '%s_%s_mask%s'%(in_fn, cm_fn, in_ext) # Load the colour map... if not args.quiet: print 'Loading colour map... (%s)' % args.map_file f = open(args.map_file, 'r') cm = read(f) f.close() col_in = numpy.empty((cm['element']['sample']['in.r'].shape[0],3), dtype=numpy.float32) col_out = numpy.empty((cm['element']['sample']['out.r'].shape[0],3), dtype=numpy.float32) col_in[:,0] = cm['element']['sample']['in.r'] col_in[:,1] = cm['element']['sample']['in.g'] col_in[:,2] = cm['element']['sample']['in.b'] col_out[:,0] = cm['element']['sample']['out.r'] col_out[:,1] = cm['element']['sample']['out.g'] col_out[:,2] = cm['element']['sample']['out.b'] if args.reverse:
def add(self, fn): """Given a filename for a linegraph file this loads it, extracts all chunks and stores them in the db.""" if fn in self.fnl: return 0 self.fnl.append(fn) self.kdtree = None # Load the LineGraph from the given filename... data = ply2.read(fn) lg = LineGraph() lg.from_dict(data) texture = os.path.normpath(os.path.join(os.path.dirname(fn), data['meta']['image'])) # Calculate the radius scaler and distance for this line graph, by calculating the median radius... rads = map(lambda i: lg.get_vertex(i)[5], xrange(lg.vertex_count)) rads.sort() median_radius = rads[len(rads)//2] radius_mult = 1.0 / median_radius dist = self.dist * median_radius # Chop it up into chains, extract chunks and store them in the database... ret = 0 for raw_chain in lg.chains(): for chain in filter(lambda c: len(c)>1, [raw_chain, raw_chain[::-1]]): head = 0 tail = 0 length = 0.0 while True: # Move tail so its long enough, or has reached the end... while length<dist and tail+1<len(chain): tail += 1 v1 = lg.get_vertex(chain[tail-1]) v2 = lg.get_vertex(chain[tail]) length += numpy.sqrt((v1[0]-v2[0])**2 + (v1[1]-v2[1])**2) # Create the chunk... chunk = LineGraph() chunk.from_vertices(lg, chain[head:tail+1]) # Tag it... chunk.add_tag(0, 0.1, 'file:%s'%fn) chunk.add_tag(0, 0.2, 'texture:%s'%texture) # Store it... self.chunks.append((chunk, median_radius)) ret += 1 # If tail is at the end exit the loop... if tail+1 >= len(chain): break # Move head along for the next chunk... to_move = dist * self.factor while to_move>0.0 and head+2<len(chain): head += 1 v1 = lg.get_vertex(chain[head-1]) v2 = lg.get_vertex(chain[head]) offset = numpy.sqrt((v1[0]-v2[0])**2 + (v1[1]-v2[1])**2) length -= offset to_move -= offset return ret
def add(self, fn): """Given a filename for a linegraph file this loads it, extracts all chunks and stores them in the db.""" if fn in self.fnl: return 0 self.fnl.append(fn) self.kdtree = None # Load the LineGraph from the given filename... data = ply2.read(fn) lg = LineGraph() lg.from_dict(data) texture = os.path.normpath( os.path.join(os.path.dirname(fn), data['meta']['image'])) # Calculate the radius scaler and distance for this line graph, by calculating the median radius... rads = map(lambda i: lg.get_vertex(i)[5], xrange(lg.vertex_count)) rads.sort() median_radius = rads[len(rads) // 2] radius_mult = 1.0 / median_radius dist = self.dist * median_radius # Chop it up into chains, extract chunks and store them in the database... ret = 0 for raw_chain in lg.chains(): for chain in filter(lambda c: len(c) > 1, [raw_chain, raw_chain[::-1]]): head = 0 tail = 0 length = 0.0 while True: # Move tail so its long enough, or has reached the end... while length < dist and tail + 1 < len(chain): tail += 1 v1 = lg.get_vertex(chain[tail - 1]) v2 = lg.get_vertex(chain[tail]) length += numpy.sqrt((v1[0] - v2[0])**2 + (v1[1] - v2[1])**2) # Create the chunk... chunk = LineGraph() chunk.from_vertices(lg, chain[head:tail + 1]) # Tag it... chunk.add_tag(0, 0.1, 'file:%s' % fn) chunk.add_tag(0, 0.2, 'texture:%s' % texture) # Store it... self.chunks.append((chunk, median_radius)) ret += 1 # If tail is at the end exit the loop... if tail + 1 >= len(chain): break # Move head along for the next chunk... to_move = dist * self.factor while to_move > 0.0 and head + 2 < len(chain): head += 1 v1 = lg.get_vertex(chain[head - 1]) v2 = lg.get_vertex(chain[head]) offset = numpy.sqrt((v1[0] - v2[0])**2 + (v1[1] - v2[1])**2) length -= offset to_move -= offset return ret
sys.exit(1) print 'Found %i line graphs' % len(lg_fn) # Load and process each in turn, to create a big database of feature/class... train = [] for fn_num, fn in enumerate(lg_fn): print 'Processing %s: (%i of %i)' % (fn, fn_num+1, len(lg_fn)) # Load line graph... print ' Loading...' f = open(fn, 'r') data = ply2.read(f) f.close() lg = LineGraph() lg.from_dict(data) lg.segment() # Extract features... print ' Extracting features...' fv = lg.features(**feat_param) # Extract labels, to match the features... segs = lg.get_segs() def seg_to_label(seg): tags = lg.get_tags(seg)
def add(self, fn): """Given the filename for a LineGraph file this loads it in and splits it into Glyphs, which it dumps into the db. Does nothing if the file is already loaded. returns the number of glyphs added.""" if fn in self.fnl: return 0 self.fnl.append(fn) # Load the LineGraph from the given filename, and get the homography... f = open(fn, 'r') data = ply2.read(f) f.close() lg = LineGraph() lg.from_dict(data) lg.segment() hg = data['element']['homography']['v'].reshape((3,3)) texture = os.path.normpath(os.path.join(os.path.dirname(fn), data['meta']['image'])) # Create a line bias object to be used in the next step... bias = gen_bias(lg, hg) # First pass - create each glyph object... glyphs = [] for s in xrange(lg.segments): g = Glyph(lg, s, hg, bias = bias) glyphs.append(g if '_' not in map(lambda t: t[0], g.lg.get_tags()) else None) # Second pass - fill in the connectivity information supported by adjacency... link_glyphs = [] for seg, glyph in enumerate(glyphs): if glyph==None: continue if glyph.key==None: continue # Brute force search to find a left partner... if glyph.left==None: best = None for g in glyphs: # Check it satisfies the conditions... if g==None: continue if g.key==None: continue; if id(g)==id(glyph): continue if g.offset_y!=glyph.offset_y: continue if (g.right_x - g.offset_x) > (glyph.right_x - glyph.offset_x): continue # Check its better than the current best... if best==None or (best.right_x - best.offset_x) < (g.right_x - g.offset_x): best = g if best!=None: glyph.left = (best, []) # Brute force search to find a right partner... if glyph.right==None: best = None for g in glyphs: # Check it satisfies the conditions... if g==None: continue if g.key==None: continue; if id(g)==id(glyph): continue if g.offset_y!=glyph.offset_y: continue if (g.left_x - g.offset_x) < (glyph.left_x - glyph.offset_x): continue # Check its better than the current best... if best==None or (best.left_x - best.offset_x) > (g.left_x - g.offset_x): best = g if best!=None: glyph.right = (best, []) # Now we have the best matches find common glyphs to link them, and record them... for other, out in [g for g in [glyph.left, glyph.right] if g!=None]: shared_seg = set([a[1] for a in glyph.adjacent]) & set([a[1] for a in other.adjacent]) for seg in shared_seg: g = glyphs[seg] if g==None: continue # We have a linking glyph - extract the information... glyph_vert = [a[0] for a in glyph.adjacent if a[1]==seg] other_vert = [a[0] for a in other.adjacent if a[1]==seg] link_glyph = [a[0] for a in g.adjacent if a[1]==glyph.seg] link_other = [a[0] for a in g.adjacent if a[1]==other.seg] # Check if we have a multi-link scenario - if so choose links... if len(glyph_vert)>1 or len(other_vert)>1: gv_y = map(lambda v: glyph.lg.get_vertex(v)[1], glyph_vert) ov_y = map(lambda v: other.lg.get_vertex(v)[1], other_vert) if (max(gv_y) - min(ov_y)) > (max(ov_y) - min(gv_y)): glyph_vert = glyph_vert[numpy.argmax(gv_y)] other_vert = other_vert[numpy.argmin(ov_y)] else: glyph_vert = glyph_vert[numpy.argmin(gv_y)] other_vert = other_vert[numpy.argmax(ov_y)] lg_y = map(lambda v: g.lg.get_vertex(v)[1], link_glyph) lo_y = map(lambda v: g.lg.get_vertex(v)[1], link_other) if (max(lg_y) - min(lo_y)) > (max(lo_y) - min(lg_y)): link_glyph = link_glyph[numpy.argmax(lg_y)] link_other = link_other[numpy.argmin(lo_y)] else: link_glyph = link_glyph[numpy.argmin(lg_y)] link_other = link_other[numpy.argmax(lo_y)] else: # Simple scenario... glyph_vert = glyph_vert[0] other_vert = other_vert[0] link_glyph = link_glyph[0] link_other = link_other[0] # Recreate the link as a simple path - its the only way to be safe!.. try: g = g.clone() nlg = LineGraph() link_glyph, link_other = nlg.from_path(g.lg, link_glyph, link_other) g.lg = nlg link_glyphs.append(g) except: continue # Line is broken in the centre - don't use it. # Add the tuple to the storage... out.append((g, glyph_vert, other_vert, link_glyph, link_other)) # Third pass - enforce consistancy... for glyph in glyphs: if glyph==None: continue if glyph.left!=None: if glyph.left[0].right==None or id(glyph.left[0].right[0])!=id(glyph): # Inconsistancy - break it... glyph.left[0].right = None glyph.left = None if glyph.right!=None: if glyph.right[0].left==None or id(glyph.right[0].left[0])!=id(glyph): # Inconsistancy - break it... glyph.right[0].left = None glyph.right = None # Forth pass - add filename tags and add to db (Count and return the glyph count)... count = 0 for glyph in (glyphs+link_glyphs): if glyph==None: continue glyph.lg.add_tag(0, 0.1, 'file:%s'%fn) glyph.lg.add_tag(0, 0.2, 'texture:%s'%texture) glyph.lg.add_tag(0, 0.3, 'link:left:%s'%('n' if glyph.left==None else ('g' if len(glyph.left[1])==0 else 'l'))) glyph.lg.add_tag(0, 0.4, 'link:right:%s'%('n' if glyph.right==None else ('g' if len(glyph.right[1])==0 else 'l'))) glyph.lg.add_tag(0, 0.5, 'source:x:%f' % glyph.source[0]) glyph.lg.add_tag(0, 0.6, 'source:y:%f' % glyph.source[1]) if glyph.key!=None: count += 1 if glyph.key in self.db: self.db[glyph.key].append(glyph) else: self.db[glyph.key] = [glyph] glyph.code = len(self.by_code) glyph.lg.add_tag(0, 0.5, 'code:%i'%glyph.code) self.by_code.append(glyph) return count
args = parser.parse_args() in_fn, in_ext = os.path.splitext(args.in_file) cm_fn, cm_ext = os.path.splitext(os.path.basename(args.map_file)) if args.out_file == '': args.out_file = '%s_%s%s' % (in_fn, cm_fn, in_ext) args.mask_file = '%s_%s_mask%s' % (in_fn, cm_fn, in_ext) # Load the colour map... if not args.quiet: print 'Loading colour map... (%s)' % args.map_file f = open(args.map_file, 'r') cm = read(f) f.close() col_in = numpy.empty((cm['element']['sample']['in.r'].shape[0], 3), dtype=numpy.float32) col_out = numpy.empty((cm['element']['sample']['out.r'].shape[0], 3), dtype=numpy.float32) col_in[:, 0] = cm['element']['sample']['in.r'] col_in[:, 1] = cm['element']['sample']['in.g'] col_in[:, 2] = cm['element']['sample']['in.b'] col_out[:, 0] = cm['element']['sample']['out.r'] col_out[:, 1] = cm['element']['sample']['out.g'] col_out[:, 2] = cm['element']['sample']['out.b']