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." )
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." )
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
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()