Example #1
0
    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
Example #3
0
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
Example #4
0
    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)
Example #5
0
 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
Example #6
0
 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
Example #7
0
 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()
Example #8
0
 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
Example #9
0
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
Example #10
0
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
Example #11
0
    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
Example #12
0
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
Example #13
0
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)
Example #14
0
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)
Example #15
0
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
Example #16
0
    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)
Example #18
0
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
Example #19
0
    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
Example #20
0
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
Example #21
0
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)
Example #22
0
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
Example #23
0
def test_polygon2mask():
    mask = draw.polygon2mask(image_shape, polygon)
    assert mask.shape == image_shape
    assert mask.sum() == 57653
Example #24
0
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
Example #25
0
        # 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)
Example #26
0
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
Example #28
0
    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
Example #30
0
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)