def loadImage(self, image): '''This function should open the image contained in the specified file and reset the class' variables''' # Reset variables self.msFilter = None self.msSegment = None # Load image self.original = PyImage() self.original.loadImage(image)
def loadImage(self, image): '''This function should initialize the class by loading an image from the function call. It then places that image at the pyramid's lowest level, and specifies no pixels were lost in this process.''' # Reset pyramid and loss info if self.pyramid: self.pyramid = [] self.info_loss = [] # Create image, append things img = PyImage() img.loadImage(image) self.pyramid.append(img) self.info_loss.append((False, False))
def __init__(self, filename, block_size=11, min_component_size=11, majority=0.56): ''' Constructor - keeps input image filename, image read from the file as a PyImage object, block size (in pixels), threshold to decide how many skin color pixels are required to declare a block as a skin-block and min number of blocks required for a component. The majority argument says what fraction of the block pixels must be skin/hair colored for the block to be a skin/hair block - the default value is 0.5 (half). ''' self.image = PyImage(filename) self.block_sz = block_size self.min_blocks = min_component_size self.fraction_pixel = majority
def loadFile(self, filepath, nFrames, pyramid=0): '''This function should load frames of a video with a regular file expression to read filenames. The number of frames is known beforehand to ease computing.''' # Update variables based on input self.pyramid = pyramid self.nFrames = nFrames self.filepath = filepath # Separate name from extension path = filepath.split('.') extension = '.' + path[-1] path = "".join(path[:-1]) + '-' # For each frame that will be processed, we will load a single file for i in np.arange(1, nFrames + 1): print "DEBUG: Loading frame", i # Load each frame frame = PyImage() frame.loadFile(path + str(i) + extension) frame.img = frame.img.convert("RGB") frame.updatePixels() # Compute its grayscale counterpart grayscaleFrame = frame.copy() grayscaleFrame.img = grayscaleFrame.img.convert("L") grayscaleFrame.updatePixels() # Append frames to lists self.frames.append(frame) self.grayscaleFrames.append(grayscaleFrame) # If pyramids will be used, start a pyramid for every grayscale # frame to be used later on if pyramid: print "DEBUG: Computing pyramids for frame", i framePyramid = GaussPyramid(pyramid) framePyramid.loadImage(grayscaleFrame.img) framePyramid.reduceMax() self.pyramids.append(framePyramid)
def meanshiftSegment(self, hr, filepath=None): '''This function should perform a segmentation in an image based on each pixel's color. It groups together neighbor pixels that have similar colors. By default, it uses the filtered image in the class instance, but it can load a file specified as a argument.''' # Check where to load image from, default is class instance if self.msFilter is None: # Check if filepath is specified if filepath is None: # Neither sources are valid, abort print "\nERROR: Please either " + \ "specify a file or run meanshiftFilter.\n" return else: # Load image from filepath img = PyImage() img.loadFile(filepath) else: # Load image from class img = self.msFilter.copy() # Start group matrix with zeros groups = np.zeros((img.height, img.width), dtype="int32") groups -= 1 pixels = [] # List of pixels per group colors = [] # Average color per group lastGroup = 0 # Iterate pixels, assigning group to each pixel for j in np.arange(img.height): for i in np.arange(img.width): # If pixel has no group, set a new group for it if groups[j][i] == -1: groups[j][i] = lastGroup lastGroup += 1 pixels.append([(j, i)]) colors.append(img.pixels[j][i].astype("float64")) # Get pixel neighbors neighbors = [] if j: neighbors.append((j - 1, i, img.pixels[j - 1][i])) if i: neighbors.append( (j - 1, i - 1, img.pixels[j - 1][i - 1])) if i < img.width - 1: neighbors.append( (j - 1, i + 1, img.pixels[j - 1][i + 1])) if j < img.height - 1: neighbors.append((j + 1, i, img.pixels[j + 1][i])) if i: neighbors.append( (j + 1, i - 1, img.pixels[j + 1][i - 1])) if i < img.width - 1: neighbors.append( (j + 1, i + 1, img.pixels[j + 1][i + 1])) if i: neighbors.append((j, i - 1, img.pixels[j][i - 1])) if i < img.width - 1: neighbors.append((j, i + 1, img.pixels[j][i + 1])) # For each neighbor, check if color is similar group = groups[j][i] for neighbor in neighbors: # Compute color difference cDiff = colors[group] - neighbor[2] cDiff = sum(cDiff**2) cDiff **= 0.5 if cDiff < hr: # Color is similar in all 3 channels, put neighbor as # same group as current pixel groups[neighbor[0]][neighbor[1]] = group oldGroupLen = len(pixels[group]) pixels[group].append((neighbor[0], neighbor[1])) color = colors[group] color *= oldGroupLen color += neighbor[2] color /= oldGroupLen + 1 colors[group] = color print lastGroup # Iterate groups for g in range(lastGroup): # Iterate pixels, updating their colors color = colors[g].astype("uint8") for pixel in pixels[g]: img.pixels[pixel[0]][pixel[1]] = color # Store result self.msSegment = img