def mask_from_via_annotation( df, filename_via=None, shape=None, fn_full=None, dtype=np.uint8 ): """ Generate mask from VGG Image Annotator (VIA). :param df: pandas dataframe generated by VIA by CSV export. :param fn_full: full file name of input image it can be used to generate filename_via and shape :param filename_via: filename used in dataframe to identify image :param shape: shape of output mask. It can be obtained by reading input image based on fn_full :param dtype: dtype of output mask :return: np.ndimage with mask """ if filename_via is None: filename_via = fn_full.name if shape is None: img = skimage.io.imread(fn_full, as_gray=True) shape = [img.shape[0], img.shape[1]] ln = np.sum(df[df["filename"] == filename_via].region_shape_attributes != "{}") mask = np.zeros(shape, dtype=dtype) for annotation_id in range(ln): # print("-----------------") # print(annotation_id, ln) dfrsa = df[df["filename"] == filename_via].region_shape_attributes.values # print("len and dfrsa", len(dfrsa), " | ", dfrsa) region_shape_attributes = json.loads( df[df["filename"] == filename_via].region_shape_attributes.values[ annotation_id ] ) # plt.imshow(img, cmap="gray") polygon_x = region_shape_attributes["all_points_x"] polygon_y = region_shape_attributes["all_points_y"] logger.debug(f"{annotation_id}, {polygon_x[:3]}, {polygon_y[:3]}") polygon = list(zip(polygon_y, polygon_x)) poly_path = mplPath(polygon) x, y = np.mgrid[: shape[0], : shape[1]] coors = np.hstack( (x.reshape(-1, 1), y.reshape(-1, 1)) ) # coors.shape is (4000000,2) mask_i = poly_path.contains_points(coors) mask_i = mask_i.reshape([shape[0], shape[1]]).astype(np.uint8) # mask_i = mask.reshape(img.shape[:-1]) mask += mask_i # mask[mask_i] = 255 # plot(region_shape_attributes["all_points_x"],region_shape_attributes["all_points_y"]) return mask
def polygonsOverlap(poly1, poly2): """Determine if two polygons intersect; can fail for very pointy polygons. Accepts two polygons, as lists of vertices (x,y) pairs. If given an object with with (vertices + pos), will try to use that as the polygon. Checks if any vertex of one polygon is inside the other polygon. Same as the `.overlaps()` method elsewhere. """ try: # do this using try:...except rather than hasattr() for speed poly1 = poly1.verticesPix # we want to access this only once except Exception: pass try: # do this using try:...except rather than hasattr() for speed poly2 = poly2.verticesPix # we want to access this only once except Exception: pass # faster if have matplotlib tools: if haveMatplotlib: if matplotlib.__version__ > '1.2': if any(mplPath(poly1).contains_points(poly2)): return True return any(mplPath(poly2).contains_points(poly1)) else: try: # deprecated in matplotlib 1.2 if any(nxutils.points_inside_poly(poly1, poly2)): return True return any(nxutils.points_inside_poly(poly2, poly1)) except Exception: pass # fall through to pure python: for p1 in poly1: if pointInPolygon(p1[0], p1[1], poly2): return True for p2 in poly2: if pointInPolygon(p2[0], p2[1], poly1): return True return False
def load_annotated_dataset(csv_file_path, images_directory_path): csv_path = Path(csv_file_path) df = pd.read_csv(csv_path) originals = [] masks = [] i = 0 for fn in df["filename"].unique(): i += 1 img_file_path = f"{images_directory_path}/{fn}" img = skimage.io.imread(img_file_path, as_gray=True) img_mask = np.zeros([img.shape[1], img.shape[0]]) dirty = False for region in df[df["filename"] == fn].region_shape_attributes: region_shape_attributes = json.loads(region) # I found out, that CSV contains some strange areas if "all_points_x" not in region_shape_attributes or "all_points_y" not in region_shape_attributes: continue plt.imshow(img, cmap="gray") polygon_x = region_shape_attributes["all_points_x"] polygon_y = region_shape_attributes["all_points_y"] polygon = list(zip(polygon_y, polygon_x)) poly_path = mplPath(polygon) x, y = np.mgrid[:img.shape[0], :img.shape[1]] coors = np.hstack((x.reshape(-1, 1), y.reshape(-1, 1))) mask = poly_path.contains_points(coors) mask = mask.reshape([img.shape[0], img.shape[1]]) dirty = True img_mask = np.logical_xor(img_mask, mask) if dirty: originals.append(img) plt.imshow(img, cmap="gray") plt.show() masks.append(img_mask) plt.imshow(img_mask, cmap="gray") plt.show() return originals, masks
def prepare_wave(self, prevOE, nrays): """Creates the beam arrays used in wave diffraction calculations. *prevOE* is the diffracting element: a descendant from :class:`~xrt.backends.raycing.oes.OE`, :class:`~xrt.backends.raycing.apertures.RectangularAperture` or :class:`~xrt.backends.raycing.apertures.RoundAperture`. *nrays* of samples are randomly distributed over the slit area. """ from . import waves as rw nrays = int(nrays) wave = rs.Beam(nrays=nrays, forceState=1, withAmplitudes=True) dX = self.limOptX[1] - self.limOptX[0] dZ = self.limOptY[1] - self.limOptY[0] footprint = mplPath(self.vertices, closed=True) randRays = 0 goodX = [] goodY = [] while randRays < nrays: xy = np.random.rand(nrays, 2) rndX = xy[:, 0] * dX + self.limOptX[0] rndY = xy[:, 1] * dZ + self.limOptY[0] inDots = footprint.contains_points(zip(rndX, rndY)) goodX = rndX[inDots] if randRays == 0 else\ np.append(goodX, rndX[inDots]) goodY = rndY[inDots] if randRays == 0 else\ np.append(goodY, rndY[inDots]) randRays = len(goodX) if raycing._VERBOSITY_ > 10: print("Generated {0} dots of {1}".format(randRays, nrays)) wave.x[:] = goodX[:nrays] wave.z[:] = goodY[:nrays] wave.area = 0.5 * np.abs( np.dot(self.vertices[:, 0], np.roll(self.vertices[:, 1], 1)) - np.dot(self.vertices[:, 1], np.roll(self.vertices[:, 0], 1))) wave.dS = wave.area / nrays wave.toOE = self glo = rs.Beam(copyFrom=wave) self.local_to_global(glo) rw.prepare_wave(prevOE, wave, glo.x, glo.y, glo.z) return wave
def prepare_wave(self, prevOE, nrays): """Creates the beam arrays used in wave diffraction calculations. *prevOE* is the diffracting element: a descendant from :class:`~xrt.backends.raycing.oes.OE`, :class:`~xrt.backends.raycing.apertures.RectangularAperture` or :class:`~xrt.backends.raycing.apertures.RoundAperture`. *nrays* of samples are randomly distributed over the slit area. """ from . import waves as rw nrays = int(nrays) wave = rs.Beam(nrays=nrays, forceState=1, withAmplitudes=True) dX = self.limOptX[1] - self.limOptX[0] dZ = self.limOptY[1] - self.limOptY[0] footprint = mplPath(self.vertices) randRays = 0 goodX = [] goodY = [] while randRays < nrays: xy = np.random.rand(nrays, 2) rndX = xy[:, 0] * dX + self.limOptX[0] rndY = xy[:, 1] * dZ + self.limOptY[0] inDots = footprint.contains_points(list(zip(rndX, rndY))) goodX = rndX[inDots] if randRays == 0 else\ np.append(goodX, rndX[inDots]) goodY = rndY[inDots] if randRays == 0 else\ np.append(goodY, rndY[inDots]) randRays = len(goodX) if raycing._VERBOSITY_ > 10: print("Generated {0} dots of {1}".format(randRays, nrays)) wave.x[:] = goodX[:nrays] wave.z[:] = goodY[:nrays] wave.area = 0.5 * np.abs( np.dot(self.vertices[:, 0], np.roll(self.vertices[:, 1], 1)) - np.dot(self.vertices[:, 1], np.roll(self.vertices[:, 0], 1))) wave.dS = wave.area / nrays wave.toOE = self glo = rs.Beam(copyFrom=wave) self.local_to_global(glo) rw.prepare_wave(prevOE, wave, glo.x, glo.y, glo.z) return wave
def pointInPolygon(x, y, poly): """Determine if a point is inside a polygon; returns True if inside. (`x`, `y`) is the point to test. `poly` is a list of 3 or more vertices as (x,y) pairs. If given an object, such as a `ShapeStim`, will try to use its vertices and position as the polygon. Same as the `.contains()` method elsewhere. """ try: # do this using try:...except rather than hasattr() for speed poly = poly.verticesPix # we want to access this only once except Exception: pass nVert = len(poly) if nVert < 3: msg = 'pointInPolygon expects a polygon with 3 or more vertices' logging.warning(msg) return False # faster if have matplotlib tools: if haveMatplotlib: if matplotlib.__version__ > '1.2': return mplPath(poly).contains_point([x, y]) else: try: return bool(nxutils.pnpoly(x, y, poly)) except Exception: pass # fall through to pure python: # adapted from http://local.wasp.uwa.edu.au/~pbourke/geometry/insidepoly/ # via http://www.ariel.com.au/a/python-point-int-poly.html inside = False # trace (horizontal?) rays, flip inside status if cross an edge: p1x, p1y = poly[-1] for p2x, p2y in poly: if y > min(p1y, p2y) and y <= max(p1y, p2y) and x <= max(p1x, p2x): if p1y != p2y: xints = (y - p1y) * (p2x - p1x) / (p2y - p1y) + p1x if p1x == p2x or x <= xints: inside = not inside p1x, p1y = p2x, p2y return inside
def pointInPolygon(x, y, poly): """Determine if a point is inside a polygon; returns True if inside. (`x`, `y`) is the point to test. `poly` is a list of 3 or more vertices as (x,y) pairs. If given an object, such as a `ShapeStim`, will try to use its vertices and position as the polygon. Same as the `.contains()` method elsewhere. """ try: # do this using try:...except rather than hasattr() for speed poly = poly.verticesPix # we want to access this only once except Exception: pass nVert = len(poly) if nVert < 3: msg = 'pointInPolygon expects a polygon with 3 or more vertices' logging.warning(msg) return False # faster if have matplotlib tools: if haveMatplotlib: if parse_version(matplotlib.__version__) > parse_version('1.2'): return mplPath(poly).contains_point([x, y]) else: try: return bool(nxutils.pnpoly(x, y, poly)) except Exception: pass # fall through to pure python: # adapted from http://local.wasp.uwa.edu.au/~pbourke/geometry/insidepoly/ # via http://www.ariel.com.au/a/python-point-int-poly.html inside = False # trace (horizontal?) rays, flip inside status if cross an edge: p1x, p1y = poly[-1] for p2x, p2y in poly: if y > min(p1y, p2y) and y <= max(p1y, p2y) and x <= max(p1x, p2x): if p1y != p2y: xints = (y - p1y) * (p2x - p1x) / (p2y - p1y) + p1x if p1x == p2x or x <= xints: inside = not inside p1x, p1y = p2x, p2y return inside
def propagate(self, beam=None, needNewGlobal=False): """Assigns the "lost" value to *beam.state* array for the rays intercepted by the aperture. The "lost" value is ``-self.ordinalNum - 1000.`` .. Returned values: beamLocal """ if self.bl is not None: self.bl.auto_align(self, beam) good = beam.state > 0 # beam in local coordinates lo = rs.Beam(copyFrom=beam) bl = self.bl if self.xyz == 'auto' else self.xyz raycing.global_to_virgin_local(bl, beam, lo, self.center, good) path = -lo.y[good] / lo.b[good] lo.x[good] += lo.a[good] * path lo.z[good] += lo.c[good] * path lo.path[good] += path footprint = mplPath(self.vertices) badIndices = np.invert( footprint.contains_points(np.array(list(zip(lo.x, lo.z))))) beam.state[badIndices] = self.lostNum lo.state[good] = beam.state[good] lo.y[good] = 0. if hasattr(lo, 'Es'): propPhase = np.exp(1e7j * (lo.E[good] / CHBAR) * path) lo.Es[good] *= propPhase lo.Ep[good] *= propPhase if self.alarmLevel is not None: raycing.check_alarm(self, good, beam) if needNewGlobal: glo = rs.Beam(copyFrom=lo) raycing.virgin_local_to_global(self.bl, glo, self.center, good) return glo, lo else: raycing.append_to_flow(self.propagate, [lo], inspect.currentframe()) return lo
def propagate(self, beam=None, needNewGlobal=False): """Assigns the "lost" value to *beam.state* array for the rays intercepted by the aperture. The "lost" value is ``-self.ordinalNum - 1000.`` .. Returned values: beamLocal """ if self.bl is not None: self.bl.auto_align(self, beam) good = beam.state > 0 # beam in local coordinates lo = rs.Beam(copyFrom=beam) raycing.global_to_virgin_local(self.bl, beam, lo, self.center, good) path = -lo.y[good] / lo.b[good] lo.x[good] += lo.a[good] * path lo.z[good] += lo.c[good] * path lo.path[good] += path footprint = mplPath(self.vertices) badIndices = np.invert(footprint.contains_points(np.array( list(zip(lo.x, lo.z))))) beam.state[badIndices] = self.lostNum lo.state[good] = beam.state[good] lo.y[good] = 0. if hasattr(lo, 'Es'): propPhase = np.exp(1e7j * (lo.E[good]/CHBAR) * path) lo.Es[good] *= propPhase lo.Ep[good] *= propPhase if self.alarmLevel is not None: raycing.check_alarm(self, good, beam) if needNewGlobal: glo = rs.Beam(copyFrom=lo) raycing.virgin_local_to_global(self.bl, glo, self.center, good) return glo, lo else: raycing.append_to_flow(self.propagate, [lo], inspect.currentframe()) return lo
def gradient_fill(x, y, axes, color, flip=True): """ Plot a linear alpha gradient beneath x y values. Here, x and y are transposed due to the nature of DOS graphs. Parameters ---------- x, y : array-like The data values of the line. Additional arguments are passed on to matplotlib's ``plot`` function. """ xmin, xmax, ymin, ymax = x.min(), x.max(), y.min(), y.max() xy = np.column_stack([x, y]) if flip: z = np.empty((1, 100, 4), dtype=float) z[:, :, -1] = np.linspace(0, 1, 100)[None, :] rgb = matplotlib.colors.colorConverter.to_rgb(color) z[:, :, :3] = rgb im = axes.imshow(z, aspect="auto", extent=[xmin, xmax, ymin, ymax], origin="upper") path = np.vstack([[0, ymin], xy, [0, ymax], [0, 0], [0, 0]]) else: z = np.empty((100, 1, 4), dtype=float) z[:, :, -1] = np.linspace(0, 1, 100)[:, None] rgb = matplotlib.colors.colorConverter.to_rgb(color) z[:, :, :3] = rgb im = axes.imshow(z, aspect="auto", extent=[xmin, xmax, ymin, ymax], origin="lower") path = np.vstack([[xmin, ymin], xy, [xmax, ymin], [xmin, ymin]]) path = mplPath(path, closed=True) patch = PathPatch(path, facecolor="none", edgecolor="none") axes.add_patch(patch) im.set_clip_path(patch) return axes
def polygonsOverlap(poly1, poly2): """Determine if two polygons intersect; can fail for very pointy polygons. Accepts two polygons, as lists of vertices (x,y) pairs. If given an object with with (vertices + pos), will try to use that as the polygon. Checks if any vertex of one polygon is inside the other polygon. Same as the `.overlaps()` method elsewhere. :Notes: We implement special handling for the `Line` stimulus as it is not a proper polygon. We do not check for class instances because this would require importing of `visual.Line`, creating a circular import. Instead, we assume that a "polygon" with only two vertices is meant to specify a line. Pixels between the endpoints get interpolated before testing for overlap. """ try: # do this using try:...except rather than hasattr() for speed if poly1.verticesPix.shape == (2, 2): # Line # Interpolate pixels. x = np.arange(poly1.verticesPix[0, 0], poly1.verticesPix[1, 0] + 1) y = np.arange(poly1.verticesPix[0, 1], poly1.verticesPix[1, 1] + 1) poly1_vert_pix = np.column_stack((x, y)) else: poly1_vert_pix = poly1.verticesPix except AttributeError: poly1_vert_pix = poly1 try: # do this using try:...except rather than hasattr() for speed if poly2.verticesPix.shape == (2, 2): # Line # Interpolate pixels. x = np.arange(poly2.verticesPix[0, 0], poly2.verticesPix[1, 0] + 1) y = np.arange(poly2.verticesPix[0, 1], poly2.verticesPix[1, 1] + 1) poly2_vert_pix = np.column_stack((x, y)) else: poly2_vert_pix = poly2.verticesPix except AttributeError: poly2_vert_pix = poly2 # faster if have matplotlib tools: if haveMatplotlib: if matplotlib.__version__ > '1.2': if any(mplPath(poly1_vert_pix).contains_points(poly2_vert_pix)): return True return any(mplPath(poly2_vert_pix).contains_points(poly1_vert_pix)) else: try: # deprecated in matplotlib 1.2 if any( nxutils.points_inside_poly(poly1_vert_pix, poly2_vert_pix)): return True return any( nxutils.points_inside_poly(poly2_vert_pix, poly1_vert_pix)) except Exception: pass # fall through to pure python: for p1 in poly1_vert_pix: if pointInPolygon(p1[0], p1[1], poly2_vert_pix): return True for p2 in poly2_vert_pix: if pointInPolygon(p2[0], p2[1], poly1_vert_pix): return True return False
def polygonsOverlap(poly1, poly2): """Determine if two polygons intersect; can fail for very pointy polygons. Accepts two polygons, as lists of vertices (x,y) pairs. If given an object with with (vertices + pos), will try to use that as the polygon. Checks if any vertex of one polygon is inside the other polygon. Same as the `.overlaps()` method elsewhere. :Notes: We implement special handling for the `Line` stimulus as it is not a proper polygon. We do not check for class instances because this would require importing of `visual.Line`, creating a circular import. Instead, we assume that a "polygon" with only two vertices is meant to specify a line. Pixels between the endpoints get interpolated before testing for overlap. """ try: # do this using try:...except rather than hasattr() for speed if poly1.verticesPix.shape == (2, 2): # Line # Interpolate pixels. x = np.arange(poly1.verticesPix[0, 0], poly1.verticesPix[1, 0] + 1) y = np.arange(poly1.verticesPix[0, 1], poly1.verticesPix[1, 1] + 1) poly1_vert_pix = np.column_stack((x,y)) else: poly1_vert_pix = poly1.verticesPix except AttributeError: poly1_vert_pix = poly1 try: # do this using try:...except rather than hasattr() for speed if poly2.verticesPix.shape == (2, 2): # Line # Interpolate pixels. x = np.arange(poly2.verticesPix[0, 0], poly2.verticesPix[1, 0] + 1) y = np.arange(poly2.verticesPix[0, 1], poly2.verticesPix[1, 1] + 1) poly2_vert_pix = np.column_stack((x,y)) else: poly2_vert_pix = poly2.verticesPix except AttributeError: poly2_vert_pix = poly2 # faster if have matplotlib tools: if haveMatplotlib: if parse_version(matplotlib.__version__) > parse_version('1.2'): if any(mplPath(poly1_vert_pix).contains_points(poly2_vert_pix)): return True return any(mplPath(poly2_vert_pix).contains_points(poly1_vert_pix)) else: try: # deprecated in matplotlib 1.2 if any(nxutils.points_inside_poly(poly1_vert_pix, poly2_vert_pix)): return True return any(nxutils.points_inside_poly(poly2_vert_pix, poly1_vert_pix)) except Exception: pass # fall through to pure python: for p1 in poly1_vert_pix: if pointInPolygon(p1[0], p1[1], poly2_vert_pix): return True for p2 in poly2_vert_pix: if pointInPolygon(p2[0], p2[1], poly1_vert_pix): return True return False