def get_face_mask(img,landmarks): mask = np.zeros((img.shape[0],img.shape[1]), dtype=img.dtype) r = landmarks[0:17,0] c = landmarks[0:17,1] #rr: row is y-coord, cc: col is x-coord rr, cc = draw.polygon(r, c) mask[cc, rr] = 255 #remove left eyes r = landmarks[36:42,0] c = landmarks[36:42,1] rr, cc = draw.polygon(r, c) mask[cc, rr] = 0 #remove right eyes r = landmarks[42:48,0] c = landmarks[42:48,1] rr, cc = draw.polygon(r, c) mask[cc, rr] = 0 #remove lips r = landmarks[48:60,0] c = landmarks[48:60,1] rr, cc = draw.polygon(r, c) mask[cc, rr] = 0 return mask
def remove_eyes_and_lips_area(mask,landmarks): r = landmarks[0:17,0] c = landmarks[0:17,1] #rr: row is y-coord, cc: col is x-coord rr, cc = draw.polygon(r, c) mask[cc, rr] = 255 #remove left eyes r = landmarks[36:42,0] c = landmarks[36:42,1] rr, cc = draw.polygon(r, c) mask[cc, rr] = 0 #remove right eyes r = landmarks[42:48,0] c = landmarks[42:48,1] rr, cc = draw.polygon(r, c) mask[cc, rr] = 0 #remove lips r = landmarks[48:60,0] c = landmarks[48:60,1] rr, cc = draw.polygon(r, c) mask[cc, rr] = 0 return mask
def draw_reference_frame(x, y, z, h, theta): frame = np.ones((2 * y + 1, x + 1)) frame.fill(0) red_x = np.array([0, x // 2, x, 0]) red_y = np.array([0, y, 0, 0]) rr, cc = draw.polygon(red_y, red_x) frame[rr, cc] = 2 m = h * x // (2 * y) white_x = np.array([m, x - m, z, m]) white_y = np.array([h, h, 0, h]) rr, cc = draw.polygon(white_y, white_x) frame[rr, cc] = 3 cy = y cx = x // 2 - 1 radius = cx rr, cc = draw.circle(cy, cx, radius) zeros = np.ones_like(frame) zeros[rr, cc] = 0 frame[zeros == 1] = 1 c_in = np.array(frame.shape) // 2 c_out = np.array(frame.shape) // 2 transform = np.array([[np.cos(theta), -np.sin(theta)], [np.sin(theta), np.cos(theta)]]) offset = c_in - c_out.dot(transform) frame = ndimage.interpolation.affine_transform(frame, transform.T, order=0, cval=1, offset=offset).astype(int) return frame.astype("uint8")
def create_ringed_spider_mask(im_shape, ann_out, ann_in=0, sp_width=10, sp_angle=0): """ Mask out information is outside the annulus and inside the spiders (zeros). Parameters ---------- im_shape : tuple of int Tuple of length two with 2d array shape (Y,X). ann_out : int Outer radius of the annulus. ann_in : int Inner radius of the annulus. sp_width : int Width of the spider arms (3 branches). sp_angle : int angle of the first spider arm (on the positive horizontal axis) in counter-clockwise sense. Returns ------- mask : numpy ndarray 2d array of zeros and ones. """ mask = np.zeros(im_shape) s = im_shape[0] r = s/2 theta = np.arctan2(sp_width/2, r) t0 = np.array([theta, np.pi-theta, np.pi+theta, np.pi*2 - theta]) t1 = t0 + sp_angle/180 * np.pi t2 = t1 + np.pi/3 t3 = t2 + np.pi/3 x1 = r * np.cos(t1) + s/2 y1 = r * np.sin(t1) + s/2 x2 = r * np.cos(t2) + s/2 y2 = r * np.sin(t2) + s/2 x3 = r * np.cos(t3) + s/2 y3 = r * np.sin(t3) + s/2 rr1, cc1 = polygon(y1, x1) rr2, cc2 = polygon(y2, x2) rr3, cc3 = polygon(y3, x3) cy, cx = frame_center(mask) rr0, cc0 = circle(cy, cx, min(ann_out, cy)) rr4, cc4 = circle(cy, cx, ann_in) mask[rr0, cc0] = 1 mask[rr1, cc1] = 0 mask[rr2, cc2] = 0 mask[rr3, cc3] = 0 mask[rr4, cc4] = 0 return mask
def tomask(coords): mask = np.zeros(dims) coords = np.array(coords) rr, cc = polygon(coords[:, 0] + 1, coords[:, 1] + 1) mask[rr, cc] = 1 return mask
def get_indices(self): """Returns a set of points that lie inside the picked polygon.""" coo = self.get_coords() if coo is None: return None y,x = coo return polygon(x,y, self.im)
def __init__(self,image): """Extract points, compute Delaunay tessellation, compute features, and make properties available: image - ndimage the image data segments - a set of N indexes of segments that still exist vertices(N) - for each segment, the coordinates of its vertices pixels(N) - for each segment, the coordinates of its boundary and interior pixels neighbors(N) - for each segment, a set of indicies of neighboring segments features(N) - for each segment, a dictionary of features""" self.image = image points = self.find_points() tri = Delaunay(points) self.segments = set() self.vertices = {} self.pixels = {} self.neighbors = {} self.features = {} N = len(tri.vertices) for v,n in zip(tri.vertices,range(N)): py,px = np.rot90(points[v],3) # ccw for y,x iy,ix = [f.astype(int) for f in polygon(py,px)] # interior oy,ox = outline(py,px) # edges self.segments.add(n) self.vertices[n] = (py,px) self.pixels[n] = (np.concatenate((iy,oy)),np.concatenate((ix,ox))) self.neighbors[n] = set(tri.neighbors[n]) self.features[n] = self.compute_features(n)
def get_morph(im1, im2, im1_pts_array, imt2_pts_array, t): # Get the average image mean_pts_array = (im1_pts_array) * (1-t) + (im2_pts_array) * (t) # Delaunay Mean tri_mean = Delaunay(mean_pts_array) #mean_pts_array[:,0], mean_pts_array[:,1] = mean_pts_array[:,1], mean_pts_array[:,0].copy() mean_im = np.zeros(im1.shape).astype(float) for tri_vert_idxs in tri_mean.simplices.copy(): vert_idx1, vert_idx2, vert_idx3 = tri_vert_idxs im1_tri = np.array([im1_pts_array[vert_idx1], im1_pts_array[vert_idx2], im1_pts_array[vert_idx3]]) im2_tri = np.array([im2_pts_array[vert_idx1], im2_pts_array[vert_idx2], im2_pts_array[vert_idx3]]) im_mean_tri = np.array([mean_pts_array[vert_idx1], mean_pts_array[vert_idx2], mean_pts_array[vert_idx3]]) Trans1 = TriAffine(im_mean_tri, im1_tri) Trans2 = TriAffine(im_mean_tri, im2_tri) poly_mean_x_idxs, poly_mean_y_idxs = polygon(im_mean_tri[:,0], im_mean_tri[:,1]) poly1_x_idxs, poly1_y_idxs = Trans1.transform(poly_mean_x_idxs, poly_mean_y_idxs) poly2_x_idxs, poly2_y_idxs = Trans2.transform(poly_mean_x_idxs, poly_mean_y_idxs) mean_im[poly_mean_x_idxs, poly_mean_y_idxs] = im1[poly1_x_idxs, poly1_y_idxs] * (1-t) + im2[poly2_x_idxs, poly2_y_idxs] * (t) return mean_im
def fromRadialShape(a, r, shape): """ desc: Generates an image array based on angle and radius information. The image will be 0 for background and 1 for shape. arguments: a: desc: An array with angles (radial). type: ndarray r: desc: An array with radii (pixels). type: ndarray shape: desc: The shape (width, height) for the resulting shape. type: tuple returns: desc: An image. type: ndarray """ x = shape[0]/2 + r * np.cos(a) y = shape[1]/2 + r * np.sin(a) rr, cc = draw.polygon(x, y) im = np.zeros(shape) im[rr, cc] = 1 return im
def output(self): """Return the drawn line and the resulting scan. Returns ------- line_image : (M, N) uint8 array, same shape as image An array of 0s with the scanned line set to 255. If the linewidth of the line tool is greater than 1, sets the values within the profiled polygon to 128. scan : (P,) or (P, 3) array of int or float The line scan values across the image. """ end_points = self.line_tool.end_points line_image = np.zeros(self.image_viewer.image.shape[:2], np.uint8) width = self.line_tool.linewidth if width > 1: rp, cp = measure.profile._line_profile_coordinates( *end_points[:, ::-1], linewidth=width) # the points are aliased, so create a polygon using the corners yp = np.rint(rp[[0, 0, -1, -1],[0, -1, -1, 0]]).astype(int) xp = np.rint(cp[[0, 0, -1, -1],[0, -1, -1, 0]]).astype(int) rp, cp = draw.polygon(yp, xp, line_image.shape) line_image[rp, cp] = 128 (x1, y1), (x2, y2) = end_points.astype(int) rr, cc = draw.line(y1, x1, y2, x2) line_image[rr, cc] = 255 return line_image, self.scan_data
def _segment_polygon(self, image, frame, target, dim, cthreshold, mi, ma): src = frame[:] wh = get_size(src) # make image with polygon im = zeros(wh) points = asarray(target.poly_points) rr, cc = polygon(*points.T) im[cc, rr] = 255 # do watershedding distance = ndimage.distance_transform_edt(im) local_maxi = feature.peak_local_max(distance, labels=im, indices=False, # footprint=ones((1, 1)) ) markers, ns = ndimage.label(local_maxi) wsrc = watershed(-distance, markers, mask=im ) wsrc = wsrc.astype('uint8') # self.test_image.setup_images(3, wh) # self.test_image.set_image(distance, idx=0) # self.test_image.set_image(wsrc, idx=1) # self.wait() targets = self._find_polygon_targets(wsrc) ct = cthreshold * 0.75 target = self._test_targets(wsrc, targets, ct, mi, ma) if not target: values, bins = histogram(wsrc, bins=max((10, ns))) # assume 0 is the most abundant pixel. ie the image is mostly background values, bins = values[1:], bins[1:] idxs = nonzero(values)[0] ''' polygon is now segmented into multiple regions consectutively remove a region and find targets ''' nimage = ones_like(wsrc, dtype='uint8') * 255 nimage[wsrc == 0] = 0 for idx in idxs: bl = bins[idx] bu = bins[idx + 1] nimage[((wsrc >= bl) & (wsrc <= bu))] = 0 targets = self._find_polygon_targets(nimage) target = self._test_targets(nimage, targets, ct, mi, ma) if target: break return target
def poly_to_mask(vertex_row_coords, vertex_col_coords, shape): ''' Creates a poligon mask ''' fill_row_coords, fill_col_coords = draw.polygon(vertex_row_coords, vertex_col_coords, shape) mask = np.zeros(shape, dtype=np.bool) mask[fill_row_coords, fill_col_coords] = True return mask
def add_background(self): dis = self.lv_radius**2/self.e_h poly = np.array(( (self.e_center[0]+self.e_h, self.e_center[1]), (self.e_center[0]-self.e_h, self.e_center[1]), (self.lv_center[0]-self.lv_radius, self.lv_center[1]), (self.lv_center[0]+self.lv_radius, self.lv_center[1]), )) self.back = d.polygon(poly[:, 0], poly[:, 1])
def __init__(self,roilist,image): ''' Construct a list of ROI masks''' self.image = image self.masks = [] for roi in roilist: empty = np.zeros(image.shape, dtype=np.uint8) rr,cc = polygon(roi[1,:],roi[0,:]) empty[rr, cc] = 1 self.masks.append(empty)
def assignPts2Triangles(triangles_vertices): triLabels = [] for i,triangle in enumerate(triangles_vertices): triangle = np.array(triangle) y = triangle[:,1:] x = triangle[:,:1] rr, cc = polygon(y,x) triLabels.append([tuple(pair) for pair in np.vstack((cc,rr)).T]) return np.array(triLabels)
def test_polygon_rectangle(): img = np.zeros((10, 10), 'uint8') rr, cc = polygon((1, 4, 4, 1, 1), (1, 1, 4, 4, 1)) img[rr, cc] = 1 img_ = np.zeros((10, 10)) img_[1:4, 1:4] = 1 assert_array_equal(img, img_)
def test_polygon_exceed(): img = np.zeros((10, 10), 'uint8') poly = np.array(((1, -1), (100, -1), (100, 100), (1, 100), (1, 1))) rr, cc = polygon(poly[:, 0], poly[:, 1], img.shape) img[rr, cc] = 1 img_ = np.zeros((10, 10)) img_[1:, :] = 1 assert_array_equal(img, img_)
def getMeanPoint(outer_axis,inner_axis,pts_array): poly=np.array([p for p in inner_axis.coords]+[p for p in reversed(outer_axis.coords)]) rr, cc = polygon(poly[:, 0], poly[:, 1]) box_array=np.column_stack((rr,cc)) pts_inside=multidim_intersect(pts_array,box_array) x,y=line2vector(outer_axis) center=outer_axis.centroid pts_shifted=pts_inside-np.array([center.x,center.y]) pts_mean=np.mean(pts_shifted[:,0]*x+pts_shifted[:,1]*y) new_pt=translate(center,xoff=pts_mean*x, yoff=pts_mean*y) return new_pt
def test_polygon_rectangle(): img = np.zeros((10, 10), 'uint8') poly = np.array(((1, 1), (4, 1), (4, 4), (1, 4), (1, 1))) rr, cc = polygon(poly[:, 0], poly[:, 1]) img[rr, cc] = 1 img_ = np.zeros((10, 10)) img_[1:4, 1:4] = 1 assert_array_equal(img, img_)
def convex_hull_image(hull,shape): """this can also be computed using skimage.measure.regionprops""" chi = np.zeros(shape,dtype=np.bool) # points in the convex hull y, x = polygon(hull[:,0], hull[:,1]) chi[y,x] = 1 # points on the convex hull for row in np.hstack((hull, np.roll(hull,1,axis=0))): chi[line(*row)]=1 return chi
def clip_to_panel(self, xy, buffer_edges=True): """ if self.roi is not None, uses it by default TODO: check if need shape kwarg TODO: optimize ROI search better than list comprehension below TODO: panel_buffer can be a 2-d boolean mask, but needs testing """ xy = np.atleast_2d(xy) if self.roi is not None: ij_crds = self.cartToPixel(xy, pixels=True) ii, jj = polygon(self.roi[:, 0], self.roi[:, 1], shape=(self.rows, self.cols)) on_panel_rows = [i in ii for i in ij_crds[:, 0]] on_panel_cols = [j in jj for j in ij_crds[:, 1]] on_panel = np.logical_and(on_panel_rows, on_panel_cols) else: xlim = 0.5*self.col_dim ylim = 0.5*self.row_dim if buffer_edges and self.panel_buffer is not None: if self.panel_buffer.ndim == 2: pix = self.cartToPixel(xy, pixels=True) roff = np.logical_or(pix[:, 0] < 0, pix[:, 0] >= self.rows) coff = np.logical_or(pix[:, 1] < 0, pix[:, 1] >= self.cols) idx = np.logical_or(roff, coff) pix[idx, :] = 0 on_panel = self.panel_buffer[pix[:, 0], pix[:, 1]] on_panel[idx] = False else: xlim -= self.panel_buffer[0] ylim -= self.panel_buffer[1] on_panel_x = np.logical_and( xy[:, 0] >= -xlim, xy[:, 0] <= xlim ) on_panel_y = np.logical_and( xy[:, 1] >= -ylim, xy[:, 1] <= ylim ) on_panel = np.logical_and(on_panel_x, on_panel_y) elif not buffer_edges: on_panel_x = np.logical_and( xy[:, 0] >= -xlim, xy[:, 0] <= xlim ) on_panel_y = np.logical_and( xy[:, 1] >= -ylim, xy[:, 1] <= ylim ) on_panel = np.logical_and(on_panel_x, on_panel_y) return xy[on_panel, :], on_panel
def motion(event): if b1 == "down": global xold, yold, photo, data, color if xold is not None and yold is not None and photo is not None: x = np.array([xold, xold + 25, event.x + 25, event.x]) y = np.array([yold, yold + 25, event.y + 25, event.y]) rr, cc = polygon(y, x, (WIDTH, HEIGHT)) for i in range(3): data[0, rr, cc, i] += color # here's where you draw it. smooth. neat. xold = event.x yold = event.y
def extract_mask_from_polygon(height, width, points): """ extract mask from polygon :param height: mask height :param width: mask width :param points: polygon points in [[x1, y1], [x2, y2]] format :return: mask """ np_points = np.array(points) M = np.zeros((height, width), dtype=np.bool) rr, cc = polygon(np_points[:, 1], np_points[:, 0]) M[rr, cc] = 1 return M
def segToMask( S, h, w ): """ Convert polygon segmentation to binary mask. :param S (float array) : polygon segmentation mask :param h (int) : target mask height :param w (int) : target mask width :return: M (bool 2D array) : binary mask """ M = np.zeros((h,w), dtype=np.bool) for s in S: N = len(s) rr, cc = polygon(np.array(s[1:N:2]), np.array(s[0:N:2])) # (y, x) M[rr, cc] = 1 return M
def _get_rr_cc(self): """ Very similar to Particle_get_rr_cc(), except rotates verticies then draws rr_cc instead of rotating rr_cc itself.""" if self.phi % 360.0 == 0.0: xs, ys = self._xverts, self._yverts else: center = self.center centered = self.xymatrix - center rr_cc_rot = rotate_vector(centered, self.phi, rint='up') xs, ys = (rr_cc_rot + center).T return draw.polygon(ys, xs)
def cutout(pageimg, coordstring, scale=1, rect=False): coords = [p.split(",") for p in coordstring.split()] coords = np.array([(int(scale * int(c[1])), int(scale * int(c[0]))) for c in coords]) if rect: return pageimg[min(c[0] for c in coords):max(c[0] for c in coords), min(c[1] for c in coords):max(c[1] for c in coords)] rr, cc = polygon(coords[:, 0], coords[:, 1], pageimg.shape) offset = (min([x[0] for x in coords]), min([x[1] for x in coords])) box = np.ones( (max([x[0] for x in coords]) - offset[0], max([x[1] for x in coords]) - offset[1]), dtype=pageimg.dtype) * 255 box[rr - offset[0], cc - offset[1]] = pageimg[rr, cc] return box
def getMask(self): from skimage.draw import polygon if self._untranslated_mask is not None: xx = self._untranslated_mask[0] + int(self.state['pos'][0]) yy = self._untranslated_mask[1] + int(self.state['pos'][1]) else: x, y = np.transpose(self._untranslated_pts) mask=np.zeros(self.window.imageDimensions()) xx, yy = polygon(x,y,shape=mask.shape) self._untranslated_mask = xx, yy idx_to_keep = np.logical_not( (xx>=self.window.mx) | (xx<0) | (yy>=self.window.my) | (yy<0)) xx = xx[idx_to_keep] yy = yy[idx_to_keep] return xx, yy
def getMaskOnImage(self, tif): pts = self.getPoints() x=np.array([p[0] for p in pts]) y=np.array([p[1] for p in pts]) nDims=len(tif.shape) if nDims==4: #if this is an RGB image stack tif=np.mean(tif,3) mask=np.zeros(tif[0,:,:].shape,np.bool) elif nDims==3: mask=np.zeros(tif[0,:,:].shape,np.bool) if nDims==2: #if this is a static image mask=np.zeros(tif.shape,np.bool) xx,yy=polygon(x,y,shape=mask.shape) mask[xx,yy]=True return mask
def morph(im1, im2, im1_pts, im2_pts, tri, warp_frac, dissolve_frac): result = np.empty(im1.shape) for triangle in tri.simplices: pts1 = im1_pts[triangle] pts2 = im2_pts[triangle] pts3 = warp_frac*pts1 + (1-warp_frac)*pts2 A = computeAffine(pts3, pts1) B = computeAffine(pts3, pts2) rr, cc = polygon(pts3[:,1], pts3[:,0]) vector = np.ones([3, len(rr)]) vector[0] = rr vector[1] = cc A = np.dot(A, vector).astype(int) B = np.dot(B, vector).astype(int) result[rr, cc] = dissolve_frac*im1[A[0], A[1]] +\ (1-dissolve_frac)*im2[B[0], B[1]] return result
def ac_mask_simple(acontour, framesize): mask = npy.zeros(framesize, dtype = npy.uint8) new_acontour = npy.zeros([2, 5 * acontour.shape[1] - 4], dtype = npy.float32) s = acontour.shape[1] cnt = npy.arange(0, s) * 5 spline = [0, 0] for i in range(2): spline[i] = itp.InterpolatedUnivariateSpline(cnt, acontour[i, :]) for j in range(new_acontour.shape[1]): if j % 5 == 0: new_acontour[:, j] = acontour[:, j / 5] else: for i in range(2): new_acontour[i, j] = spline[i](j) rr, cc = polygon(acontour[1, :], acontour[0, :]) mask[cc, rr] = 1 return mask
def createMask(levelDims, vertices, pattern): """ Input: levelDims (nested list): dimensions of each layer of the slide. vertices (dict object as describe above) Output: (tuple) mask numpy nd array of 0/1, where 1 indicates inside the region and 0 is outside the region """ # Down scale the XML region to create a low reso image mask, and then # rescale the image to retain reso of image mask to save memory and time Xratio, Yratio = calculateRatio(levelDims) nRows, nCols = levelDims[-1] mask = np.zeros((nRows, nCols), dtype=np.uint8) for i in range(len(vertices[pattern])): lowX = np.array(vertices[pattern][i]['X']) / Xratio lowY = np.array(vertices[pattern][i]['Y']) / Yratio rr, cc = polygon(lowX, lowY, (nRows, nCols)) mask[rr, cc] = 1 return mask
def create_mask(coordinates, shape=STANDARD_SHAPE): ''' `coordinates` as represented in the Pylidc database for outlining the boundary of individual nodules. ''' coords = coordinates.split('\n') coords_split = [c.split(',') for c in coords] rows = [int(c[0]) for c in coords_split] cols = [int(c[1]) for c in coords_split] #min_x = np.amin(rows) #min_y = np.amin(cols) #rows = [r - min_x for r in rows] #cols = [c - min_y for c in cols] rows, cols = draw.polygon(rows, cols, shape) mask = np.zeros(shape, dtype=np.bool) mask[rows, cols] = True return mask, rows, cols
def create_polygon_fig(csv_files, patch_size=(300, 300)): """ Create and save the polygon ground truth image :param csv_files: list of csv files :param patch_size: used if the ground truth file is empty :return: """ for csv_file in tqdm(csv_files): df = pd.read_csv(csv_file) if not df.empty: gt = np.zeros((df['height'][0], df['width'][0])) for name, group in df.groupby('Object', sort=False): y, x = polygon(group['Y'].values, group['X'].values) y, x = check_bounds(y, x, df['height'][0] - 1, df['width'][0] - 1) gt[y, x] = 1 else: gt = np.zeros((patch_size)) save_name = csv_file[:-7] + 'GT.png' ersa_utils.save_file(save_name, gt.astype(np.uint8))
def fillColor(self,image, boundary,rgb): # boundary[:,[0,1]] = boundary[:,[1,0]] #print(boundary) #b = np.repeat(F[:, :, np.newaxis], 3, axis=2) img = image.copy() rr, cc = polygon(boundary[:,0], boundary[:,1], image.shape) image[rr,cc,:] = rgb#*image[rr,cc,:] rr, cc = polygon_perimeter(boundary[:,0], boundary[:,1], image.shape) image[rr,cc,:] = rgb#*image[rr,cc,:] # rgb = (webcolors.name_to_rgb(col)[0],webcolors.name_to_rgb(col)[1],webcolors.name_to_rgb(col)[2]) # print(rgb) # for x in range(image.shape[0]): # for y in range(image.shape[1]): # if(cv2.pointPolygonTest(boundary,(x,y),True)>=0): # image[y][x][0] = rgb[0] # image[y][x][1] = rgb[1] # image[y][x][2] = rgb[2] #cv2.fillPoly(image, pts =[boundary], color=rgb) #cv2.imwrite("123.png",image) # cv2.imshow("sdjkfnskj",image) # cv2.waitKey(0) return image
def read_polygon_csv_data(csv_file): def get_bounding_box(y, x): y_min = np.min(y).astype(int) x_min = np.min(x).astype(int) y_max = np.max(y).astype(int) x_max = np.max(x).astype(int) return y_min, x_min, y_max, x_max encoder = {'DT': 1, 'TT': 2, 'T': 1} label_order = ['SS', 'OT', 'DT', 'TT', 'OL', 'DL', 'TL'] df = pd.read_csv(csv_file) df['temp_label'] = pd.Categorical(df['Label'], categories=label_order, ordered=True) df.sort_values('temp_label', inplace=True, kind='mergesort') for name, group in df.groupby('Object', sort=False): label = group['Label'].values[0] if group['Type'].values[0] == 'Polygon' and label in encoder: x, y = polygon(group['X'].values, group['Y'].values) if (x != []) and (y != []): yield label, get_bounding_box(y, x)
def draw_polygon(img_height, img_width, vertices): """ Uses scikit-image draw polygon function to draw a polygonal shape on an empty image Input: img_height -- image height img_width -- image width vertices -- List of vertices in relative coordinates, e.g. [(0.0,0.3), (0.0,0.7), (0.3,0.5), (0.0,0.3)] will create a reversed triangle on the top of the image Output: bitmask representing the drawn shape """ fmask = np.zeros((img_height, img_width), dtype=np.uint8) r = np.round(img_height * np.array(vertices)[:, 0]) c = np.round(img_width * np.array(vertices)[:, 1]) rr, cc = polygon(r, c, (img_height, img_width)) fmask[rr, cc] = 1 return fmask
def add_rectangle(image, centre, shape, angle, RGB): """ Adds a rectangle to an image. :param image: An image :param centre: Pixel on which rectangle should be centred :param shape: (height, width) of rectangle :param angle: angle counterclockwise from right horizontal (radians) :param RGB: (red,green,blue) values between 0 and 1 """ corners = [[-shape[0] / 2, -shape[1] / 2], [shape[0] / 2, -shape[1] / 2], [shape[0] / 2, shape[1] / 2], [-shape[0] / 2, shape[1] / 2], [-shape[0] / 2, -shape[1] / 2]] rotation = [[np.cos(angle), -np.sin(angle)], [np.sin(angle), np.cos(angle)]] rotated = np.dot(rotation, np.array(corners).transpose()).transpose() centered = np.add(rotated, centre).astype(np.int) rr, cc = polygon(centered[:, 0], centered[:, 1], image.shape) for i in range(3): image[rr, cc, i] = RGB[i]
def produce_ma_mask(kp_array, img_size, point_radius=4): from skimage.morphology import dilation, erosion, square mask = np.zeros(shape=img_size, dtype=bool) limbs = [[2, 3], [2, 6], [3, 4], [4, 5], [6, 7], [7, 8], [2, 9], [9, 10], [10, 11], [2, 12], [12, 13], [13, 14], [2, 1], [1, 15], [15, 17], [1, 16], [16, 18], [2, 17], [2, 18], [9, 12], [12, 6], [9, 3], [17, 18]] limbs = np.array(limbs) - 1 for f, t in limbs: from_missing = kp_array[f][0] == MISSING_VALUE or kp_array[f][ 1] == MISSING_VALUE to_missing = kp_array[t][0] == MISSING_VALUE or kp_array[t][ 1] == MISSING_VALUE if from_missing or to_missing: continue norm_vec = kp_array[f] - kp_array[t] norm_vec = np.array([-norm_vec[1], norm_vec[0]]) norm_vec = point_radius * norm_vec / np.linalg.norm(norm_vec) vetexes = np.array([ kp_array[f] + norm_vec, kp_array[f] - norm_vec, kp_array[t] - norm_vec, kp_array[t] + norm_vec ]) yy, xx = polygon(vetexes[:, 0], vetexes[:, 1], shape=img_size) mask[yy, xx] = True for i, joint in enumerate(kp_array): if kp_array[i][0] == MISSING_VALUE or kp_array[i][1] == MISSING_VALUE: continue yy, xx = circle(joint[0], joint[1], radius=point_radius, shape=img_size) mask[yy, xx] = True mask = dilation(mask, square(5)) mask = erosion(mask, square(5)) return mask
def create_coco_dataset(): # images http://images.cocodataset.org/annotations/annotations_trainval2017.zip # labels http://calvin.inf.ed.ac.uk/wp-content/uploads/data/cocostuffdataset/stuffthingmaps_trainval2017.zip parser = argparse.ArgumentParser() parser.add_argument('--annotation_file', type=str, default=os.path.join(settings.dataset_dir, "annotations_trainval2017", "annotations", "instances_train2017.json")) parser.add_argument('--input_label_dir', type=str, default=os.path.join(settings.dataset_dir, "stuffthingmaps_trainval2017", "train2017")) parser.add_argument('--output_instance_dir', type=str, default=os.path.join(settings.res_dir, "train_instances")) opt = parser.parse_args() print("annotation file at {}".format(opt.annotation_file)) print("input label maps at {}".format(opt.input_label_dir)) print("output dir at {}".format(opt.output_instance_dir)) coco = COCO(opt.annotation_file) cats = coco.loadCats(coco.getCatIds()) imgIds = coco.getImgIds(catIds=coco.getCatIds(cats)) for ix, id in enumerate(imgIds): if ix % 50 == 0: print("{} / {}".format(ix, len(imgIds))) img_dict = coco.loadImgs(id)[0] filename = img_dict["file_name"].replace("jpg", "png") label_name = os.path.join(opt.input_label_dir, filename) inst_name = os.path.join(opt.output_instance_dir, filename) img = io.imread(label_name, as_grey=True) annIds = coco.getAnnIds(imgIds=id, catIds=[], iscrowd=None) anns = coco.loadAnns(annIds) count = 0 for ann in anns: if type(ann["segmentation"]) == list: if "segmentation" in ann: for seg in ann["segmentation"]: poly = np.array(seg).reshape((int(len(seg) / 2), 2)) rr, cc = polygon(poly[:, 1] - 1, poly[:, 0] - 1) img[rr, cc] = count count += 1 io.imsave(inst_name, img)
def get_mask(contours, slices): """ INPUT: coutours: output from read_structure; a list of structures slices: a list of dicom slices of CT scan corresponding to contours OUTPUT: label: a mask of the original CT scan where the values correspond to structure number colors: a list of colors corresponding """ image = np.stack([s.pixel_array for s in slices], axis=-1) z = [s.ImagePositionPatient[2] for s in slices] pos_r = slices[0].ImagePositionPatient[1] spacing_r = slices[0].PixelSpacing[1] pos_c = slices[0].ImagePositionPatient[0] spacing_c = slices[0].PixelSpacing[0] label = np.zeros_like(image, dtype=np.uint8) for con in contours: num = int(con['number']) for c in con['contours']: nodes = np.array(c).reshape((-1, 3)) assert np.amax(np.abs(np.diff(nodes[:, 2]))) == 0 zNew = [round(elem, 0) for elem in z] try: z_index = z.index(round(nodes[0, 2], 1)) except ValueError: try: z_index = zNew.index(round(nodes[0, 2], 0)) except ValueError: z_index = (np.abs(z - nodes[0, 2])).argmin() # z_index = z.index(np.around(nodes[0, 2],1)) r = (nodes[:, 1] - pos_r) / spacing_r c = (nodes[:, 0] - pos_c) / spacing_c rr, cc = polygon(r, c) # label[rr, cc, z_index] = num label[rr, cc, z_index] = int(1) colors = tuple(np.array([con['color'] for con in contours]) / 255.0) return label, colors
def render_images(self): if self.current_sample_id != self.renderingThread.id: self.log.info( 'rendering thread finished but for a different id! self %d thread %d' % (self.current_sample_id, self.renderingThread.id)) self.render_cell() return if self.renderingMutex.tryLock(): self.imgEdu.setPixmap( QPixmap.fromImage(self.renderingThread.qimg_edu)) self.imgCell.setPixmap( QPixmap.fromImage(self.renderingThread.qimg_hoechst)) self.imgPericentrin.setPixmap( QPixmap.fromImage(self.renderingThread.qimg_peri)) self.imgTubulin.setPixmap( QPixmap.fromImage(self.renderingThread.qimg_tubulin)) sample = [ s for s in self.samples if s['id'] == self.current_sample_id ][0] nucleus = sample['nucleus'] c, r = nucleus.boundary.xy r_n, c_n = draw.polygon(r, c) self.mplEduHist.clear() sns.distplot(self.edu[r_n, c_n], kde=False, rug=True, ax=self.mplEduHist.canvas.ax) self.mplEduHist.canvas.ax.xaxis.set_major_formatter( EngFormatter()) self.mplEduHist.canvas.ax.set_xlim([0, 2**16]) self.mplEduHist.canvas.draw() self.mplEduHist.show() self.renderingMutex.unlock()
def create_label_map_from_polygons(building_list, label_map): """ create label map from polygons Dependencies: skimage Input: polygons: same as the output of importgeojson Output: label_map: 2-D ndarray """ for building in building_list: polygon = building['poly'] ring = polygon.GetGeometryRef(0) xx, yy = [], [] for i in range(0, ring.GetPointCount()): y, x, z = ring.GetPoint(i) xx.append(x) yy.append(y) xx = np.array(xx) yy = np.array(yy) rr, cc = sk_draw.polygon(xx, yy) #print('{}, {}'.format(rr, cc)) label_map[rr, cc] = building['BuildingId'] return label_map
def _get_polygon_intensities(image, shape, zero_edge): # We max cause marking ROIs in GUI may render some coordinates negative shape_points = shape.getPoints()._val shape_points = [ tuple(float(c) for c in p.split(',')) for p in shape_points.split() ] image_x_coords = [int(x) for x, y in shape_points] image_y_coords = [int(y) for x, y in shape_points] # Marking ROIs in GUI may render some coordinates out of bounds # TODO: Using this approach just brings every point within bounds but if taking ir diagonally it can have a larger influence on the selected area image_size_x = image.getSizeX() image_size_y = image.getSizeY() image_x_coords = [max(0, min(x, image_size_x)) for x in image_x_coords] image_y_coords = [max(0, min(y, image_size_y)) for y in image_y_coords] shape_x_pos = min(image_x_coords) shape_y_pos = min(image_y_coords) shape_x_coors = [x - shape_x_pos for x in image_x_coords] shape_y_coors = [y - shape_y_pos for y in image_y_coords] x_range = (shape_x_pos, max(image_x_coords)) y_range = (shape_y_pos, max(image_y_coords)) data = get_intensities(image=image, x_range=x_range, y_range=y_range) if zero_edge: fill_y_coords, fill_x_coords = draw.polygon(shape_y_coors, shape_x_coors, data.shape[-2:]) masked_data = np.zeros(data.shape, dtype=data.dtype) masked_data[..., fill_y_coords, fill_x_coords] = data[..., fill_y_coords, fill_x_coords] return masked_data else: return data
def load_inbreast_mask(mask_path, imshape=(4084, 3328)): """ This function loads a osirix xml region as a binary numpy array for INBREAST dataset @mask_path : Path to the xml file @imshape : The shape of the image as an array e.g. [4084, 3328] return: numpy array where positions in the roi are assigned a value of 1. """ def load_point(point_string): x, y = tuple( [float(num) for num in point_string.strip('()').split(',')]) return y, x mask_shape = np.transpose(imshape) mask = np.zeros(mask_shape) with open(mask_path, 'rb') as mask_file: plist_dict = plistlib.load(mask_file, fmt=plistlib.FMT_XML)['Images'][0] numRois = plist_dict['NumberOfROIs'] rois = plist_dict['ROIs'] assert len(rois) == numRois for roi in rois: numPoints = roi['NumberOfPoints'] points = roi['Point_px'] assert numPoints == len(points) points = [load_point(point) for point in points] if len(points) <= 2: for point in points: mask[int(point[0]), int(point[1])] = 1 else: x, y = zip(*points) x, y = np.array(x), np.array(y) poly_x, poly_y = polygon(x, y, shape=mask_shape) mask[poly_x, poly_y] = 1 return mask
def contour_sep(): img = color.rgb2grey(imread('segmentation_WBC-master/Dataset 1/' + file)) #invert black->white , white->black invert_img = 1 - img #find contour ( edge ) contours = measure.find_contours(invert_img, 0.7) ''' # save contour plot fig, ax = plt.subplots() ax.imshow(invert_img, cmap=plt.cm.gray) for n, contour in enumerate(contours): ax.plot(contour[:, 1], contour[:, 0], linewidth=2) ax.axis('image') ax.set_xticks([]) ax.set_yticks([]) plt.tight_layout() plt.savefig('contour_'+file+'.png',bbox_inches='tight',pad_inches=0) ''' for n, contour in enumerate(contours): pr = np.array([p[0] for p in contour]) pc = np.array([p[1] for p in contour]) row = list(map(np.uint8, contour[:, 0])) col = list(map(np.uint8, contour[:, 1])) rr, cc = polygon(pr, pc) #print(pr,',',pc) invert_img[rr, cc] = 255 #convert gray -> binary thresh = threshold_mean(invert_img) binary = invert_img > thresh binary = binary * 255 imsave(PATH + '/segmentation/' + 'out_' + file + '.png', binary) #label object in image label_img = label(binary) props = regionprops(label_img)
def iou(grasp_pre, grasp_true, angle_threshold=np.pi / 6): ''' :功能 :计算两个给定框的iou :参数 : grasp_pre :Grasp对象,单个预测结果中反求出的抓取框 :参数 : grasp_true :Grasp对象,单个真实标注抓取框 :参数 : angle_threshold:角度阈值,超过这个角度就认为两者不符 :返回 : 两者的iou ''' #超过这个角度阈值就认为这两者不符,下面的计算复杂是为了消除角度方向的影响 if abs((grasp_pre.angle - grasp_true.angle + np.pi / 2) % np.pi - np.pi / 2) > angle_threshold: return 0 #先提取出两个框的所覆盖区域 rr1, cc1 = grasp_pre.polygon_coords() #现在是中心点和角度定义的抓取,要转换成四个角点定义的抓取才方便操作 rr2, cc2 = polygon(grasp_true.points[:, 0], grasp_true.points[:, 1]) try: #有时候这边返回的rr2是空的,再运行下面的就会报错,在这加个故障处理确保正常运行 r_max = max(rr1.max(), rr2.max()) + 1 c_max = max(cc1.max(), cc2.max()) + 1 except: return 0 #读取两个框的极限位置 r_max = max(rr1.max(), rr2.max()) + 1 c_max = max(cc1.max(), cc2.max()) + 1 #根据最大的边界来确定蒙版画布大小 canvas = np.zeros((r_max, c_max)) canvas[rr1, cc1] += 1 canvas[rr2, cc2] += 1 union = np.sum(canvas > 0) if union == 0: return 0 intersection = np.sum(canvas == 2) #print(intersection/union) return intersection / union
def get_mask(contours, slices): z = [s.ImagePositionPatient[2] for s in slices] pos_r = slices[0].ImagePositionPatient[1] spacing_r = slices[0].PixelSpacing[1] pos_c = slices[0].ImagePositionPatient[0] spacing_c = slices[0].PixelSpacing[0] #print z #print pos_r, pos_c, spacing_r, spacing_c #label = np.zeros_like(image, dtype=np.uint8) label = np.zeros((slices[0].Columns, slices[0].Rows, len(slices) ), dtype=np.uint8) for con in contours:# For each contour get the corresponding matching slice num = int(con['number']) ref_sopuid = con['name'] for s in slices: if(s.SOPInstanceUID == ref_sopuid): # Match contour with slice for c in con['contours']: nodes = np.array(c).reshape((-1, 3)) assert np.amax(np.abs(np.diff(nodes[:, 2]))) == 0 #print nodes try: z_index = z.index(nodes[0, 2]) except ValueError: print "Boundary case, skipping...." continue #z_index = zNew.index(nodes[0, 2]) #z_index = z.index(nodes[0, 2]) r = (nodes[:, 1] - pos_r) / spacing_r c = (nodes[:, 0] - pos_c) / spacing_c #r = s.Rows + np.floor(s.Rows * s.PixelSpacing[1]) * nodes[:,1] #c = s.Columns + np.floor(s.Columns * s.PixelSpacing[0]) * nodes[:,0] #print r,c rr, cc = polygon(r, c) #print rr,cc #label[rr, cc, s.InstanceNumber] = num label[rr, cc, z_index] = num colors = tuple(np.array([con['color'] for con in contours]) / 255.0) return label, colors
def draw_eggs_rectangle(mask_shape, pos_ant, pos_lat, pos_post): """ from given 3 point estimate the ellipse :param (int, int) mask_shape: :param [[int, int]] pos_ant: :param [[int, int]] pos_lat: :param [[int, int]] pos_post: :return [ndarray]: >>> pos_ant, pos_lat, pos_post = [10, 10], [20, 20], [35, 20] >>> points = np.array([pos_ant, pos_lat, pos_post]) >>> _= plt.plot(points[:, 0], points[:, 1], 'og') >>> masks = draw_eggs_rectangle([30, 50], [pos_ant], [pos_lat], [pos_post]) >>> [m.shape for m in masks] [(30, 50)] >>> for mask in masks: ... _= plt.imshow(mask, alpha=0.5, interpolation='nearest') >>> _= plt.xlim([0, mask.shape[1]]), plt.ylim([0, mask.shape[0]]), plt.grid() >>> # plt.show() """ list_masks = [] pos_ant, pos_lat, pos_post = list(pos_ant), list(pos_lat), list(pos_post) for ant, lat, post in zip(pos_ant, pos_lat, pos_post): ant, lat, post = map(np.array, [ant, lat, post]) lat_proj = closest_point_on_line(ant, post, lat) shift = lat - lat_proj # center = ant + (post - ant) / 2. # dist = np.linalg.norm(shift) # angle = np.arctan2(*(post - ant)) points = np.array([ ant + shift, ant - shift, post - shift, post + shift, ant + shift ]) rr, cc = draw.polygon(points[:, 1], points[:, 0], shape=mask_shape) mask = np.zeros(mask_shape) mask[rr, cc] = True list_masks.append(mask) return list_masks
def ragToGraphMat( self, maxT ): #A appeler qu'une fois que la rag a été validé, on utilise donc la valeur des attributs zMax = self.shape[2] maxD = self.rag.graph['maxD'] self.graphMat = np.zeros( (self.shape[0], self.shape[1], zMax, 4)).astype(np.uint8) for z in range(zMax): for n in self.rag: x0, y0, z0 = self.rag.nodes[n]['centroid'] x0 = int(x0) y0 = int(y0) z0 = int(z0) if (int(z0) == z): for v in self.rag.neighbors(n): d = self.rag[n][v]['weight'] corners = self.thickLine( (x0, y0), (int(self.rag.nodes[v]['centroid'][0]), int(self.rag.nodes[v]['centroid'][1])), self.distanceToThickness(d, maxD, maxT)) rTL, cTL = draw.polygon(corners[:, 0], corners[:, 1], self.shape[0:2]) self.graphMat[rTL, cTL, z, :] = self.deltaZToColor( int(self.rag.nodes[v]['centroid'][2]) - z0, zMax) #On dessine ENSUITE les sommets pour les avoir au dessus des aretes for n in self.rag: x0, y0, z0 = self.rag.nodes[n]['centroid'] x0 = int(x0) y0 = int(y0) z0 = int(z0) if (int(z0) == z): rC, cC = draw.disk((x0, y0), 5, shape=self.shape[0:2]) #On met ces pixels à une valeur différente de 0 self.graphMat[rC, cC, z, :] = [0, 204, 255, 120]
def fill_polygon_by_lonlat(array_to_fill, longitude, latitude, vertices_lon, vertices_lat, fill_value=1, additive=False): """ Draws and fills a polygon onto an existing numpy array based on vertices defined by longitude and latitude locations. This does NOT draw a polygon on a sphere, but instead based on straight lines between points. This is OK for small regional areas, but not advisable for large and global regions. Polygon vertices are drawn in the order given. Parameters ---------- array_to_fill (2D array): Array onto which to fill polygon vertices_r (1D array): Row indices for polygon vertices vertices_c (1D_array): Column indices for polygon vertices fill_value (float, bool or int): Fill value for polygon (Default: 1) additive (bool): If true, add fill value to existing array. Otherwise indices will be overwritten. (Default: False) Returns ------- Filled 2D array """ array_to_fill = np.array(array_to_fill) ind2D = general_utils.nearest_indices_2D(longitude, latitude, vertices_lon, vertices_lat) polygon_ind = draw.polygon(ind2D[1], ind2D[0], array_to_fill.shape) if additive: array_to_fill[polygon_ind[0], polygon_ind[1]] += fill_value else: array_to_fill[polygon_ind[0], polygon_ind[1]] = fill_value return array_to_fill
def add_figs(im): """Add random shapes.""" figs = np.zeros((im.shape[0], im.shape[1], 3)) wide = np.random.choice(range(10, 200), 1)[0] poly = np.array(( (0, 0), (0, wide), (1000, wide), (1000, 0), )) rr, cc = polygon(poly[:, 0], poly[:, 1], figs.shape) figs[rr, cc, 0] = 0.7 figs[rr, cc, 1] = 0.1 figs[rr, cc, 2] = 0.2 figs = np.roll(figs, shift=np.random.choice(range(1000), 1)[0], axis=1) figs = filters.gaussian(figs, sigma=5, multichannel=True, mode='reflect', cval=0.6) im += figs im[im > 1.0] = 1.0 return im
def draw_polygons(event): global pts, draw_img, draw_ax, draw_mask if event.button == 1: if not (event.ydata == None or event.xdata == None): pts.append([event.xdata, event.ydata]) if len(pts) > 1: rr, cc = line(int(round(pts[-1][0])), int(round(pts[-1][1])), int(round(pts[-2][0])), int(round(pts[-2][1]))) draw_img[cc, rr, :1] = 255 draw_ax.set_data(draw_img) plt.draw() elif event.button == 3: if len(pts) > 2: # draw polygon pts_array = np.asarray(pts) rr, cc = polygon(pts_array[:, 0], pts_array[:, 1]) draw_img[cc, rr, :1] = 255 draw_ax.set_data(draw_img) draw_mask[cc, rr] = 1 pts.clear() plt.draw() else: print('need at least three clicks before finishing annotation')
def cutout(pageimg, coordstring, scale=1, rect=False): """ Cut region from image Parameters ---------- pageimg : image (numpy array) coordstring : coordinates from PAGE as one string scale : factor to scale the coordinates with rect : cut out rectangle instead of polygons """ coords = [p.split(",") for p in coordstring.split()] coords = np.array([(int(scale*int(c[1])), int(scale*int(c[0]))) for c in coords]) if rect: return pageimg[min(c[0] for c in coords):max(c[0] for c in coords), min(c[1] for c in coords):max(c[1] for c in coords)] rr, cc = polygon(coords[:, 0], coords[:, 1], pageimg.shape) offset = (min([x[0] for x in coords]), min([x[1] for x in coords])) box = np.ones( (max([x[0] for x in coords]) - offset[0], max([x[1] for x in coords]) - offset[1]), dtype=pageimg.dtype) * 255 box[rr-offset[0], cc-offset[1]] = pageimg[rr, cc] return box
def iou(self, bb, angle_threshold=np.pi / 6): #if abs(self.angle - bb.angle) % np.pi > angle_threshold: if abs((self.angle - bb.angle + np.pi / 2) % np.pi - np.pi / 2) > angle_threshold: return 0 rr1, cc1 = self.polygon_coords() rr2, cc2 = polygon(bb.points[:, 0], bb.points[:, 1]) try: r_max = max(rr1.max(), rr2.max()) + 1 c_max = max(cc1.max(), cc2.max()) + 1 except: return 0 canvas = np.zeros((r_max, c_max)) canvas[rr1, cc1] += 1 canvas[rr2, cc2] += 1 union = np.sum(canvas > 0) if union == 0: return 0 intersection = np.sum(canvas == 2) return intersection * 1.0 / union
def vis_bbox(bbox, img, color=(0, 0, 0), modify=False): im_h, im_w = img.shape[0:2] x1, y1, x2, y2 = bbox x1 = max(0, min(x1, im_w - 1)) x2 = max(x1, min(x2, im_w - 1)) y1 = max(0, min(y1, im_h - 1)) y2 = max(y1, min(y2, im_h - 1)) r = [y1, y1, y2, y2] c = [x1, x2, x2, x1] if modify: img_ = img else: img_ = np.copy(img) rr, cc = skdraw.polygon(r, c, img.shape[:2]) skdraw.set_color(img_, (rr, cc), color, alpha=0.2) rr, cc = skdraw.polygon_perimeter(r, c, img.shape[:2]) for k in range(3): img_[rr, cc, k] = color[k] return img_
def draw_slope(arr, img_id='slope'): xx = [] yy = [] xs = np.linspace(0, params.length, params.res) ys = arr[::-1] # base xx.extend([x for x in xs]) yy.extend([0 for y in ys]) # top xx.extend([x for x in xs[::-1]]) yy.extend([y for y in ys[::-1]]) # side xx.extend([0 for x in xs]) yy.extend([y for y in ys]) xx = np.array(xx) * params.res / max(params.length, params.height) yy = np.array(yy) * params.res / max(params.length, params.height) img = np.zeros((params.res + 1, params.res + 1), dtype=np.uint8) + 255 img[polygon(xx, yy)] = 0 png.from_array(np.rot90(img), 'L').save(os.path.join('Images', '{0}.png'.format(img_id)))
def get_mask(self, contours, slices, image): z = [round(s.ImagePositionPatient[2], 1) for s in slices] ## pos_r = slices[0].ImagePositionPatient[1] spacing_r = slices[0].PixelSpacing[1] pos_c = slices[0].ImagePositionPatient[0] spacing_c = slices[0].PixelSpacing[0] label = np.zeros(image, dtype=np.uint8) for con in contours: num = int(con['number']) for c in con['contours']: nodes = np.array(c).reshape( (-1, 3)) #triplets describing points of contour assert np.amax(np.abs(np.diff(nodes[:, 2]))) == 0 z_index = z.index(np.around(nodes[0, 2], 1)) r = (nodes[:, 1] - pos_r) / spacing_r c = (nodes[:, 0] - pos_c) / spacing_c rr, cc = polygon(r, c) label[rr, cc, z_index] = num colors = tuple( np.array([con['color'] for con in contours]) / 255.0) return label, colors
def generate(self, roi_list): from skimage import draw image_size = self.image_size mask_fill = np.zeros(image_size + (1, ), dtype=np.uint8) rr_all = [] cc_all = [] for i, roi in enumerate(roi_list): # Draw polygon and add it to image rr, cc = draw.polygon(roi[:, 0], roi[:, 1]) rr[rr < 0] = 0 rr[rr > image_size[0] - 1] = image_size[0] - 1 cc[cc < 0] = 0 cc[cc > image_size[0] - 1] = image_size[0] - 1 # test if this region has already been added if any(np.array_equal(rr, rr_test) for rr_test in rr_all) and any( np.array_equal(cc, cc_test) for cc_test in cc_all): # print('Region #{} has already been used'.format(i + 1)) continue rr_all.append(rr) cc_all.append(cc) # Generate mask mask_fill[rr, cc, :] = 1 return mask_fill
def __init__(self, e, id, shape=None): self.id = id self.name = e.getAttribute('id') self.X, self.Y = self.get_points(e) if abs(max(self.X) - min(self.X)) < 4 or abs(max(self.Y) - min(self.Y)) < 4: # wall is too small and we ignore it. raise ValueError("small wall") if shape: self.X = np.clip(self.X, 0, shape[1]) self.Y = np.clip(self.Y, 0, shape[0]) # self.X, self.Y = self.sort_X_Y(self.X, self.Y) self.rr, self.cc = polygon(self.Y, self.X) direction = self.get_direction(self.X, self.Y) end_points = self.get_end_points(self.X, self.Y, direction) self.min_width = self.get_width(self.X, self.Y, direction) self.max_width = self.min_width Wall.__init__(self, id, end_points, direction, self.max_width, self.name) self.length = self.get_length(self.end_points) self.center = self.get_center(self.X, self.Y) self.min_coord, self.max_coord = self.get_width_coods(self.X, self.Y)
def getMask(self): pts = self.pts tif = self.window.image x = np.array([p[0] for p in pts]) y = np.array([p[1] for p in pts]) nDims = len(tif.shape) if nDims == 4: #if this is an RGB image stack tif = np.mean(tif, 3) mask = np.zeros(tif[0, :, :].shape, np.bool) elif nDims == 3: mask = np.zeros(tif[0, :, :].shape, np.bool) if nDims == 2: #if this is a static image mask = np.zeros(tif.shape, np.bool) xx, yy = polygon(x, y, shape=mask.shape) mask[xx, yy] = True pts_plus = np.array(np.where(mask)).T for pt in pts_plus: if not self.path.contains(QPointF(pt[0], pt[1])): mask[pt[0], pt[1]] = 0 self.minn = np.min( np.array([np.array([p[0], p[1]]) for p in self.pts]), 0) self.mask = np.array(np.where(mask)).T - self.minn