Exemple #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)
Exemple #2
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))
Exemple #3
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
Exemple #4
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)
Exemple #5
0
    def cut(self, blob, lines):
        """
        Given a curve specified as a set of points and a selected blob, the operation cuts it in several separed new blobs
        """
        points = blob.lineToPoints(lines, snap=False)

        mask = blob.getMask()
        original = mask.copy()
        box = blob.bbox
        #box is y, x, w, h
        Mask.paintPoints(mask, box, points, 0)

        label_image = measure.label(mask, connectivity=1)
        for point in points:
            x = point[0] - box[1]
            y = point[1] - box[0]

            if x <= 0 or y <= 0 or x >= box[2] - 1 or y >= box[3] - 1:
                continue

            if original[y][x] == 0:
                continue
            largest = 0
            largest = max(label_image[y + 1][x], largest)
            largest = max(label_image[y - 1][x], largest)
            largest = max(label_image[y][x + 1], largest)
            largest = max(label_image[y][x - 1], largest)
            label_image[y][x] = largest

        area_th = 30
        created_blobs = []
        first = True
        for region in measure.regionprops(label_image):

            if region.area > area_th:
                b = Blob(region, box[1], box[0], self.progressive_id)
                self.progressive_id += 1
                b.class_color = blob.class_color
                b.class_name = blob.class_name
                created_blobs.append(b)

        return created_blobs
Exemple #6
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
Exemple #7
0
    def cut(self, blob, lines):
        """
        Given a curve specified as a set of points and a selected blob, the operation cuts it in several separed new blobs
        """
        points = blob.lineToPoints(lines)

        mask = blob.getMask()
        box = blob.bbox
        Mask.paintPoints(mask, box, points, 0)

        label_image = measure.label(mask)
        area_th = 30
        created_blobs = []
        for region in measure.regionprops(label_image):

            if region.area > area_th:
                id = len(self.seg_blobs)
                b = Blob(region, box[1], box[0], id + 1)
                b.class_color = blob.class_color
                b.class_name = blob.class_name
                created_blobs.append(b)

        return created_blobs