def get_mask(self, reference_image, mask, label, idx, continuous): size = reference_image.GetSize()[::-1] physical_points = self.roi_points.get(label, np.array([])) mask_points = physical_points_to_idxs(reference_image, physical_points, continuous=continuous) for contour in mask_points: try: z, slice_points = np.unique(contour[:, 0]), contour[:, 1:] if len(z) == 1: #f assert len(z) == 1, f"This contour ({name}) spreads across more than 1 slice." z = z[0] slice_mask = polygon2mask(size[1:], slice_points) mask[z, :, :, idx] += slice_mask except: # rounding errors for points on the boundary if z == mask.shape[0]: z -= 1 elif z == -1: z += 1 elif z > mask.shape[0] or z < -1: raise IndexError( f"{z} index is out of bounds for image sized {mask.shape}." ) # if the contour spans only 1 z-slice if len(z) == 1: z = int(np.floor(z[0])) slice_mask = polygon2mask(size[1:], slice_points) mask[z, :, :, label] += slice_mask else: raise ValueError( "This contour is corrupted and spans across 2 or more slices." )
def segment_fields(xx, yy, freq, rate, area_thresh): xbound = (0, xx.shape[1]-1) ybound = (0, yy.shape[0]-1) normmap = rate / rate.max() # Padding to make sure contour is always closed padded_normmap = np.zeros((normmap.shape[0]+10, normmap.shape[1]+10)) padded_normmap[5:-5, 5:-5] = normmap contours = find_contours(padded_normmap, level=0.2) for c_each in contours: c_rowi = c_each[:, 0] - 5 # y c_coli = c_each[:, 1] - 5 # x c_rowi, c_coli = np.clip(c_rowi, a_min=ybound[0], a_max=ybound[1]), np.clip(c_coli, a_min=xbound[0], a_max=xbound[1]) c_coli, c_rowi, case = complete_contourline(c_coli, c_rowi, xbound=xbound, ybound=ybound) mask = polygon2mask(xx.shape, np.stack([c_rowi, c_coli]).T) # Remember to transpose! c_rowi = np.around(c_rowi).astype(int) c_coli = np.around(c_coli).astype(int) c_x = xx[c_rowi, c_coli] c_y = yy[c_rowi, c_coli] xyval = np.stack([c_x, c_y]).T area = mask.sum() if area < 1: continue meanrate_in = np.mean(rate[mask]) meanrate_out = np.mean(rate[np.invert(mask)]) peak_freq_in = freq[mask].max() if (area > area_thresh) and (meanrate_in > meanrate_out) and (peak_freq_in > 1): yield mask, xyval
def _poly2mask(masks, size): """ Helper function to convert polygon masks since they can be lists, arrays, or PolygonMask instances Parameters ---------- masks: list list of arrays containing polygon coordinates [x0,y0,x1,y1,...,xn,yn] size: tuple height, width of mask in pixels Returns --------- bitmask_array: ndarray n_mask x height x width array where bitmask_array[i] gives a binary mask """ return np.stack([ polygon2mask( # stack along axis 0 to get (n x r x c) size, np.stack( ( p[1::2], # x coords p[0::2]), # y coords axis=1)) # stack along axis 1 to get (n_p x 2) for p in masks ]) # for every polygon
def create_voltage_signal(self, list_of_rois): filled_mask = OriginalImage = np.zeros((1000, 1000)) for roi in list_of_rois: filled_mask += polygon2mask((1000, 1000), (roi + 5) * 100) filled_mask = (filled_mask > 0).astype(int).transpose() fig, axs = plt.subplots(1, 1) axs.imshow(filled_mask) scanning_voltage = 5 points_per_contour = int(self.points_per_contour_textbox.text()) sampling_rate = int(self.sampling_rate_textbox.text()) contourScanningSignal = ProcessImage.mask_to_contourScanning_DAQsignals( filled_mask, OriginalImage, scanning_voltage, points_per_contour, sampling_rate, repeats=1) contourScanningSignal = np.vstack( (contourScanningSignal[0][0], contourScanningSignal[1][0])) self.galvoThread = pmtimagingTest_contour() self.galvoThread.setWave_contourscan(sampling_rate, contourScanningSignal, points_per_contour)
def _filter(x: NDImage) -> NDBoolMask: shape = x.shape[:2] mask = np.zeros(shape, dtype=bool) for polygon in polygons: polygon = polygon / 100 * np.array(shape) mask = mask | polygon2mask(shape, polygon) return mask
def mask_of_polygons(self, polygons): image = np.zeros(self.map_size, dtype=bool) for polygon in polygons: idx_polygon = self.get_indices_of_coordinates(polygon) temp = polygon2mask(self.map_size, idx_polygon) # TODO: speed up using opencv image = np.logical_or(image, temp) return image
def __QPolygon2Mask(imageShape: np.array, polygon: QPolygonF): poa = np.empty([len(polygon), 2]) for i, p in enumerate(polygon): poa[i, :] = [p.x(), p.y()] # poa = np.append(poa, [p.x(), p.y()]) from skimage import draw mask = draw.polygon2mask([imageShape[1], imageShape[0]], poa) return mask.transpose()
def update_mod(self): imod = self.__image_raw.copy() # apply threshold imod[imod < self._threshold] = self.min_val() # apply mask mask = polygon2mask(imod.shape, self._mask_poly) imod = imod * mask self.__image_raw_mod = imod * mask
def get_exterior_mask(a_stack, p_out=None, verbose=False): ''' This filter will build a non-convex exterior mask based on the alpha-complex approach. After Delaunay triangulation, exterior triangles are filtered out by checking if their circumcenter falls inside the convex hull. The outline of the interior triangles is then retrieved and a mask is created This approach can be an alternative for the active contour, In theory the same approach could be applied in 3D, but runtime is a bottleneck given the large amount of circumcenters""" ''' a_exterior_mask = np.zeros(a_stack.shape, dtype='uint16') prev_slice = None with warnings.catch_warnings(): warnings.simplefilter("ignore") for ix_slice, a_slice in enumerate(a_stack): if not a_slice.any(): a_exterior_mask[ix_slice] = a_slice try: a_points = _downsample_membrane_points(a_slice) a_circumcenters, a_circumradii, tri = _get_voronoi_points( a_points) a_selector_inside_hull, hull = _test_points_inside_convex_hull( a_check=a_circumcenters, a_points_hull=a_points) a_non_convex_hull_simplices = \ tri.simplices[a_selector_inside_hull] a_boundary_edges = _get_boundary_edges( a_non_convex_hull_simplices) l_polygon_loop = _get_polygon_loop(a_boundary_edges, verbose=False) # orders matters, has to be sequential outline of a polygon a_exterior_mask[ix_slice] = polygon2mask( a_slice.shape, a_points[l_polygon_loop]) prev_slice = a_exterior_mask[ix_slice] except Exception as e: # traceback.print_exc() if prev_slice is not None and prev_slice.any(): if verbose: print(f"{ix_slice}<", end="") a_exterior_mask[ix_slice] = prev_slice else: if verbose: print(f"{ix_slice}x", end="") a_exterior_mask[ix_slice] = a_slice if p_out: with warnings.catch_warnings(): p_out.parent.mkdir(parents=True, exist_ok=True) imsave_fiji(p_out, a_exterior_mask.astype('uint16')) return a_exterior_mask
def get_zones_for_slice_by_curves(contours, shape, size=1, curves_values=[]): liver_slice, *curves = contours shape = shape[:2] mask = np.zeros(shape) if not liver_slice.any(): return mask contour = liver_slice.copy() last_hit = 0 for i, curve in enumerate(curves, 1): if not curve.any(): continue # if we have not correct curve split_contour_by_curve returns ValueError (see cut_curve_outside) try: contour, zone = split_contour_by_curve(curve, contour, size) # check if we swap contour and zone # angle magic - we want to cut zones in clockwise order contour_centre, zone_centre = contour.mean(axis=0), zone.mean( axis=0) contour_angle = get_angle(shape - contour_centre, np.array([0, -1])) zone_angle = get_angle(shape - zone_centre, np.array([0, -1])) if zone_angle > contour_angle: contour, zone = zone, contour except ValueError: continue last_hit = i temp_mask = polygon2mask(shape, zone) mask[temp_mask] = i temp_mask = polygon2mask(shape, contour) mask[temp_mask] = last_hit + 1 # TODO: add pixels in plot_curve to returned mask if curves_values: for n, c in zip(curves_values, contours): mask[plot_curve(c, shape)] = n return mask
def box_and_mask(self): min = self.vertices.min(0) max = self.vertices.max(0) box = Box(min, max) local_shape = (box.width, box.height) local_polygon = self.vertices - min mask = polygon2mask(local_shape, local_polygon) return box, mask
def mask_region(DEM, bounds, polygon, m_val=-1): if m_val == None: m_val = np.min(DEM) GeoStart = bounds[[0, 3]] polygon = map_coor_2_pixel(polygon[::-1, :], GeoStart) polygon = simplify_polygon(polygon) mask = polygon2mask(DEM.shape, polygon) DEM[np.logical_not(mask)] = m_val return DEM
def bin_lattice(image, latticesites, latticevectors): """ Histogram an image based on defined lattice. Inputs: image ndarray latticesites ndarray latticevectors tuple? Outputs totals list, with same order as latticesites """ #scale = 5 #image = transform.resize(image,(image.shape[0]*scale,image.shape[1]*scale),order = 0,mode = "edge") halfvectors = latticevectors / 2 totals = [] #print(halfvectors) firstpoint = latticesites[0] pixelsize = 1 i = 0 for i in range(latticesites.shape[0]): point = latticesites[i, :] square = np.array( [[ point[1] - (halfvectors[0][1] + halfvectors[1][1]), point[0] - (halfvectors[0][0] + halfvectors[1][0]), ], [ point[1] - (-halfvectors[0][1] + halfvectors[1][1]), point[0] - (-halfvectors[0][0] + halfvectors[1][0]) ], [ point[1] - (-halfvectors[0][1] - halfvectors[1][1]), point[0] - (-halfvectors[0][0] - halfvectors[1][0]) ], [ point[1] - (halfvectors[0][1] - halfvectors[1][1]), point[0] - (halfvectors[0][0] - halfvectors[1][0]) ]]) # if np.all(square>0) and np.all(square<image.shape[0]): #NB the way the lattice is returned means point[0] is 2nd index of the mask mask = draw.polygon2mask(image.shape, square) totals.append(np.sum(image[mask])) return np.array(totals)
def poly_to_mask(mask_shape, vertices): """Converts a polygon to a boolean mask with `True` for points lying inside the shape. Uses the bounding box of the vertices to reduce computation time. Parameters ---------- mask_shape : np.ndarray | tuple 1x2 array of shape of mask to be generated. vertices : np.ndarray Nx2 array of the vertices of the polygon. Returns ------- mask : np.ndarray Boolean array with `True` for points inside the polygon """ return polygon2mask(mask_shape, vertices)
def contour_to_mask(ctr, m, upsample=1): """ Given set of coordinates definining a contour in world coordinates, create a mask that is 1 inside the contour and 0 outside. Parameters ---------- ctr : astropy.coordinates.SkyCoord m : sunpy.map.Map Returns ------- mask : sunpy.map.Map """ from skimage import draw # Get pixel values of the contour ch_indices = np.array(m.wcs.world_to_pixel(ctr)).T mask = draw.polygon2mask(m.data.shape, ch_indices) return mask
def createMaskSingleROI(self, vertices): if self.ui_widget.selectionMode == "polygonMode": flag_fill_contour = self.ui_widget.polygonFillContourButton.isChecked( ) else: flag_fill_contour = self.ui_widget.freehandFillContourButton.isChecked( ) if flag_fill_contour: return polygon2mask((1024, 768), vertices) else: mask = np.zeros((1024, 768)) mask[polygon_perimeter(vertices[:, 0], vertices[:, 1], (1024, 768))] = 1 # The mask now created contains a one pixel thick perimeter. In order # to make the perimeter thicker, binary dilation is performed. mask = binary_dilation(binary_dilation(mask)) return mask
def mask_from_polyon_shape(shape, imshape): """Converts an omero roi `shape` (as returned by the `roi.getShape` method) to a binay image with the pixels inside the shape set to 1. Parameters ---------- shape : `omero.model.PolygonI` instance imshape : tuple, the shape of the output mask Returns ------- mask : `np.ndarray` of shape `imshape` and dtype uint8 with ones inside the input shape. """ points = shape.getPoints() points = np.array([[float(v) for v in l.split(",") if v] for l in points.val.split(" ")]) return polygon2mask(imshape, points).astype(np.uint8)
def get_zones_for_slice_by_lines(curves, shape, curves_values=[]): """ curves : slices of ['Left', 'Middle','Right'] """ shape = shape[:2] mask = np.zeros(shape) bounds = [[0, 0], [0, shape[1]], shape, [shape[0], 0]] bounds = np.array(bounds) for n, curve in zip([1, 10, 100], curves): if not curve.any(): raise ValueError('Got empty curve') # continue # extrapolate line to borders curve = intersect_line_and_image(curve, shape) contour, zone = split_contour_by_curve(curve, bounds, 1) # check if we swap contour and zone # angle magic - we want to cut zones in clockwise order contour_centre, zone_centre = contour.mean(axis=0), zone.mean(axis=0) contour_angle = get_angle(shape - contour_centre, np.array([0, -1])) zone_angle = get_angle(shape - zone_centre, np.array([0, -1])) if zone_angle > contour_angle: contour, zone = zone, contour mask += n * polygon2mask(shape, zone) for i, n in enumerate([111, 110, 100, 0], 1): mask[mask == n] = i # TODO: add pixels in plot_curve to returned mask if curves_values: for n, c in zip(curves_values, curve): c = intersect_line_and_image(c, shape) mask[plot_curve(c, shape)] = n return mask
def __getitem__(self, index): ''' Capturing data from datasets according to input index Parameters: index: type(int)(0-len(self)) return: ''' sid, yid, pid = self.get_index(index) img_name = self.img_list[sid] annotation = self.json_list[sid] with open(annotation) as reader: an = json.load(reader) points = (an['shapes'][0]['points']) points = np.asarray(points) w, h = an['imageWidth'], an['imageHeight'] points = points[:, ::-1] mask = draw.polygon2mask((h, w), points) mask = np.asarray(mask, dtype=np.uint8) mask[mask > 0] = 255 img = cv2.imread(img_name) img[mask == 0] = 0 mask = mask[..., None] mask = np.repeat(mask, 3, axis=2) tmp_keys = img_name.split("/") keys = [] keys += tmp_keys[:-1] keys.append(tmp_keys[-1].replace('.jpeg', '')) keys.append(tmp_keys[-1]) img_name = os.path.join(*keys) val = dict(name=img_name, img=img, mask=mask) val = self.transformer(val) val['img'] = val['mask'].expand_as(val['img']) * val['img'] return val
def toy_voronoi_labels_affinities( width_, height_, radius, opening_radius, deform_sigma, deform_points, intensity_prob, noise_sigma ): # we will create bigger images such that we can crop out regions, # that look good offset = 2 * radius height = height_ + 2 * offset width = width_ + 2 * offset shape = (height, width) labels = np.zeros(shape, dtype=np.uint16) sketch = np.zeros_like(labels, dtype=float) # r is the distance between two center points, so we need to multiply by 2 centers = poisson_disc_samples(width=width, height=height, r=radius * 2) # append far points to centers to complete voronoi regions x_max = width + 1 y_max = height + 1 centers = centers + [(-1, -1), (-1, y_max), (x_max, -1), (x_max, y_max)] vor = Voronoi(centers) # create selem with provided radius to apply clsoing selem = disk(opening_radius) for i, region in enumerate(vor.regions): if -1 in region or len(region) == 0: continue polygon = [vor.vertices[i] for i in region] mask = polygon2mask(shape, polygon) # close polygon mask with provided selem and radius mask = binary_opening(mask, selem) # enumerate starts at 0, but 0 is background labels[mask] = i + 1 edt = distance_transform_edt(mask) edt = edt / edt.max() tmp_intensity = np.random.uniform(*intensity_prob) sketch[mask] = edt[mask] * tmp_intensity sketch = scipy.ndimage.gaussian_filter(sketch, radius / 4) [labels, sketch] = elasticdeform.deform_random_grid( [labels, sketch], sigma=deform_sigma, points=deform_points, # labels must be interpolated by nearest neighbor order=[0, 3], crop=( slice(offset, offset + height_ + 1), slice(offset, offset + width_ + 1) ) ) # labels = labels[offset:-offset + 1, offset:-offset + 1] # sketch = sketch[offset:-offset + 1, offset:-offset + 1] noise = sketch + np.random.normal(0, noise_sigma, size=sketch.shape) affinities = get_affinities(labels) return labels[:-1, :-1], sketch[:-1, :-1], noise[:-1, :-1], affinities
def get_shortest_path_mask(mat, spr=1, diag=1, ker_prep=5): print(mat.shape) mat = cv.GaussianBlur(mat, (ker_prep, ker_prep), 0) verts = find_shortest_path(mat, spr, diag) verts = np.concatenate((verts, [[mat.shape[0], 0], [0, 0]]), axis=0) return draw.polygon2mask(mat.shape[:2], verts)
def fill_boundary(shape, bpts): t_or_f = draw.polygon2mask(shape, bpts[:, [1, 0]]) mask = np.zeros_like(t_or_f, dtype=np.uint8) mask[t_or_f] = 1 return mask
def test_polygon2mask(): mask = draw.polygon2mask(image_shape, polygon) assert mask.shape == image_shape assert mask.sum() == 57653
def get_foreground2(im): im_thresh = threshold(im) contours = find_contours(im_thresh,.9,fully_connected='high', positive_orientation='low') msk = polygon2mask(im.shape[:2],contours[0]).astype('uint8') return msk
# METHODE CREER MASK V1 mask = np.zeros(shape=(height, width), dtype=np.uint8) # Pour chaque carrie dans une radio for item in data[currentImg]: # points de type polygon ou autre if (item['type'] == "polygon"): at_least_one_carry = True res = [] for a, b in pairwise(item['points']): res.append((b, a)) # METHODE CREER MASK V1 tmpMask = polygon2mask((height, width), res).astype(int) tmpMask[tmpMask == 1] = int(item['classId']) mask[:, :] = np.maximum(mask[:, :], tmpMask[:, :]) #cv2.imwrite(currentImgPathSave, mask, params=cv2.IMREAD_GRAYSCALE) toSave = Image.fromarray(mask, 'L') toSave.save(currentImgPathSave) #GEN NUMPY FILES ''' newName = currentImg.split(".")[0] + ".npy" toSave = os.path.join(dirImgDst, newName)
def compute_lvLA(P, lv): p1 = P[0] p2 = P[1] p3 = P[2] mvcenter = p2 cprod = np.cross((p1 - p2), (p3 - p2)) n = cprod / np.linalg.norm(cprod) for i in range(0, 1): thickness = 2 count = 0 top_plane = [] for j in range(0, len(lv)): if abs(np.dot(n, mvcenter - lv[j, :])) < thickness: top_plane.append(lv[j, :]) # evaluate LV's top plane and fit a plane on to the data points top_plane = np.array(top_plane) [n, V, mvcenter] = affine_fit(top_plane) n = np.array(n) tngnt = n node_pt = mvcenter if tngnt[2] != 0: pt1 = [ 1, 1, (-tngnt[0] - tngnt[1] + np.dot(tngnt, node_pt)) / tngnt[2] ] elif tngnt[1] != 0: pt1 = [ 1, (-tngnt[0] - tngnt[2] + np.dot(tngnt, node_pt)) / tngnt[1], 1 ] else: pt1 = [(-tngnt[1] - tngnt[2] + np.dot(tngnt, node_pt)) / tngnt[0], 1, 1] # Find two inplane vectors to take projections tangent = np.array(tngnt / (np.sqrt(np.dot(tngnt, tngnt)))) v1 = np.array(pt1 - node_pt) v2 = np.cross(tangent, v1) v1n = v1 / np.linalg.norm(v1) v2n = v2 / np.linalg.norm(v2) count = 0 proj = [] # iterate through the LV data and store projections for j in range(len(lv)): sample = lv[j, :] proj.append( proj_on_plane(tangent, X=np.array([v1n, v2n]), a=np.array([node_pt, sample]))) count += 1 proj = np.array(proj) hull = ConvexHull(proj) xtrans = min(proj[hull.vertices, 0]) ytrans = min(proj[hull.vertices, 1]) # fig = plt.figure() # plt.plot(proj[hull.vertices,0],proj[hull.vertices,1]) projections = [] for ii in range(0, len(hull.vertices)): projections.append([ proj[hull.vertices[ii], 0] - xtrans + 5, proj[hull.vertices[ii], 1] - ytrans + 5 ]) projections = np.array(projections) # print(projections) image_shape = (250, 250) polygon = projections mask = polygon2mask(image_shape, polygon) # print(mask) img = mask label_img = label(img) regions = regionprops(label_img) for props in regions: xcentroid = props.centroid[0] ycentroid = props.centroid[1] print(props.centroid) # xcentroid = np.mean(proj[:,0]) + xtrans-5 # ycentroid = np.mean(proj[:,1]) + ytrans-5 proj_ctd = np.array([xcentroid + xtrans - 5, ycentroid + ytrans - 5]) mvcenter = proj_ctd[0] * v1n + proj_ctd[1] * v2n + node_pt apex = generateLVApexPts(lv) long_axisv = mvcenter - apex long_axis = long_axisv / np.linalg.norm(long_axisv) print("long_axis = ", long_axis) # print('apex1',apex) return long_axis, mvcenter, apex
def _poly2mask(self, coords_x, coords_y, shape): mask = draw.polygon2mask(tuple(reversed(shape)), np.column_stack((coords_y, coords_x))) return mask
def detect_lines(self, img, region): """Performs simple line extraction in single text region using thresholding, correlation and connected component analysis. :param img: input image array :param region: target region polygon """ baselines_list = [] heights_list = [] y1 = np.amin(region[:, 0].astype(np.int32)) y2 = np.amax(region[:, 0].astype(np.int32)) x1 = np.amin(region[:, 1].astype(np.int32)) x2 = np.amax(region[:, 1].astype(np.int32)) if y2 == y1 or x1 == x2: return [], [], [] column_width = x2 - x1 column_height = y2 - y1 img_mask = polygon2mask(img.shape[0:2], region) img_mask = img_mask[y1:y2, x1:x2] img_mask = binary_erosion(img_mask, structure=np.ones( (1, 2 * self.ignored_border_pixels + 1))) img_crop = img[y1:y2, x1:x2, :] img_crop = img_crop.mean(axis=2).astype(np.uint8) img_crop = cv2.adaptiveThreshold(img_crop, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, self.block_size, self.adaptive_threshold) == 0 img_crop = img_crop * img_mask img_crop_labeled, num_features = ndimage.measurements.label(img_crop) proj = np.sum(img_crop, axis=1) corr = np.correlate(proj, proj, mode='full')[proj.shape[0]:] corr_peaks = signal.find_peaks(corr, prominence=0, distance=1)[0] if len(corr_peaks) > 0: line_period = float( signal.find_peaks(corr, prominence=0, distance=1)[0][0]) else: line_period = 1 target_signal = -np.diff(proj) target_signal[target_signal < 0] = 0 baseline_coords = signal.find_peaks(target_signal, distance=int( round(0.85 * line_period)))[0] region = shapely.geometry.polygon.Polygon(region) used_inds = [] for baseline_coord in baseline_coords[::-1]: valid_baseline = True matching_objects = np.unique(img_crop_labeled[baseline_coord - 10, :])[1:] if len(matching_objects) > 0: for ind in matching_objects: if ind in used_inds: valid_baseline = False used_inds.append(ind) for yb1 in range(baseline_coord, 0, -3): line_inds_to_check = img_crop_labeled[yb1, :] if not np.any( np.intersect1d(matching_objects, line_inds_to_check)): break for yb2 in range(baseline_coord, column_height, 3): line_inds_to_check = img_crop_labeled[yb2, :] if not np.any( np.intersect1d(matching_objects, line_inds_to_check)): break xb1, xb2 = 0, column_width if yb2 - yb1 < self.minimum_length: valid_baseline = False line = shapely.geometry.LineString( [[y1 + baseline_coord, x1 + xb1 - 20], [y1 + baseline_coord, x1 + xb2 + 20]]) intersection = region.intersection(line) if not intersection.is_empty: if valid_baseline: baselines_list.append( np.flip(np.round( np.asarray( list(region.intersection( line).coords[:]))).astype(np.int16), axis=1)) heights_list.append( [baseline_coord - yb1, yb2 - baseline_coord]) textlines_list = [ pp.baseline_to_textline(baseline, heights) for baseline, heights in zip(baselines_list, heights_list) ] return baselines_list, heights_list, textlines_list
def __init__(self, anchor, invisible_elements=None, normalize=True, noise_params=None, only_front=False, **sensor_params): """ Refer to Sensor Class. Args: anchor: body Part to which the sensor is attached. Sensor is attached to the center of the Part. invisible_elements: elements that the sensor does not perceive. List of Parts of SceneElements. normalize: if true, Sensor values are normalized between 0 and 1. Default: True only_front: Only return the half part of the Playground that the Sensor faces. Remove what is behind the sensor. Default: False. """ default_config = parse_configuration('agent_sensors', self.sensor_type) sensor_params = {**default_config, **sensor_params} super().__init__(anchor=anchor, invisible_elements=invisible_elements, normalize=normalize, noise_params=noise_params, **sensor_params) if invisible_elements: self._invisible_elements = invisible_elements else: self._invisible_elements = [] self.only_front = only_front self._center = (int(self._resolution / 2) - 1, int(self._resolution / 2) - 1) # Calculate range with circle mask_circle = np.zeros((self._resolution, self._resolution), dtype=bool) rr, cc = draw.disk((self._center[0], self._center[1]), (int(self._resolution / 2) - 1), shape=mask_circle.shape) mask_circle[rr, cc] = 1 # Calculate fov with poly points = [[(int(self._resolution / 2) - 1), 0], [0, 0], [0, self._resolution], [(int(self._resolution / 2) - 1), self._resolution]] if self._fov > math.pi: points = [[self._resolution, 0] ] + points + [[self._resolution, self._resolution]] r1 = self._center[0] - (int(self._resolution / 2) - 1) * np.sin(math.pi / 2 + self._fov / 2) c1 = self._center[1] + (int(self._resolution / 2) - 1) * np.cos(math.pi / 2 + self._fov / 2) r2 = self._center[0] - (int(self._resolution / 2) - 1) * np.sin(math.pi / 2 - self._fov / 2) c2 = self._center[1] + (int(self._resolution / 2) - 1) * np.cos(math.pi / 2 - self._fov / 2) points = points + [[r2, c2], self._center, [r1, c1]] mask_poly = draw.polygon2mask((self._resolution, self._resolution), np.array(points)) self.mask_total_fov = mask_circle & mask_poly self._sensor_max_value = 255
def __QPolygon2Mask(imageShape: np.array, polygon: QPolygonF): poa = np.empty([len(polygon), 2]) for i, p in enumerate(polygon): poa[i, :] = [p.x(), p.y()] # poa = np.append(poa, [p.x(), p.y()]) return draw.polygon2mask(imageShape, poa)