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 predict(folderName, parameters, segmentAlgo, fitnessFunc, plot=False, exportImages=False): # Requires: -parameters is of type Parameters # -segmentAlgo is of type Segment # -fitnessFunc is of type Fitness # -folder is a string of a folder which contains two subfolders: # -original which contains the original image # -manualsegmentations which contains segmentations # of the original images, the segmentations have the same # name and are of .png format # -plot and export is of type Bool # Effects: -attempts to segment images inside of the speicied folder # based on the single sample image / mask provided to the system # -outputs a histogram plot, "plot-date-time.png", of the fitness # distrubution of the images segmented if plot = True # -saves masks of the segmented images if export = True file_list = glob.glob(folderName + "original/" + "*") prefixLen = len(folderName) + len("original/") suffixLen = len(file_list[0].split(".")[-1]) + 1 fitnessList = [] iteration = 1 for fileName in file_list: image = Image.open(fileName) if parameters.colorSpace in ("hsv", "hls"): imageData = colorSpaceConvert(list(image.getdata()), parameters.colorSpace) else: imageData = colorSpaceConvert(list(image.getdata()), parameters.colorSpace) maskname = fileName[prefixLen:-suffixLen] + ".png" mask = Image.open(folderName + "manualsegmentations/" + maskname) idealMaskData = list(mask.getdata()) parameters.setImageSize(image.size) maskData = segmentAlgo.segmentImage(imageData, parameters, True) fit = fitnessFunc.findFitness(maskData, idealMaskData, parameters) # save mask if export enabled if exportImages == True: dataToImage(maskData, image.size, "-" + str(iteration)) fitnessList.append(fit / float(image.size[0] * image.size[1])) iteration += 1 time = datetime.datetime.now() npFitnessList = numpy.array(fitnessList) mu = npFitnessList.mean() median = numpy.median(npFitnessList) sigma = npFitnessList.std() textstr = '$\overline{x}=%.2f$\n$\mathrm{median}=%.2f$\n$\sigma=%.2f$' % ( mu, median, sigma) fig, ax = pylab.subplots(1) pylab.hist(fitnessList, bins=10) pylab.xlabel('Fitness ratio (Fitness / Image Size)') pylab.ylabel('Number of Images') pylab.title('Number of Images vs. Fitness Ratio') props = dict(boxstyle='round', facecolor='wheat', alpha=0.5) pylab.text(0.78, 0.95, textstr, transform=ax.transAxes, fontsize=14, verticalalignment='top', bbox=props) timeString = "output-" + str(time.month) + '.' + str(time.day) + '.' + str( time.year) timeString += '-' + str(time.hour) + '.' + str(time.minute) pylab.savefig("plotImages" + timeString + ".png")
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)
def predict(folderName, parameters, segmentAlgo, fitnessFunc, plot = False, exportImages = False): # Requires: -parameters is of type Parameters # -segmentAlgo is of type Segment # -fitnessFunc is of type Fitness # -folder is a string of a folder which contains two subfolders: # -original which contains the original image # -manualsegmentations which contains segmentations # of the original images, the segmentations have the same # name and are of .png format # -plot and export is of type Bool # Effects: -attempts to segment images inside of the speicied folder # based on the single sample image / mask provided to the system # -outputs a histogram plot, "plot-date-time.png", of the fitness # distrubution of the images segmented if plot = True # -saves masks of the segmented images if export = True file_list = glob.glob(folderName + "original/" + "*") prefixLen = len(folderName) + len("original/") suffixLen = len(file_list[0].split(".")[-1]) + 1 fitnessList = [] iteration = 1 for fileName in file_list: image = Image.open(fileName) if parameters.colorSpace in ("hsv", "hls"): imageData = colorSpaceConvert(list(image.getdata()), parameters.colorSpace) else: imageData = colorSpaceConvert(list(image.getdata()), parameters.colorSpace) maskname = fileName[prefixLen:-suffixLen] + ".png" mask = Image.open(folderName + "manualsegmentations/" + maskname) idealMaskData = list(mask.getdata()) parameters.setImageSize(image.size) maskData = segmentAlgo.segmentImage(imageData, parameters, True) fit = fitnessFunc.findFitness(maskData, idealMaskData, parameters) # save mask if export enabled if exportImages == True: dataToImage(maskData, image.size, "-" + str(iteration)) fitnessList.append(fit / float(image.size[0] * image.size[1])) iteration += 1 time = datetime.datetime.now() npFitnessList = numpy.array(fitnessList) mu = npFitnessList.mean() median = numpy.median(npFitnessList) sigma = npFitnessList.std() textstr = '$\overline{x}=%.2f$\n$\mathrm{median}=%.2f$\n$\sigma=%.2f$'%(mu, median, sigma) fig, ax = pylab.subplots(1) pylab.hist(fitnessList, bins = 10) pylab.xlabel('Fitness ratio (Fitness / Image Size)') pylab.ylabel('Number of Images') pylab.title('Number of Images vs. Fitness Ratio') props = dict(boxstyle='round', facecolor='wheat', alpha=0.5) pylab.text(0.78, 0.95, textstr, transform=ax.transAxes, fontsize=14, verticalalignment='top', bbox=props) timeString = "output-" + str(time.month) + '.' + str(time.day) + '.' + str(time.year) timeString += '-' + str(time.hour) + '.' + str(time.minute) pylab.savefig("plotImages" + timeString + ".png")