Compute region outline by differencing two dilations.

        Parameters
        ----------
        inner : int
            Size of inner outline boundary (in pixels)

        outer : int
            Size of outer outline boundary (in pixels)
554917
def outline(self, inner, outer):
        
        return self.dilate(outer).exclude(self.dilate(inner))
769393
def outline(labels):
    
    
    output = numpy.zeros(labels.shape, labels.dtype)
    lr_different = labels[1:,:]!=labels[:-1,:]
    ud_different = labels[:,1:]!=labels[:,:-1]
    d1_different = labels[1:,1:]!=labels[:-1,:-1]
    d2_different = labels[1:,:-1]!=labels[:-1,1:]
    different = numpy.zeros(labels.shape, bool)
    different[1:,:][lr_different]  = True
    different[:-1,:][lr_different] = True
    different[:,1:][ud_different]  = True
    different[:,:-1][ud_different] = True
    different[1:,1:][d1_different] = True
    different[:-1,:-1][d1_different] = True
    different[1:,:-1][d2_different] = True
    different[:-1,1:][d2_different] = True
    #
    # Labels on edges need outlines
    #
    different[0,:] = True
    different[:,0] = True
    different[-1,:] = True
    different[:,-1] = True
    
    output[different] = labels[different]
    return output
1031681
def inROI(self, Y):
        ''''''
        if Y.ndim > 1:
            area = np.zeros((Y.shape[0],4))
        else:
            area = np.zeros((1,4))
        pts = np.zeros((0,), int)
        pdist = np.zeros((0,), int)
        dist0 = 0
        for k in range(len(self.prect)):
            self.square_area = (triangle_area(self.prect[k][0,:], self.prect[k][1,:], self.prect[k][2,:]) +
                            triangle_area(self.prect[k][2,:], self.prect[k][3,:], self.prect[k][4,:]))
            for n in range(4):
                area[:,n] = triangle_area(self.prect[k][0+n,:], self.prect[k][1+n,:], Y)
            # points inside prect
            newpts = np.array((area.sum(axis=1) <= self.square_area+1e-5).nonzero()).flatten().astype(int)
            if newpts.size > 0:
                pts = np.concatenate((pts, newpts))
                newdists = self.orthproj(Y[newpts, :], k) + dist0
                pdist = np.concatenate((pdist, newdists))
            dist0 += (np.diff(self.pos[k], axis=0)[0,:]**2).sum()
            # check if in radius of circle
            if k < len(self.prect)-1:
                pcent = self.pos[k][1,:]
                dist = ((Y - pcent[np.newaxis,:])**2).sum(axis=1)**0.5
                newpts = np.array((dist<=self.d).nonzero()[0].astype(int))
                if newpts.size > 0:
                    pts = np.concatenate((pts, newpts))
                    newdists = dist0 * np.ones(newpts.shape)
                    pdist = np.concatenate((pdist, newdists))

        pts, inds = np.unique(pts, return_index=True)
        pdist = pdist[inds]
        return pts, pdist
1015180
def draw_boundary_images(glf, glb, v, f, vpe, fpe, camera):
    """"""
    glf.Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glb.Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    # Figure out which edges are on pairs of differently visible triangles
    from opendr.geometry import TriNormals
    tn = TriNormals(v, f).r.reshape((-1,3))
    campos = -cv2.Rodrigues(camera.rt.r)[0].T.dot(camera.t.r)
    rays_to_verts = v.reshape((-1,3)) - row(campos)
    rays_to_faces = rays_to_verts[f[:,0]] + rays_to_verts[f[:,1]] + rays_to_verts[f[:,2]]
    dps = np.sum(rays_to_faces * tn, axis=1)
    dps = dps[fpe[:,0]] * dps[fpe[:,1]]
    silhouette_edges = np.asarray(np.nonzero(dps<=0)[0], np.uint32)
    non_silhouette_edges = np.nonzero(dps>0)[0]
    lines_e = vpe[silhouette_edges]
    lines_v = v

    visibility = draw_edge_visibility(glb, lines_v, lines_e, f, hidden_wireframe=True)
    shape = visibility.shape
    visibility = visibility.ravel()
    visible = np.nonzero(visibility.ravel() != 4294967295)[0]
    visibility[visible] = silhouette_edges[visibility[visible]]
    result = visibility.reshape(shape)
    return result
