Esempio n. 1
0
    def extractFromBinary(self,
                          binaryImg,
                          colorImg,
                          minsize=5,
                          maxsize=-1,
                          appx_level=3):
        """
        This method performs blob extraction given a binary source image that is used
        to get the blob images, and a color source image.
        binarymg- The binary image with the blobs.
        colorImg - The color image.
        minSize  - The minimum size of the blobs in pixels.
        maxSize  - The maximum blob size in pixels.
        * *appx_level* - The blob approximation level - an integer for the maximum distance between the true edge and the approximation edge - lower numbers yield better approximation.
        """
        #If you hit this recursion limit may god have mercy on your soul.
        #If you really are having problems set the value higher, but this means
        # you have over 10,000,000 blobs in your image.
        sys.setrecursionlimit(5000)
        #h_next moves to the next external contour
        #v_next() moves to the next internal contour
        if (maxsize <= 0):
            maxsize = colorImg.width * colorImg.height
        #binaryImg.show()
        retVal = []
        test = binaryImg.meanColor()
        if (test[0] == 0.00 and test[1] == 0.00 and test[2] == 0.00):
            return FeatureSet(retVal)

        # There are a couple of weird corner cases with the opencv
        # connect components libraries - when you try to find contours
        # in an all black image, or an image with a single white pixel
        # that sits on the edge of an image the whole thing explodes
        # this check catches those bugs. -KAS
        # Also I am submitting a bug report to Willow Garage - please bare with us.
        ptest = (4 * 255.0) / (binaryImg.width * binaryImg.height
                               )  # val if two pixels are white
        if (test[0] <= ptest and test[1] <= ptest and test[2] <= ptest):
            return retVal
        contourImage = binaryImg.toGray().getGrayNumpy()
        #print contourImage.shape, contourImage.dtype
        contours, hierarchy = cv2.findContours(contourImage, cv2.RETR_CCOMP,
                                               cv2.CHAIN_APPROX_SIMPLE)
        self.contours = copy(contours)
        self.hierarchy = copy(hierarchy)
        if not contours:
            warnings.warn("Unable to find Blobs. Retuning Empty FeatureSet.")
            return FeatureSet([])
        try:
            # note to self
            # http://code.activestate.com/recipes/474088-tail-call-optimization-decorator/
            retVal = self._extractFromBinary(contours, hierarchy, colorImg,
                                             minsize, maxsize, appx_level)
        except RuntimeError, e:
            logger.warning(
                "You exceeded the recursion limit. This means you probably have too many blobs in your image. We suggest you do some morphological operations (erode/dilate) to reduce the number of blobs in your image. This function was designed to max out at about 5000 blobs per image."
            )
Esempio n. 2
0
    def extractFromBinary(self, binaryImg, colorImg, minsize=5, maxsize=-1, appx_level=3):
        """
        This method performs blob extraction given a binary source image that is used
        to get the blob images, and a color source image.
        binarymg- The binary image with the blobs.
        colorImg - The color image.
        minSize  - The minimum size of the blobs in pixels.
        maxSize  - The maximum blob size in pixels.
        * *appx_level* - The blob approximation level - an integer for the maximum distance between the true edge and the approximation edge - lower numbers yield better approximation.
        """
        # If you hit this recursion limit may god have mercy on your soul.
        # If you really are having problems set the value higher, but this means
        # you have over 10,000,000 blobs in your image.
        sys.setrecursionlimit(5000)
        # h_next moves to the next external contour
        # v_next() moves to the next internal contour
        if maxsize <= 0:
            maxsize = colorImg.width * colorImg.height
        # binaryImg.show()
        retVal = []
        test = binaryImg.meanColor()
        if test[0] == 0.00 and test[1] == 0.00 and test[2] == 0.00:
            return FeatureSet(retVal)

        # There are a couple of weird corner cases with the opencv
        # connect components libraries - when you try to find contours
        # in an all black image, or an image with a single white pixel
        # that sits on the edge of an image the whole thing explodes
        # this check catches those bugs. -KAS
        # Also I am submitting a bug report to Willow Garage - please bare with us.
        ptest = (4 * 255.0) / (binaryImg.width * binaryImg.height)  # val if two pixels are white
        if test[0] <= ptest and test[1] <= ptest and test[2] <= ptest:
            return retVal
        contourImage = binaryImg.toGray().getGrayNumpy()
        # print contourImage.shape, contourImage.dtype
        contours, hierarchy = cv2.findContours(contourImage, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE)
        self.contours = copy(contours)
        self.hierarchy = copy(hierarchy)
        if not contours:
            warnings.warn("Unable to find Blobs. Retuning Empty FeatureSet.")
            return FeatureSet([])
        try:
            # note to self
            # http://code.activestate.com/recipes/474088-tail-call-optimization-decorator/
            retVal = self._extractFromBinary(contours, hierarchy, colorImg, minsize, maxsize, appx_level)
        except RuntimeError, e:
            logger.warning(
                "You exceeded the recursion limit. This means you probably have too many blobs in your image. We suggest you do some morphological operations (erode/dilate) to reduce the number of blobs in your image. This function was designed to max out at about 5000 blobs per image."
            )
Esempio n. 3
0
    def colorWithClusterMeans(self):
        """
        **SUMMARY**

        This function colors each superpixel with its mean color and
        return an image.

        **RETURNS**
        Image with superpixles drawn in its mean color.

        **EXAMPLE**
        >>> image = Image("lenna")
        >>> sp = image.segmentSuperpixels(300, 20)
        >>> sp.colorWithClusterMeans().show()
        """
        if type(self.clusterMeanImage) != type(None):
            return self.clusterMeanImage
        self.clusterMeanImage = Image(self.image.getEmpty(3))
        _mLayers = []
        for sp in self:
            color = tuple(reversed(sp.meanColor()))
            sp.draw(color=color, width=-1)
            self.clusterMeanImage += sp.image.copy()
            for layer in sp.image._mLayers:
                _mLayers.append(layer)
        self.clusterMeanImage._mLayers = copy(_mLayers)
        return self.clusterMeanImage
Esempio n. 4
0
    def draw(self, color=Color.RED, width=2, alpha=255):
        """
        **SUMMARY**

        Draw all the superpixels, in the given color, to the appropriate layer

        By default, this draws the superpixels boundary. If you
        provide a width, an outline of the exterior and interior contours is drawn.

        **PARAMETERS**

        * *color* -The color to render the blob as a color tuple.
        * *width* - The width of the drawn blob in pixels, if -1 then filled then the polygon is filled.
        * *alpha* - The alpha value of the rendered blob 0=transparent 255=opaque.
        
        **RETURNS**

        Image with superpixels drawn on it.

        **EXAMPLE**

        >>> image = Image("lenna")
        >>> sp = image.segmentSuperpixels(300, 20)
        >>> sp.draw(color=(255, 0, 255), width=5, alpha=128).show()
        """
        img = self.image.copy()
        self._drawingImage = Image(self.image.getEmpty(3))
        _mLayers = []
        for sp in self:
            sp.draw(color=color, width=width, alpha=alpha)
            self._drawingImage += sp.image.copy()
            for layer in sp.image._mLayers:
                _mLayers.append(layer)
        self._drawingImage._mLayers = copy(_mLayers)
        return self._drawingImage.copy()