Python skimage.draw.line() Examples
The following are 23
code examples of skimage.draw.line().
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example.
You may also want to check out all available functions/classes of the module
skimage.draw
, or try the search function
.
Example #1
Source File: dataset.py From deep-high-resolution-net.TensorFlow with MIT License | 6 votes |
def draw_lines_on_img(img, point_ver, point_hor, point_class): line_list = [[0, 1], [1, 2], [3, 4], [4, 5], [6, 7], [7, 8], [9, 10], [10, 11], [12, 13], [13, 6], [13, 9], [13, 0], [13, 3]] # key point class: 1:visible, 2: not visible, 3: not marked for start_point_id in range(len(point_class)): if point_class[start_point_id] == 3: continue for end_point_id in range(len(point_class)): if point_class[end_point_id] == 3: continue if [start_point_id, end_point_id] in line_list: rr, cc = draw.line(int(point_ver[start_point_id]), int(point_hor[start_point_id]), int(point_ver[end_point_id]), int(point_hor[end_point_id])) draw.set_color(img, [rr, cc], [255, 0, 0]) return img
Example #2
Source File: segmentation.py From kraken with Apache License 2.0 | 6 votes |
def _find_superpixels(skeleton, heatmap, min_sp_dist): logger.debug('Finding superpixels') conf_map = heatmap * skeleton sp_idx = np.unravel_index(np.argsort(1.-conf_map, axis=None), conf_map.shape) if not sp_idx[0].any(): logger.info('No superpixel candidates found for line vectorizer. Likely empty page.') return np.empty(0) zeroes_idx = conf_map[sp_idx].argmin() if not zeroes_idx: logger.info('No superpixel candidates found for line vectorizer. Likely empty page.') return np.empty(0) sp_idx = sp_idx[0][:zeroes_idx], sp_idx[1][:zeroes_idx] sp_can = [(sp_idx[0][0], sp_idx[1][0])] for x in range(len(sp_idx[0])): loc = np.array([[sp_idx[0][x], sp_idx[1][x]]]) if min(cdist(sp_can, loc)) > min_sp_dist: sp_can.extend(loc.tolist()) return np.array(sp_can)
Example #3
Source File: LinearMotionBlur.py From pyblur with MIT License | 6 votes |
def LineKernel(dim, angle, linetype): kernelwidth = dim kernelCenter = int(math.floor(dim/2)) angle = SanitizeAngleValue(kernelCenter, angle) kernel = np.zeros((kernelwidth, kernelwidth), dtype=np.float32) lineAnchors = lineDict.lines[dim][angle] if(linetype == 'right'): lineAnchors[0] = kernelCenter lineAnchors[1] = kernelCenter if(linetype == 'left'): lineAnchors[2] = kernelCenter lineAnchors[3] = kernelCenter rr,cc = line(lineAnchors[0], lineAnchors[1], lineAnchors[2], lineAnchors[3]) kernel[rr,cc]=1 normalizationFactor = np.count_nonzero(kernel) kernel = kernel / normalizationFactor return kernel
Example #4
Source File: anno_helper.py From lost with MIT License | 5 votes |
def to_abs(annos, types, img_size): '''Convert relative annotation coordinates to absolute ones Args: annos (list of list): types (list of str): img_size (tuple): (width, height) of the image in pixels. Returns: list of list: Annotations in absolute format. ''' w, h = img_size new = [] for twod, t in zip(annos,types): if t == 'bbox': new.append([ twod[0]*w, twod[1]*h, twod[2]*w, twod[3]*h ]) elif t == 'line' or t == 'polygon': lp = np.array(twod) lp[:,0] = lp[:,0]*w lp[:,1] = lp[:,1]*h new.append(lp.tolist()) elif t=='point': new.append([twod[0]*w, twod[1]*h]) else: raise Exception('Unknown annotation type: {}'.format(t)) return np.array(new, dtype=int).tolist()
Example #5
Source File: visualisation.py From DeepVOG with GNU General Public License v3.0 | 5 votes |
def draw_line(output_frame, frame_shape, o, l, color=[255, 0, 0]): """ Parameters ---------- output_frame : numpy.darray Video frame to draw the circle. The value of video frame should be of type int [0, 255] frame_shape : list or tuple or numpy.darray Shape of the frame. For example, (240, 320) o : list or tuple or numpy.darray Origin of the line, with shape (2,) denoting (x, y). l : list or tuple or numpy.darray Vector with length. Body of the line. Shape = (2, ), denoting (x, y) color : tuple or list or numpy.darray RBG colors, e.g. [255, 0, 0] (red color), values of type int [0, 255] Returns ------- output frame : numpy.darray Frame with the ellipse drawn. """ R, G, B = color rr, cc = line(int(np.round(o[0])), int(np.round(o[1])), int(np.round(o[0] + l[0])), int(np.round(o[1] + l[1]))) rr[rr > int(frame_shape[1]) - 1] = frame_shape[1] - 1 cc[cc > int(frame_shape[0]) - 1] = frame_shape[0] - 1 rr[rr < 0] = 0 cc[cc < 0] = 0 output_frame[cc, rr, 0] = R output_frame[cc, rr, 1] = G output_frame[cc, rr, 2] = B return output_frame
Example #6
Source File: predict.py From Convolutional-Pose-Machine-tf with GNU Lesser General Public License v3.0 | 5 votes |
def joints_plot_image(joints, weight, img, radius=3, thickness=2): """ Plot the joints on image :param joints: (np.array)Assuming input of shape (num, joint_num, dim) :param img: (image)Assuming input of shape (num, w, h, c) :param weight: (np.array)Assuming input of shape (num, joint_num) :param radius: (int)Radius :param thickness: (int)Thickness :return: set of RGB image (num, w, h, c) """ assert len(joints.shape) == 3 and len(img.shape) == 4 and len(weight.shape) == 2 assert joints.shape[0] == img.shape[0] == weight.shape[0] colors = [(241, 242, 224), (196, 203, 128), (136, 150, 0), (64, 77, 0), (201, 230, 200), (132, 199, 129), (71, 160, 67), (32, 94, 27), (130, 224, 255), (7, 193, 255), (0, 160, 255), (0, 111, 255), (220, 216, 207), (174, 164, 144), (139, 125, 96), (100, 90, 69), (252, 229, 179), (247, 195, 79), (229, 155, 3), (155, 87, 1), (231, 190, 225), (200, 104, 186), (176, 39, 156), (162, 31, 123), (210, 205, 255), (115, 115, 229), (80, 83, 239), (40, 40, 198)] ret = np.zeros(img.shape, np.uint8) assert len(joints.shape) == 3 and len(img.shape) == 4 assert img.shape[-1] == 3 ret = img.copy() for num in range(joints.shape[0]): for jnum in range(joints.shape[1]): if weight[num, jnum] == 1: rr, cc = draw.circle( int(joints[num, jnum, 0]), int(joints[num, jnum, 1]), radius) ret[num, rr, cc] = colors[jnum] for num in range(joints.shape[0]): for lnk in range(len(LINKS)): if weight[num, LINKS[lnk][0]] == 1 and weight[num, LINKS[lnk][1]] == 1: rr, cc = draw.line(int(joints[num, LINKS[lnk][0], 0]), int(joints[num, LINKS[lnk][0], 1]), int(joints[num, LINKS[lnk][1], 0]), int(joints[num, LINKS[lnk][1], 1])) ret[num, rr, cc] = colors[lnk] return ret
Example #7
Source File: line_dataset.py From DSACLine with BSD 3-Clause "New" or "Revised" License | 5 votes |
def draw_models(self, labels, data=None, correct=None): ''' Draw lines for a batch of images. labels -- line parameters, array shape (Nx2) where N is the number of images in the batch 2 is the number of line parameters (intercept, slope) data -- batch of images to draw to, if empty a new batch wil be created according to the shape of labels and lines will be green, lines will be blue otherwise correct -- array of shape (N) indicating whether a line estimate is correct ''' n = labels.shape[0] if data is None: data = np.zeros((n, self.imgH, self.imgW, 3), dtype=np.float32) data.fill(self.bg_clr) clr = (0, 1, 0) else: clr = (0, 0, 1) for i in range (0, n): lY1 = int(labels[i, 0] * self.imgH) lY2 = int(labels[i, 1] * self.imgW + labels[i, 0] * self.imgH) self.draw_line(data[i], 0, lY1, self.imgW, lY2, clr) if correct is not None: # draw border green if estiamte is correct, red otherwise if correct[i]: borderclr = (0, 1, 0) else: borderclr = (1, 0, 0) set_color(data[i], line(0, 0, 0, self.imgW-1), borderclr) set_color(data[i], line(0, 0, self.imgH-1, 0), borderclr) set_color(data[i], line(self.imgH-1, 0, self.imgH-1, self.imgW-1), borderclr) set_color(data[i], line(0, self.imgW-1, self.imgH-1, self.imgW-1), borderclr) return data
Example #8
Source File: line_dataset.py From DSACLine with BSD 3-Clause "New" or "Revised" License | 5 votes |
def draw_hyps(self, labels, scores, data=None): ''' Draw a set of line hypothesis for a batch of images. labels -- line parameters, array shape (NxMx2) where N is the number of images in the batch M is the number of hypotheses per image 2 is the number of line parameters (intercept, slope) scores -- hypotheses scores, array shape (NxM), see above, higher score will be drawn with higher opacity data -- batch of images to draw to, if empty a new batch wil be created according to the shape of labels ''' n = labels.shape[0] # number of images m = labels.shape[1] # number of hypotheses if data is None: # create new batch of images data = np.zeros((n, self.imgH, self.imgW, 3), dtype=np.float32) data.fill(self.bg_clr) clr = (0, 0, 1) for i in range (0, n): for j in range (0, m): lY1 = int(labels[i, j, 0] * self.imgH) lY2 = int(labels[i, j, 1] * self.imgW + labels[i, j, 0] * self.imgH) self.draw_line(data[i], 0, lY1, self.imgW, lY2, clr, scores[i, j]) return data
Example #9
Source File: line_dataset.py From DSACLine with BSD 3-Clause "New" or "Revised" License | 5 votes |
def draw_line(self, data, lX1, lY1, lX2, lY2, clr, alpha=1.0): ''' Draw a line with the given color and opacity. data -- image to draw to lX1 -- x value of line segment start point lY1 -- y value of line segment start point lX2 -- x value of line segment end point lY2 -- y value of line segment end point clr -- line color, triple of values alpha -- opacity (default 1.0) ''' rr, cc, val = line_aa(lY1, lX1, lY2, lX2) set_color(data, (rr, cc), clr, val*alpha)
Example #10
Source File: drawing.py From pyImSegm with BSD 3-Clause "New" or "Revised" License | 5 votes |
def closest_point_on_line(start, end, point): """ projection of the point to the line :param list(int) start: line starting point :param list(int) end: line ending point :param list(int) point: point for extimation :return list(int): point on the line >>> closest_point_on_line([0, 0], [1, 2], [0, 2]) array([ 0.8, 1.6]) """ start, end, point = [np.array(a) for a in [start, end, point]] line = pl_line.Line(start, (end - start)) proj = np.array(line.project(point)) return proj
Example #11
Source File: line_dataset.py From DSACLine with BSD 3-Clause "New" or "Revised" License | 5 votes |
def __init__(self, imgW = 64, imgH = 64, margin = -5, bg_clr = 0.5): ''' Constructor. imgW -- image width (default 64) imgH -- image height (default 64) margin -- lines segments are sampled within this margin, negative value means that a line segment can start or end outside the image (default -5) bg_clr -- background intensity (default 0.5) ''' self.imgW = imgW self.imgH = imgH self.margin = margin self.bg_clr = bg_clr
Example #12
Source File: missing_parts.py From pytorch_connectomics with MIT License | 4 votes |
def prepare_deform_slice(self, slice_shape, random_state): # grow slice shape by 2 x deformation strength grow_by = 2 * self.deformation_strength #print ('sliceshape: '+str(slice_shape[0])+' growby: '+str(grow_by)+ ' strength: '+str(deformation_strength)) shape = (slice_shape[0] + grow_by, slice_shape[1] + grow_by) # randomly choose fixed x or fixed y with p = 1/2 fixed_x = random_state.rand() < 0.5 if fixed_x: x0, y0 = 0, np.random.randint(1, shape[1] - 2) x1, y1 = shape[0] - 1, np.random.randint(1, shape[1] - 2) else: x0, y0 = np.random.randint(1, shape[0] - 2), 0 x1, y1 = np.random.randint(1, shape[0] - 2), shape[1] - 1 ## generate the mask of the line that should be blacked out #print (shape) line_mask = np.zeros(shape, dtype='bool') rr, cc = line(x0, y0, x1, y1) line_mask[rr, cc] = 1 # generate vectorfield pointing towards the line to compress the image # first we get the unit vector representing the line line_vector = np.array([x1 - x0, y1 - y0], dtype='float32') line_vector /= np.linalg.norm(line_vector) # next, we generate the normal to the line normal_vector = np.zeros_like(line_vector) normal_vector[0] = - line_vector[1] normal_vector[1] = line_vector[0] # make meshgrid x, y = np.meshgrid(np.arange(shape[1]), np.arange(shape[0])) # generate the vector field flow_x, flow_y = np.zeros(shape), np.zeros(shape) # find the 2 components where coordinates are bigger / smaller than the line # to apply normal vector in the correct direction components, n_components = label(np.logical_not(line_mask).view('uint8')) assert n_components == 2, "%i" % n_components neg_val = components[0, 0] if fixed_x else components[-1, -1] pos_val = components[-1, -1] if fixed_x else components[0, 0] flow_x[components == pos_val] = self.deformation_strength * normal_vector[1] flow_y[components == pos_val] = self.deformation_strength * normal_vector[0] flow_x[components == neg_val] = - self.deformation_strength * normal_vector[1] flow_y[components == neg_val] = - self.deformation_strength * normal_vector[0] # generate the flow fields flow_x, flow_y = (x + flow_x).reshape(-1, 1), (y + flow_y).reshape(-1, 1) # dilate the line mask line_mask = binary_dilation(line_mask, iterations=self.iterations) #default=10 return flow_x, flow_y, line_mask
Example #13
Source File: defect_augment.py From gunpowder with MIT License | 4 votes |
def __prepare_deform_slice(self, slice_shape): # grow slice shape by 2 x deformation strength grow_by = 2 * self.deformation_strength shape = (slice_shape[0] + grow_by, slice_shape[1] + grow_by) # randomly choose fixed x or fixed y with p = 1/2 fixed_x = random.random() < .5 if fixed_x: x0, y0 = 0, np.random.randint(1, shape[1] - 2) x1, y1 = shape[0] - 1, np.random.randint(1, shape[1] - 2) else: x0, y0 = np.random.randint(1, shape[0] - 2), 0 x1, y1 = np.random.randint(1, shape[0] - 2), shape[1] - 1 ## generate the mask of the line that should be blacked out line_mask = np.zeros(shape, dtype='bool') rr, cc = line(x0, y0, x1, y1) line_mask[rr, cc] = 1 # generate vectorfield pointing towards the line to compress the image # first we get the unit vector representing the line line_vector = np.array([x1 - x0, y1 - y0], dtype='float32') line_vector /= np.linalg.norm(line_vector) # next, we generate the normal to the line normal_vector = np.zeros_like(line_vector) normal_vector[0] = - line_vector[1] normal_vector[1] = line_vector[0] # make meshgrid x, y = np.meshgrid(np.arange(shape[1]), np.arange(shape[0])) # generate the vector field flow_x, flow_y = np.zeros(shape), np.zeros(shape) # find the 2 components where coordinates are bigger / smaller than the line # to apply normal vector in the correct direction components, n_components = label(np.logical_not(line_mask).view('uint8')) assert n_components == 2, "%i" % n_components neg_val = components[0, 0] if fixed_x else components[-1, -1] pos_val = components[-1, -1] if fixed_x else components[0, 0] flow_x[components == pos_val] = self.deformation_strength * normal_vector[1] flow_y[components == pos_val] = self.deformation_strength * normal_vector[0] flow_x[components == neg_val] = - self.deformation_strength * normal_vector[1] flow_y[components == neg_val] = - self.deformation_strength * normal_vector[0] # generate the flow fields flow_x, flow_y = (x + flow_x).reshape(-1, 1), (y + flow_y).reshape(-1, 1) # dilate the line mask line_mask = binary_dilation(line_mask, iterations=10) return flow_x, flow_y, line_mask
Example #14
Source File: line_dataset.py From DSACLine with BSD 3-Clause "New" or "Revised" License | 4 votes |
def sample_lines(self, n): ''' Create new input images of random line segments and distractors along with ground truth parameters. n -- number of images to create ''' data = np.zeros((n, self.imgH, self.imgW, 3), dtype=np.float32) data.fill(self.bg_clr) labels = np.ndarray((n, 2, 1, 1), dtype=np.float32) for i in range (0, n): # for each image # create a random number of distractor circles nC = random.randint(2, 5) for c in range(0, nC): cR = random.randint(int(0.1 * self.imgW), int(1 * self.imgW)) cX1 = random.randint(int(-0.5 * cR), int(self.imgW+0.5*cR+1)) cY1 = random.randint(int(-0.5 * cR), int(self.imgH+0.5*cR+1)) clr = (random.uniform(0, 1), random.uniform(0, 1), random.uniform(0, 1)) rr, cc, val = circle_perimeter_aa(cY1, cX1, cR) set_color(data[i], (rr, cc), clr, val) # create line segment while True: # sample segment end points lX1 = random.randint(self.margin, self.imgW-self.margin+1) lX2 = random.randint(self.margin, self.imgW-self.margin+1) lY1 = random.randint(self.margin, self.imgH-self.margin+1) lY2 = random.randint(self.margin, self.imgH-self.margin+1) # check min length length = math.sqrt((lX1 - lX2) * (lX1 - lX2) + (lY1 - lY2) * (lY1 - lY2)) if length < minLength: continue # random color clr = (random.uniform(0, 1), random.uniform(0, 1), random.uniform(0, 1)) # calculate line ground truth parameters delta = lX2 - lX1 if delta == 0: delta = 1 slope = (lY2 - lY1) / delta intercept = lY1 - slope * lX1 # not too steep for stability if abs(slope) < maxSlope: break labels[i, 0] = intercept / self.imgH labels[i, 1] = slope self.draw_line(data[i], lX1, lY1, lX2, lY2, clr) # apply some noise on top data[i] = random_noise(data[i], mode='speckle') return data, labels
Example #15
Source File: imgOp.py From TextDetector with GNU General Public License v3.0 | 4 votes |
def drawbb(img, coor, color): ''' drawbb(canvas, coor, color) draw bounding box on canvas cavas: grey-scale image to draw on coor: coordinates of bounding box (tuple contains: x, y, w, h) color: the bounding box color ''' def rect_draw(canvas, Coor): canvas = numpy.uint8(canvas) for coor in Coor: x1 = coor[0] y1 = coor[1] x2 = coor[2] y2 = coor[3] line1 = skimage_line(x1, y1, x2, y1) line2 = skimage_line(x1, y1, x1, y2) line3 = skimage_line(x1, y2, x2, y2) line4 = skimage_line(x2, y1, x2, y2) skimage_set_color(canvas, line1, 255) skimage_set_color(canvas, line2, 255) skimage_set_color(canvas, line3, 255) skimage_set_color(canvas, line4, 255) return canvas if len(img.shape) == 3 and img.shape[2] == 3: # if color image if color == 'r': img[:, :, 0] = rect_draw(img[:, :, 0], coor) elif color == 'g': img[:, :, 1] = rect_draw(img[:, :, 1], coor) elif color == 'b': img[:, :, 2] = rect_draw(img[:, :, 2], coor) else: print 'Error: use only \'r, g, b\' for colors' return else: # if greyscale image canvas = numpy.uint8(img) img = numpy.zeros((canvas.shape[0], canvas.shape[1], 3)) img[:, :, 0] = canvas img[:, :, 1] = canvas img[:, :, 2] = canvas canvas = rect_draw(canvas, coor) if color == 'r': img[:, :, 0] = canvas elif color == 'g': img[:, :, 1] = canvas elif color == 'b': img[:, :, 2] = canvas else: print 'Error: use only \'r, g, b\' for colors' return return img
Example #16
Source File: drawing.py From pyImSegm with BSD 3-Clause "New" or "Revised" License | 4 votes |
def draw_graphcut_weighted_edges(segments, centers, edges, edge_weights, img_bg=None, img_alpha=0.5): """ visualise the edges on the overlapping a background image :param [tuple(int,int)] centers: list of centers :param ndarray segments: np.array<height, width> :param ndarray edges: list of edges of shape <nb_edges, 2> :param ndarray edge_weights: weight per edge <nb_edges, 1> :param ndarray img_bg: image background :param float img_alpha: transparency :return ndarray: np.array<height, width, 3> >>> slic = np.array([[0] * 3 + [1] * 3 + [2] * 3+ [3] * 3] * 4 + ... [[4] * 3 + [5] * 3 + [6] * 3 + [7] * 3] * 4) >>> centres = [[1, 1], [1, 4], [1, 7], [1, 10], ... [5, 1], [5, 4], [5, 7], [5, 10]] >>> edges = [[0, 1], [1, 2], [2, 3], [0, 4], [1, 5], ... [4, 5], [2, 6], [5, 6], [3, 7], [6, 7]] >>> img = np.random.randint(0, 256, slic.shape + (3,)) >>> edge_weights = np.ones(len(edges)) >>> edge_weights[0] = 0 >>> img = draw_graphcut_weighted_edges(slic, centres, edges, edge_weights, img_bg=img) >>> img.shape (8, 12, 3) """ if img_bg is not None: if img_bg.ndim == 2: # duplicate channels to be like RGB img_bg = np.rollaxis(np.tile(img_bg, (3, 1, 1)), 0, 3) # convert to range 0,1 so the drawing is correct max_val = 1. if img_bg.dtype != np.float: max_val = max(255., img_bg.max()) img = img_bg.astype(np.float) / max_val # make it partialy transparent img = (1. - img_alpha) + img * img_alpha else: img = np.zeros(segments.shape + (3,)) clrs = plt.get_cmap('Greens') diff = (edge_weights.max() - edge_weights.min()) if diff > 0: edge_ratio = (edge_weights - edge_weights.min()) / diff else: edge_ratio = np.zeros(edge_weights.shape) for i, edge in enumerate(edges): n1, n2 = edge y1, x1 = map(int, centers[n1]) y2, x2 = map(int, centers[n2]) # line = draw.line(y1, x1, y2, x2) # , shape=img.shape[:2] # img[line] = clrs(edge_ratio[i])[:3] # using anti-aliasing rr, cc, val = draw.line_aa(y1, x1, y2, x2) # , shape=img.shape[:2] color_w = np.tile(val, (3, 1)).T img[rr, cc, :] = color_w * clrs(edge_ratio[i])[:3] + (1 - color_w) * img[rr, cc, :] circle = draw.circle(y1, x1, radius=2, shape=img.shape[:2]) img[circle] = 1., 1., 0. return img
Example #17
Source File: segmentation.py From graph-based-image-classification with MIT License | 4 votes |
def draw_image(image, segmentation, adjacency, neighborhood): neighborhood = list(neighborhood) image = mark_boundaries(image, segmentation, (0, 0, 0)) graph = nx.from_numpy_matrix(adjacency) segmentation += np.ones_like(segmentation) segments = regionprops(segmentation) # Save the centroids in the node properties. for (n, data), segment in zip(graph.nodes_iter(data=True), segments): data['centroid'] = segment['centroid'] # Iterate over all edges and draw them. for n1, n2, data in graph.edges_iter(data=True): y1, x1 = map(int, graph.node[n1]['centroid']) y2, x2 = map(int, graph.node[n2]['centroid']) line = draw.line(y1, x1, y2, x2) n1_idx = neighborhood.index(n1) if n1 in neighborhood else -1 n2_idx = neighborhood.index(n2) if n2 in neighborhood else -1 if abs(n1_idx - n2_idx) == 1 and n1_idx != -1 and n2_idx != -1: image[line] = [1, 0, 0] else: image[line] = [0, 1, 0] # Draw a circle at the root node. for i in range(0, len(neighborhood)): if neighborhood[i] < 0: continue y1, x1 = graph.node[neighborhood[i]]['centroid'] circle = draw.circle(y1, x1, 2) if i == 0: image[circle] = [1, 1, 0] else: j = (i-1)/(len(neighborhood) - 2) image[circle] = [j, j, j] return image
Example #18
Source File: segmentation.py From kraken with Apache License 2.0 | 4 votes |
def polygonal_reading_order(lines: Sequence[Tuple[List, List]], text_direction: str = 'lr', regions: Optional[Sequence[List[Tuple[int, int]]]] = None) -> Sequence[Tuple[List, List]]: """ Given a list of baselines and regions, calculates the correct reading order and applies it to the input. Args: lines (Sequence): List of tuples containing the baseline and its polygonization. regions (Sequence): List of region polygons. text_direction (str): Set principal text direction for column ordering. Can be 'lr' or 'rl' Returns: A reordered input. """ bounds = [] if regions is not None: r = [geom.Polygon(reg) for reg in regions] else: r = [] region_lines = [[] for _ in range(len(r))] indizes = {} for line_idx, line in enumerate(lines): l = geom.LineString(line[1]) is_in_region = False for idx, reg in enumerate(r): if reg.contains(l): region_lines[idx].append((line_idx, (slice(l.bounds[1], l.bounds[0]), slice(l.bounds[3], l.bounds[2])))) is_in_region = True break if not is_in_region: bounds.append((slice(l.bounds[1], l.bounds[0]), slice(l.bounds[3], l.bounds[2]))) indizes[line_idx] = ('line', line) # order everything in regions intra_region_order = [[] for _ in range(len(r))] for idx, reg in enumerate(r): if len(region_lines[idx]) > 0: order = reading_order([x[1] for x in region_lines[idx]], text_direction) lsort = topsort(order) intra_region_order[idx] = [region_lines[idx][i][0] for i in lsort] reg = reg.bounds bounds.append((slice(reg[1], reg[0]), slice(reg[3], reg[2]))) indizes[line_idx+idx+1] = ('region', idx) # order unassigned lines and regions order = reading_order(bounds, text_direction) lsort = topsort(order) sidz = sorted(indizes.keys()) lsort = [sidz[i] for i in lsort] ordered_lines = [] for i in lsort: if indizes[i][0] == 'line': ordered_lines.append(indizes[i][1]) else: ordered_lines.extend(lines[x] for x in intra_region_order[indizes[i][1]]) return ordered_lines
Example #19
Source File: segmentation.py From kraken with Apache License 2.0 | 4 votes |
def _interpolate_lines(clusters, elongation_offset, extent, st_map, end_map): """ Interpolates the baseline clusters and sets the correct line direction. """ logger.debug('Reticulating splines') lines = [] extent = geom.Polygon([(0, 0), (extent[1]-1, 0), (extent[1]-1, extent[0]-1), (0, extent[0]-1), (0, 0)]) f_st_map = maximum_filter(st_map, size=20) f_end_map = maximum_filter(end_map, size=20) for cluster in clusters[1:]: # find start-end point points = [point for edge in cluster for point in edge] dists = squareform(pdist(points)) i, j = np.unravel_index(dists.argmax(), dists.shape) # build adjacency matrix for shortest path algo adj_mat = np.full_like(dists, np.inf) for l, r in cluster: idx_l = points.index(l) idx_r = points.index(r) adj_mat[idx_l, idx_r] = dists[idx_l, idx_r] # shortest path _, pr = shortest_path(adj_mat, directed=False, return_predecessors=True, indices=i) k = j line = [points[j]] while pr[k] != -9999: k = pr[k] line.append(points[k]) # smooth line line = np.array(line[::-1]) line = approximate_polygon(line[:,[1,0]], 1) lr_dir = line[0] - line[1] lr_dir = (lr_dir.T / np.sqrt(np.sum(lr_dir**2,axis=-1))) * elongation_offset/2 line[0] = line[0] + lr_dir rr_dir = line[-1] - line[-2] rr_dir = (rr_dir.T / np.sqrt(np.sum(rr_dir**2,axis=-1))) * elongation_offset/2 line[-1] = line[-1] + rr_dir ins = geom.LineString(line).intersection(extent) if ins.type == 'MultiLineString': ins = linemerge(ins) # skip lines that don't merge cleanly if ins.type != 'LineString': continue line = np.array(ins, dtype='uint') l_end = tuple(line[0])[::-1] r_end = tuple(line[-1])[::-1] if f_st_map[l_end] - f_end_map[l_end] > 0.2 and f_st_map[r_end] - f_end_map[r_end] < -0.2: pass elif f_st_map[l_end] - f_end_map[l_end] < -0.2 and f_st_map[r_end] - f_end_map[r_end] > 0.2: line = line[::-1] else: logger.debug('Insufficient marker confidences in output. Defaulting to upright line.') if line[0][0] > line[-1][0]: line = line[::-1] lines.append(line.tolist()) return lines
Example #20
Source File: segmentation.py From kraken with Apache License 2.0 | 4 votes |
def _compute_sp_states(sp_can, bl_map, st_map, end_map): """ Estimates the superpixel state information. """ sep_map = st_map + end_map logger.debug('Triangulating superpixels') # some pages might not contain if len(sp_can) < 2: logger.warning('Less than 2 superpixels in image. Nothing to vectorize.') return {} elif len(sp_can) < 3: logger.warning('Less than 3 superpixels in image. Skipping triangulation') key = tuple([tuple(sp_can[0]), tuple(sp_can[1])]) line_locs = draw.line(*(key[0] + key[1])) intensities = {key: (bl_map[line_locs].mean(), bl_map[line_locs].var(), sep_map[line_locs].mean(), sep_map[line_locs].max())} return intensities tri = Delaunay(sp_can, qhull_options="QJ Pp") indices, indptr = tri.vertex_neighbor_vertices # dict mapping each edge to its intensity. Needed for subsequent clustering step. intensities = {} logger.debug('Computing superpixel state information') for vertex in range(len(sp_can)): # look up neighboring indices neighbors = tri.points[indptr[indices[vertex]:indices[vertex+1]]] # calculate intensity of line segments to neighbors in both bl map and separator map intensity = [] for nb in neighbors.astype('int'): key = [tuple(sp_can[vertex]), tuple(nb)] key.sort() key = tuple(key) line_locs = draw.line(*(key[0] + key[1])) intensities[key] = (bl_map[line_locs].mean(), bl_map[line_locs].var(), sep_map[line_locs].mean(), sep_map[line_locs].max()) intensity.append(intensities[key][0]) logger.debug('Filtering triangulation') # filter edges in triangulation for k, v in list(intensities.items()): if v[0] < 0.4: del intensities[k] continue if v[1] > 5e-02: del intensities[k] continue # filter edges with high separator affinity if v[2] > 0.125 or v[3] > 0.25 or v[0] < 0.5: del intensities[k] continue return intensities
Example #21
Source File: segmentation.py From kraken with Apache License 2.0 | 4 votes |
def reading_order(lines: Sequence, text_direction: str = 'lr') -> List: """Given the list of lines (a list of 2D slices), computes the partial reading order. The output is a binary 2D array such that order[i,j] is true if line i comes before line j in reading order.""" logger.info('Compute reading order on {} lines in {} direction'.format(len(lines), text_direction)) order = np.zeros((len(lines), len(lines)), 'B') def _x_overlaps(u, v): return u[1].start < v[1].stop and u[1].stop > v[1].start def _above(u, v): return u[0].start < v[0].start def _left_of(u, v): return u[1].stop < v[1].start def _separates(w, u, v): if w[0].stop < min(u[0].start, v[0].start): return 0 if w[0].start > max(u[0].stop, v[0].stop): return 0 if w[1].start < u[1].stop and w[1].stop > v[1].start: return 1 return 0 if text_direction == 'rl': def horizontal_order(u, v): return not _left_of(u, v) else: horizontal_order = _left_of for i, u in enumerate(lines): for j, v in enumerate(lines): if _x_overlaps(u, v): if _above(u, v): order[i, j] = 1 else: if [w for w in lines if _separates(w, u, v)] == []: if horizontal_order(u, v): order[i, j] = 1 return order
Example #22
Source File: anno_helper.py From lost with MIT License | 4 votes |
def draw_annos(annos, types, img, color=(255,0,0), point_r=2): '''Draw annotations inside a image Args: annos (list): List of annotations. types (list): List of types. img (numpy.array): The image to draw annotations in. color (tuple): (R,G,B) color that is used for drawing. Note: The given image will be directly edited! Returns: numpy.array: Image with drawn annotations ''' if annos: if len(img.shape) < 3: img = gray2rgb(img) img_h, img_w, _ = img.shape for anno, t in zip(annos, types): if t == 'bbox': anno = trans_boxes_to([anno])[0] anno = to_abs([anno], [t], (img_w, img_h))[0] xmin, ymin, xmax, ymax = anno rr, cc = polygon_perimeter([ymin, ymin, ymax, ymax], [xmin, xmax, xmax, xmin ], shape=img.shape) elif t == 'polygon': anno = to_abs([anno], [t], (img_w, img_h))[0] anno = np.array(anno) rr, cc = polygon_perimeter(anno[:,1].tolist(), anno[:,0].tolist(), shape=img.shape) elif t == 'point': anno = to_abs([anno], [t], (img_w, img_h))[0] rr, cc = circle(anno[1], anno[0], point_r, shape=img.shape) elif t == 'line': anno = to_abs([anno], [t], (img_w, img_h))[0] for i, point in enumerate(anno): if i >= (len(anno)-1): break rr, cc = line(point[1], point[0], anno[i+1][1], anno[i+1][0]) img[rr,cc] = color else: raise ValueError('Unknown annotation type: {}'.format(t)) img[rr,cc] = color return img else: return []
Example #23
Source File: core_annots.py From ibeis with Apache License 2.0 | 4 votes |
def make_hog_block_image(hog, config=None): """ References: https://github.com/scikit-image/scikit-image/blob/master/skimage/feature/_hog.py """ from skimage import draw if config is None: config = HOGConfig() cx, cy = config['pixels_per_cell'] normalised_blocks = hog (n_blocksy, n_blocksx, by, bx, orientations) = normalised_blocks.shape n_cellsx = (n_blocksx - 1) + bx n_cellsy = (n_blocksy - 1) + by # Undo the normalization step orientation_histogram = np.zeros((n_cellsy, n_cellsx, orientations)) for x in range(n_blocksx): for y in range(n_blocksy): norm_block = normalised_blocks[y, x, :] # hack, this only works right for block sizes of 1 orientation_histogram[y:y + by, x:x + bx, :] = norm_block sx = n_cellsx * cx sy = n_cellsy * cy radius = min(cx, cy) // 2 - 1 orientations_arr = np.arange(orientations) dx_arr = radius * np.cos(orientations_arr / orientations * np.pi) dy_arr = radius * np.sin(orientations_arr / orientations * np.pi) hog_image = np.zeros((sy, sx), dtype=float) for x in range(n_cellsx): for y in range(n_cellsy): for o, dx, dy in zip(orientations_arr, dx_arr, dy_arr): centre = tuple([y * cy + cy // 2, x * cx + cx // 2]) rr, cc = draw.line(int(centre[0] - dx), int(centre[1] + dy), int(centre[0] + dx), int(centre[1] - dy)) hog_image[rr, cc] += orientation_histogram[y, x, o] return hog_image