948697
private void interiorLineInteriorLine_(int half_edge, int id_a, int id_b,
			int cluster_index_a, int cluster_index_b) {
		if (m_matrix[MatrixPredicate.InteriorInterior] == 1)
			return;

		int parentage = m_topo_graph.getHalfEdgeParentage(half_edge);

		if ((parentage & id_a) != 0 && (parentage & id_b) != 0) {
			m_matrix[MatrixPredicate.InteriorInterior] = 1;
			return;
		}

		if (m_matrix[MatrixPredicate.InteriorInterior] != 0) {
			if (m_topo_graph.getHalfEdgeUserIndex(m_topo_graph
					.getHalfEdgePrev(m_topo_graph.getHalfEdgeTwin(half_edge)),
					m_visited_index) != 1) {
				int cluster = m_topo_graph.getHalfEdgeTo(half_edge);
				int clusterParentage = m_topo_graph
						.getClusterParentage(cluster);

				if ((clusterParentage & id_a) != 0
						&& (clusterParentage & id_b) != 0) {
					int index_a = m_topo_graph.getClusterUserIndex(cluster,
							cluster_index_a);
					int index_b = m_topo_graph.getClusterUserIndex(cluster,
							cluster_index_b);
					assert (index_a != -1);
					assert (index_b != -1);

					if ((index_a % 2 == 0) && (index_b % 2 == 0)) {
						assert ((m_topo_graph.getClusterParentage(cluster) & id_a) != 0 && (m_topo_graph
								.getClusterParentage(cluster) & id_b) != 0);
						m_matrix[MatrixPredicate.InteriorInterior] = 0;
					}
				}
			}
		}
	}
1322252
private Point2D intersect(List<Point2D> outline, Line2D line) {

        Point2D previousPoint = outline.get(outline.size() - 1);
        for (Point2D point : outline) {

            Line2D currentLine = new Line2D.Double(point.getX(), point.getY(), previousPoint.getX(),
                    previousPoint.getY());
            if (line.intersectsLine(currentLine)) {
                return lineLineIntersect(currentLine, line);
            }
            previousPoint = point;
        }
        return new Point2D.Double(line.getX1(), line.getY1());
    }
1271246
def contourInside(self, otherContour):
        
        otherContour = normalizers.normalizeContour(otherContour)
        return self._contourInside(otherContour)
1013558
def _inner(self, x1, x2):
        """"""
        return self.tspace._inner(x1.tensor, x2.tensor)
1362758
def rn_boundary(af, b_hi):
    
    return np.sqrt( rn_theory(af, b)*rn_theory(af, b-1) )
102118
def inner(tensor0: BKTensor, tensor1: BKTensor) -> BKTensor:
    """"""
    # Note: Relying on fact that vdot flattens arrays
    return np.vdot(tensor0, tensor1)
6753
private void interiorLineInteriorPoint_(int cluster, int id_a, int id_b,
			int cluster_index_a) {
		if (m_matrix[MatrixPredicate.InteriorInterior] == 0)
			return;

		int clusterParentage = m_topo_graph.getClusterParentage(cluster);

		if ((clusterParentage & id_a) != 0 && (clusterParentage & id_b) != 0) {
			int index = m_topo_graph.getClusterUserIndex(cluster,
					cluster_index_a);

			if (index % 2 == 0) {
				m_matrix[MatrixPredicate.InteriorInterior] = 0;
			}
		}
	}
383364
def _blank_within(self, perimeter):
        
        # Method:
        # scan around the perimeter filling 'up' from each pixel
        # stopping when we reach the other boundary
        for p in perimeter:
            # if we are on the edge of the data then there is nothing to fill
            if p[0] >= self.data.shape[0] or p[1] >= self.data.shape[1]:
                continue
            # if this pixel is blank then don't fill
            if self.data[p] == 0:
                continue

            # blank this pixel
            self.data[p] = 0

            # blank until we reach the other perimeter
            for i in range(p[1]+1, self.data.shape[1]):
                q = p[0], i
                # stop when we reach another part of the perimeter
                if q in perimeter:
                    break
                # fill everything in between, even inclusions
                self.data[q] = 0

        return
