def countRegions(): # Requires: -the first command line argument is the name of the # image to be segmented # -the second command line argument is the color space being # used, either RGB, HSV, or HLS # Effects: -calls closure with count foreground argument on, returns # count of distinct foreground objects colorSpace = argv[2].lower() if not (colorSpace in ["rgb", "hsv", "hls"]): print "Second argument not one of RGB, HSV, or HLS" print "The first argument should be the name of the image to be segmented" print "Followed by the desire color space representation" exit(1) try: image = Image.open(argv[1]) imageData = colorSpaceConvert(list(image.getdata()), argv[2].lower()) except: print "Invalid or no image name given" print "The first argument should be the name of the image to be segmented" print "Followed by the desire color space representation" exit(1) if colorSpace == "rgb": redMinMax = raw_input("Red min-max, between 0 and 255: ") greenMinMax = raw_input("Green min-max, between 0 and 255: ") blueMinMax = raw_input("Blue min-max, between 0 and 255: ") redMinMax = [float(x) / 255.0 for x in redMinMax.split()] greenMinMax = [float(x) / 255.0 for x in greenMinMax.split()] blueMinMax = [float(x) / 255.0 for x in blueMinMax.split()] colorRanges = [redMinMax, greenMinMax, blueMinMax] elif colorSpace == "hsv": hueMinMax = raw_input("Hue min-max, between 0 and 360: ") satMinMax = raw_input("Saturation min-max, between 0 and 100: ") valMinMax = raw_input("Value min-max, between 0 and 100: ") hueMinMax = [float(x) / 360.0 for x in hueMinMax.split()] satMinMax = [float(x) / 100.0 for x in satMinMax.split()] valMinMax = [float(x) / 100.0 for x in valMinMax.split()] colorRanges = [hueMinMax, satMinMax, valMinMax] else: hueMinMax = raw_input("Hue min-max, between 0 and 360: ") lightMinMax = raw_input("Lightness min-max, between 0 and 100: ") satMinMax = raw_input("Saturation min-max, between 0 and 100: ") hueMinMax = [float(x) / 360.0 for x in hueMinMax.split()] lightMinMax = [float(x) / 100.0 for x in lightMinMax.split()] satMinMax = [float(x) / 100.0 for x in satMinMax.split()] colorRanges = [hueMinMax, lightMinMax, satMinMax] param = Parameters() param.setImageSize(image.size) param.setColorRanges(colorRanges) seg = segmentation.colorSegmenter() mask = seg.segmentImage(imageData, param, True) close = closure.closure() close.segmentRegions(mask, param, 0, True, False)
def mutateParameters(self, parameters): # Requires: parameters is of type Parameters # Modifies: parameters # Effects: mutates the parameters based on segmenter used # if color based segmenter, then mutate color range if type(self.segmenter) == type(segmentation.colorSegmenter()): self.mutateColorRange(parameters.colorRanges)
def randomizeParameters(self, parameters): # Requires: parameters is of type Parameters # Modifies: parameters # Effects: randomly modifies parameters based on segmenter used # if color based segmenter, then randomize color range + flip bit if type(self.segmenter) == type(segmentation.colorSegmenter()): parameters.colorRanges = self.randColorRange() parameters.flipBit = choice([True, False])
def searchImage(self, imageData, idealMaskData, parameters, plot=False): # Requires: -image and idealMask is an RGB based image # -parameters is of type Parameters # Modifies: parameters # Effects: - Searches the parameter space using simulated annealing # to find an optimal solution, returns most optimal parameter found # -plots fitness vs. generation of search if plot set to True print "Running Anneal Search" # runs random search to find best from initial population # note, random search sets initial upper limit print "Calling random search for initial random guess" randSearch = RandomSearch.randomSearch(self.segmenter, self.fitness) parameters = randSearch.searchImage(imageData, idealMaskData, parameters) # set no upper limit (infinity) for fitness function parameters.setUpperLimit(float("inf")) # hold references to image data and ideal mask data # to conform with scipy's need for a simple fitness function (not using multiple arguments) self.imageData = imageData self.idealMaskData = idealMaskData # if color based segmenter, run anneal accordingkly if type(self.segmenter) == type(segmentation.colorSegmenter()): # make initial guess based off random search initialGuess = numpy.array(sum(parameters.colorRanges, [])) # runs scipy's anneal results = optimize.anneal(self.segmentAndFitnessColor, x0=initialGuess, args=(parameters, ), schedule='cauchy', full_output=True, dwell=50, lower=0.0, upper=1.0, disp=True, T0=.005) # prints anneal's final fitness print "Final Fitness " + str(results[1]) # for color segmenters colorRanges = results[0] colorRanges = [ colorRanges[0:2], colorRanges[2:4], colorRanges[4:6] ] parameters.setColorRanges(colorRanges) # if other kind of segmenter, add below return parameters
def searchImage(self, imageData, idealMaskData, parameters, plot = False): # Requires: -image and idealMask is an RGB based image # -parameters is of type Parameters # Modifies: parameters # Effects: - Searches the parameter space using simulated annealing # to find an optimal solution, returns most optimal parameter found # -plots fitness vs. generation of search if plot set to True print "Running Anneal Search" # runs random search to find best from initial population # note, random search sets initial upper limit print "Calling random search for initial random guess" randSearch = RandomSearch.randomSearch(self.segmenter, self.fitness) parameters = randSearch.searchImage(imageData, idealMaskData, parameters) # set no upper limit (infinity) for fitness function parameters.setUpperLimit(float("inf")) # hold references to image data and ideal mask data # to conform with scipy's need for a simple fitness function (not using multiple arguments) self.imageData = imageData self.idealMaskData = idealMaskData # if color based segmenter, run anneal accordingkly if type(self.segmenter) == type(segmentation.colorSegmenter()): # make initial guess based off random search initialGuess = numpy.array(sum(parameters.colorRanges, [])) # runs scipy's anneal results = optimize.anneal(self.segmentAndFitnessColor, x0 = initialGuess, args=(parameters,), schedule='cauchy', full_output=True, dwell=50, lower=0.0, upper=1.0, disp=True, T0 = .005) # prints anneal's final fitness print "Final Fitness " + str(results[1]) # for color segmenters colorRanges = results[0] colorRanges = [colorRanges[0:2], colorRanges[2:4], colorRanges[4:6]] parameters.setColorRanges(colorRanges) # if other kind of segmenter, add below return parameters
def main(): # commented out try for debugging purposes #try: shortOpts = "d:f:s:i:m:hepc:r:" longOpts = ["segment=", "fitness=", "search=", "image=", "mask=", "help", "export", "plot", "close=", "predict="] try: options, remainder = getopt.getopt(sys.argv[1:], shortOpts, longOpts) except: print "\nERROR: Invalid option argument\n" exit(1) export = False plot = False close = False predictImages = False # sets relevant variables based on command line input for opt, arg in options: if opt in ("-d", "--segment"): segmenterName = arg elif opt in ("-f", "--fitness"): fitnessName = arg elif opt in ("-s", "--search"): searchName = arg elif opt in ("-i", "--image"): imageName = arg elif opt in ("-m", "--mask"): idealMaskName = arg elif opt in ("-e", "--export"): export = True elif opt in ("-p", "--plot"): plot = True elif opt in ("-c", "--close"): close = True closeType = arg elif opt in ("-r", "--predict"): predictImages = True predictFolderName = arg elif opt in ("-h", "--help"): print __doc__ exit(0) else: pass # quit if extraneous input provided if remainder != []: print "\nERROR: Extraneous input\n" exit(1) # initialize segmenter algorithm if segmenterName.lower() in ("rgb", "hsv", "hls"): segmenter = segmentation.colorSegmenter() else: print "\nERROR: Invalid or no segmenter name\n" exit(1) # initialize fitness function if fitnessName.lower() == "diff": fitnessFunc = fitness.absDiffFitness() else: print "\nERROR: Invalid or no fitness name\n" exit(1) # initialize search space algorithm if searchName.lower() == "random": searchFunc = RandomSearch.randomSearch(segmenter, fitnessFunc) elif searchName.lower() == "genetic": searchFunc = GeneticSearch.geneticSearch(segmenter, fitnessFunc) elif searchName.lower() == "anneal": searchFunc = AnnealSearch.annealSearch(segmenter, fitnessFunc) else: print "\nERROR: Invalid or no search name\n" exit(1) # try to open image, and convert image data from a [0, 255] RGB space # to a [0, 1] normalized RGB, HSV, or HLS space, depending on the segmenter selected # (chooses HSV or HLS if their respective segmenter is selected, else selects RGB) # if opening image fails, quit with error try: image = Image.open(imageName) # initialize parameters object, init's image size and color space used parameter = parameters.Parameters() parameter.setImageSize(image.size) # use hsv or hls if segmenter specified, else use rgb by default if segmenterName.lower() in ("hsv", "hls"): parameter.setColorSpace(segmenterName.lower()) else: parameter.setColorSpace("rgb") imageData = colorSpaceConvert(list(image.getdata()), parameter.colorSpace) except: print "\nERROR: Invalid or no image name\n" exit(1) # try to open ideal mask, if it fails, quit with error try: mask = Image.open(idealMaskName) idealMaskData = list(mask.getdata()) except: print "\nERROR: Invalid or no mask name\n" exit(1) # run search on image parameter space for segmentation # returns optimal paramaters found upon search completion # and saves a plot of fitness vs. search extent if plot set to true optimalParameters = searchFunc.searchImage(imageData, idealMaskData, parameter, plot) # reset upper limit optimalParameters.setUpperLimit(float("inf")) # if export enabled, saves mask using optimal parameters found to output.png if (export == True): segmenter.segmentImage(imageData, optimalParameters, True) # if export enabled, saves a 'closed' mask using optimal parameters found to output.png if (close == True): whiteArg = 1 if closeType.lower() == "white" else 0 mask = segmenter.segmentImage(imageData, optimalParameters) close = closure.closure() close.segmentRegions(mask, optimalParameters, saveImage = export, clearWhite = whiteArg) if predictImages == True: predict.predict(predictFolderName, optimalParameters, segmenter, fitnessFunc, plot = True, exportImages = export)