Ejemplo n.º 1
0
    def editBorder(self, blob, lines):
        points = [blob.drawLine(line) for line in lines]

        if points is None or len(points) == 0:
            return

        # compute the box for the outer contour
        intersected = False
        (mask, box,
         intersected) = self.editBorderContour(blob, blob.contour, points)

        pointIntersectsContours = intersected
        for contour in blob.inner_contours:
            (inner_mask, inner_box,
             intersected) = self.editBorderContour(blob, contour, points)
            pointIntersectsContours = pointIntersectsContours or intersected
            Mask.paintMask(mask, box, inner_mask, inner_box, 0)

        if not pointIntersectsContours:
            #probably a hole, draw the points fill the hole and subtract from mask
            allpoints = np.empty(shape=(0, 2), dtype=int)
            for arc in points:
                allpoints = np.append(allpoints, arc, axis=0)
            points_box = Mask.pointsBox(allpoints, 4)
            (points_mask, points_box) = Mask.jointMask(points_box, points_box)
            Mask.paintPoints(points_mask, points_box, allpoints, 1)
            origin = np.array([points_box[1], points_box[0]])
            Mask.paintPoints(points_mask, points_box, allpoints - origin, 1)
            points_mask = ndi.binary_fill_holes(points_mask)
            points_mask = binary_erosion(points_mask)
            Mask.paintMask(mask, box, points_mask, points_box, 0)

        blob.updateUsingMask(box, mask)
Ejemplo n.º 2
0
    def editBorderContour(self, blob, contour, points):
        snapped_points = np.empty(shape=(0, 2), dtype=int)
        for arc in points:
            snapped = blob.snapToContour(arc, contour)
            if snapped is not None:
                snapped_points = np.append(snapped_points, snapped, axis=0)

        contour_box = Mask.pointsBox(contour, 4)

        #if the countour did not intersect with the outer contour, get the mask of the outer contour
        if snapped_points is None or len(snapped_points) == 0:
            # not very elegant repeated code...
            (mask, box) = Mask.jointMask(contour_box, contour_box)
            origin = np.array([box[1], box[0]])
            contour_points = contour.round().astype(int)
            fillPoly(mask, pts=[contour_points - origin], color=(1))
            return (mask, box, False)

        points_box = Mask.pointsBox(snapped_points, 4)

        # create a mask large enough to accomodate the points and the contour and paint.
        (mask, box) = Mask.jointMask(contour_box, points_box)

        origin = np.array([box[1], box[0]])
        contour_points = contour.round().astype(int)
        fillPoly(mask, pts=[contour_points - origin], color=(1, 1, 1))

        Mask.paintPoints(mask, box, snapped_points, 1)

        mask = ndi.binary_fill_holes(mask)

        # now draw in black the part of the points inside the contour
        Mask.paintPoints(mask, box, snapped_points, 0)

        # now we label all the parts and keep the larges only
        regions = measure.regionprops(measure.label(mask, connectivity=1))

        largest = max(regions, key=lambda region: region.area)

        # adjust the image bounding box (relative to the region mask) to directly use area.image mask
        box = np.array([
            box[0] + largest.bbox[0], box[1] + largest.bbox[1],
            largest.bbox[3] - largest.bbox[1],
            largest.bbox[2] - largest.bbox[0]
        ])
        return (largest.image, box, True)
Ejemplo n.º 3
0
    def editBorder(self, blob, lines):
        #need padding

        #would be lovely to be able do edit holes too.
        #the main problem is snapping to the external contour

        points = blob.lineToPoints(lines, snap=True)

        if points is None:
            return

        if len(points) == 0:
            return

        pointsbox = Mask.pointsBox(points, 3)
        blobmask = blob.getMask()

        #add to mask painting the points as 1 and filling the holes.
        (mask, box) = Mask.jointMask(blob.bbox, pointsbox)
        Mask.paintMask(mask, box, blobmask, blob.bbox, 1)

        #save holes
        full = ndi.binary_fill_holes(mask.astype(int))
        holes = full & ~mask

        #cut from mask
        Mask.paintPoints(mask, box, points, 1)
        mask = ndi.binary_fill_holes(mask.astype(int))

        #erase the points to carve to remove the internal parts.
        Mask.paintPoints(mask, box, points, 0)

        #add back holes
        mask = mask & ~holes

        regions = measure.regionprops(measure.label(mask))

        if len(regions):
            largest = regions[0]
            for region in regions:
                if region.area > largest.area:
                    largest = region

            #adjust the image bounding box (relative to the region mask) to directly use area.image mask
            #image box is standard (minx, miny, maxx, maxy)
            box = np.array([
                box[0] + largest.bbox[0], box[1] + largest.bbox[1],
                largest.bbox[3], largest.bbox[2]
            ])

            blob.updateUsingMask(box, largest.image.astype(int))
Ejemplo n.º 4
0
    def addingIntersection(self, blobA, blobB, blobC):
        """
        Update the blobA by adding to it the intersection between the blobB and the blobC
        """
        mask_intersect, bbox_intersect = Mask.intersectMask(
            blobB.getMask(), blobB.bbox, blobC.getMask(), blobC.bbox)

        bbox = Mask.jointBox([blobA.bbox, bbox_intersect])
        (mask, bbox) = Mask.jointMask(bbox, bbox)

        Mask.paintMask(mask, bbox, blobA.getMask(), blobA.bbox, 1)
        Mask.paintMask(mask, bbox, mask_intersect, bbox_intersect, 1)

        if mask.any():
            blobA.updateUsingMask(bbox, mask.astype(int))
Ejemplo n.º 5
0
    def createFromClosedCurve(self, lines):
        """
        It creates a blob starting from a closed curve. If the curve is not closed False is returned.
        If the curve intersect itself many times the first segmented region is created.
        """
        points = self.lineToPoints(lines)
        box = Mask.pointsBox(points, 4)

        (mask, box) = Mask.jointMask(box, box)
        Mask.paintPoints(mask, box, points, 1)
        mask = ndi.binary_fill_holes(mask)

        mask = binary_erosion(mask)
        mask = binary_dilation(mask)
        self.updateUsingMask(box, mask)
        return True
Ejemplo n.º 6
0
    def union(self, blobs):
        """
        Create a new blob that is the union of the (two) blobs given
        """
        #boxs are in image space, masks invert x and y.
        boxes = []
        for blob in blobs:
            boxes.append(blob.bbox)
        box = Mask.jointBox(boxes)
        (mask, box) = Mask.jointMask(box, box)

        for blob in blobs:
            Mask.paintMask(mask, box, blob.getMask(), blob.bbox, 1)

        if mask.any():
            # measure is brutally slower with non int types (factor 4), while byte&bool would be faster by 25%, conversion is fast.
            blob = blobs[0].copy()
            blob.updateUsingMask(box, mask.astype(int))
            return blob
        return None
Ejemplo n.º 7
0
    def createFromClosedCurve(self, lines):
        """
        It creates a blob starting from a closed curve. If the curve is not closed False is returned.
        If the curve intersect itself many times the first segmented region is created.
        """
        points = self.lineToPoints(lines)
        box = Mask.pointsBox(points, 4)

        (mask, box) = Mask.jointMask(box, box)
        Mask.paintPoints(mask, box, points, 1)
        before = np.count_nonzero(mask)
        mask = ndi.binary_fill_holes(mask)
        after = np.count_nonzero(mask)

        if before == after:
            return False

        selem = np.array([[0, 0, 0], [0, 0, 1], [0, 1, 0]])
        mask = binary_erosion(mask, selem)
        self.updateUsingMask(box, mask)
        return True