575058
def irregular_contour(x, y, z, func=plt.contourf, func_kwargs=dict(),
                      grid_size=(100,100), padding_fraction=0.05,
                      interp_method='nearest'):
  '''
  '''
  from scipy.interpolate import griddata  # Late import; scipy is optional
  x, y, z = map(np.asanyarray, (x, y, z))
  x_range = (x.min(), x.max())
  y_range = (y.min(), y.max())
  pad_x = padding_fraction * -np.subtract.reduce(x_range)
  pad_y = padding_fraction * -np.subtract.reduce(y_range)
  grid_x = np.linspace(x_range[0] - pad_x, x_range[1] + pad_x, grid_size[0])
  grid_y = np.linspace(y_range[0] - pad_y, y_range[1] + pad_y, grid_size[1])
  grid_z = griddata((x, y), z, (grid_x[None], grid_y[:,None]),
                    method=interp_method)
  return func(grid_x, grid_y, grid_z, **func_kwargs)
647727
public static void hessianBorder(GrayF32 integral, int skip , int size ,
									 GrayF32 intensity)
	{
		final int w = intensity.width;
		final int h = intensity.height;

		// get convolution kernels for the second order derivatives
		IntegralKernel kerXX = DerivativeIntegralImage.kernelDerivXX(size,null);
		IntegralKernel kerYY = DerivativeIntegralImage.kernelDerivYY(size,null);
		IntegralKernel kerXY = DerivativeIntegralImage.kernelDerivXY(size,null);

		int radiusFeature = size/2;
		final int borderOrig = radiusFeature+ 1 + (skip-(radiusFeature+1)%skip);
		final int border = borderOrig/skip;

		float norm = 1.0f/(size*size);

		BoofConcurrency.loopFor(0, h, y -> {
			int yy = y * skip;
			for (int x = 0; x < border; x++) {
				int xx = x * skip;
				computeHessian(integral, intensity, kerXX, kerYY, kerXY, norm, y, yy, x, xx);
			}
			for (int x = w - border; x < w; x++) {
				int xx = x * skip;
				computeHessian(integral, intensity, kerXX, kerYY, kerXY, norm, y, yy, x, xx);
			}
		});

		BoofConcurrency.loopFor(border, w-border, x -> {
			int xx = x*skip;

			for( int y = 0; y < border; y++ ) {
				int yy = y*skip;
				computeHessian(integral, intensity, kerXX, kerYY, kerXY, norm, y, yy, x, xx);
			}
			for( int y = h-border; y < h; y++ ) {
				int yy = y*skip;
				computeHessian(integral, intensity, kerXX, kerYY, kerXY, norm, y, yy, x, xx);
			}
		});
	}
913014
def segment_area(seg):
    '''
    '''
    r0 = seg[0][COLS.R]
    r1 = seg[1][COLS.R]
    h2 = point_dist2(seg[0], seg[1])
    return math.pi * (r0 + r1) * math.sqrt((r0 - r1) ** 2 + h2)
479620
def inner(tensor0: BKTensor, tensor1: BKTensor) -> BKTensor:
    """"""
    # Note: Relying on fact that vdot flattens arrays
    N = rank(tensor0)
    axes = list(range(N))
    return tf.tensordot(tf.math.conj(tensor0), tensor1, axes=(axes, axes))
162886
def _draw_contour(self, img):
        """"""
        if self.mask is None or self.contour_width == 0:
            return img

        mask = self._get_bolean_mask(self.mask) * 255
        contour = Image.fromarray(mask.astype(np.uint8))
        contour = contour.resize(img.size)
        contour = contour.filter(ImageFilter.FIND_EDGES)
        contour = np.array(contour)

        # make sure borders are not drawn before changing width
        contour[[0, -1], :] = 0
        contour[:, [0, -1]] = 0

        # use gaussian to change width, divide by 10 to give more resolution
        radius = self.contour_width / 10
        contour = Image.fromarray(contour)
        contour = contour.filter(ImageFilter.GaussianBlur(radius=radius))
        contour = np.array(contour) > 0
        contour = np.dstack((contour, contour, contour))

        # color the contour
        ret = np.array(img) * np.invert(contour)
        if self.contour_color != 'black':
            color = Image.new(img.mode, img.size, self.contour_color)
            ret += np.array(color) * contour

        return Image.fromarray(ret)