Esempio n. 1
0
    def segmentImage(self, imageData, parameters, saveMaskImage=False):
        # Requires: -imageData holds 0-1 values of color values (either RGB, HSV, or HLS)
        #           -parameters is three 2-tuple numbers between 0 - 1 that
        #            respectively represent (min, max) color ranges for foreground selection
        # Effects:  returns an RGB mask-list where
        #           (0, 0, 0) is background, (255, 255, 255) is foreground
        if parameters.colorRanges == None:
            print "No color range set!"
            exit(1)

        colorRanges = parameters.colorRanges

        # check for bounds errors
        for tuples in colorRanges:
            if tuples[0] > tuples[1]:
                print "Min > Max in parameter!"
                exit(1)

            for number in tuples:
                if not (0 <= number <= 1):
                    print "Parameter not within 0 - 1 range!"
                    exit(1)

        # xRange either R or H
        # yRange either G or S
        # zRange either B or V or L
        xRange = colorRanges[0]
        yRange = colorRanges[1]
        zRange = colorRanges[2]

        isForeground = lambda x: (
            xRange[0] <= x[0] <= xRange[1] and yRange[0] <= x[1] <= yRange[1] and zRange[0] <= x[2] <= zRange[1]
        )

        # if flip bit off, act normally,
        # else switch background and foreground
        if parameters.flipBit == False:
            foreground = (255, 255, 255)
            background = (0, 0, 0)
        else:
            foreground = (0, 0, 0)
            background = (255, 255, 255)

        mask = [background] * len(imageData)

        # mark foreground if in color range
        for i in range(len(imageData)):
            if isForeground(imageData[i]):
                mask[i] = foreground

        # save image if set true
        if saveMaskImage == True:
            dataToImage(mask, parameters.imageSize)

        return mask
Esempio n. 2
0
    def segmentRegions(self, maskData, parameters, clearWhite = 0, countWhite = False, saveImage = False):
        # Requires : -maskData is a (0, 0, 0) / (255, 255, 255)
        #             black / white rgb based list data set 
        #            -parameters is of type Parameters
        #            -clearWhite is an integer, either 0 or 1
        #            -countWhite and saveImage is a bool
        # Effects : -segments a black / white image into distinct
        #            black / white regions and attempts to fill
        #            smaller black regions for increased fit
        #           -if clearWhite set to 1, segmentRegions
        #            will remove any white that is
        #            not connected to the largest sized foreground object
        #           -if countWhite set to True, returns the count of
        #            distinct white / foreground regions bigger than 200 pixels
        #           -if saveImage set to False, segmentRegions does not
        #            save image of new filled image as it does by default
        
        imageSize = parameters.imageSize
        
        imageMat = imaging.dataToMatrix(maskData, imageSize)
        
        # label matrix with "black"/"white" instead of rgb values for convenience
        for row in range(imageSize[1]):
            for col in range(imageSize[0]):
                if imageMat[row][col] == (0, 0, 0):
                    imageMat[row][col] = "black"
                else:
                    imageMat[row][col] = "white"
        
        #list of distinct white / black regions with the count of pixels in each
        blackRegions = []
        whiteRegions = []
        
        blackCount = 0
        whiteCount = 0
        
        # flood fill each pixel value with 'black' or 'white', 
        # and mark them with distinct values
        for row in range(imageSize[1]):
            for col in range(imageSize[0]):
                if imageMat[row][col] == "black":
                    blackCount += 1
                    (count, border) = self.floodFill(imageMat, (col, row), blackCount, parameters)
                    blackRegions.append((count, border))
                elif imageMat[row][col] == "white":
                    whiteCount -= 1
                    (count, border) = self.floodFill(imageMat, (col, row), whiteCount, parameters)
                    whiteRegions.append((count, border))
        dataList = imaging.matrixToData(imageMat)
        

        # clear out any foreground not connected to the largest piece
        # of white foreground, executed after recursive call if clearWhite 
        # set to 1 by user
        if clearWhite == 2:
            maxWhiteMarked = (whiteRegions.index(max(whiteRegions)) + 1) * -1
            
            for i in range(len(dataList)):
                if dataList[i] == maxWhiteMarked:
                    dataList[i] = (255,) * 3
                else:
                    dataList[i] = (0,) * 3
            
        # any black that is adjacent to border is background
        # otherwise surrounded by white, foreground
        else:
            for i in range(len(dataList)):
                if dataList[i] > 0 and blackRegions[abs(dataList[i]) - 1][1] == False:
                    dataList[i] = (255,) * 3
                elif dataList[i] > 0:
                    dataList[i] = (0,) * 3
                else:
                    dataList[i] = (255,) * 3
        
        
        # count white regions
        if countWhite == True:
            totalCount = 0
            for i in range(len(whiteRegions)):
                if whiteRegions[i][0] > 200:
                    totalCount += 1
            print "Total foreground count is " + str(totalCount)
        
        # if clear white is its non default value of 0, recursively call self
        # to clear non connecting pieces
        if clearWhite == 1:
            self.segmentRegions(dataList, parameters, clearWhite = 2, saveImage = True)
        
        # export image if saveImage true 
        # and clearWhite is either 0 or 2
        if saveImage == True and clearWhite != 1:
            imaging.dataToImage(dataList, parameters.imageSize)
Esempio n. 3
0
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")
Esempio n. 4
0
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")
Esempio n. 5
0
    def segmentRegions(self,
                       maskData,
                       parameters,
                       clearWhite=0,
                       countWhite=False,
                       saveImage=False):
        # Requires : -maskData is a (0, 0, 0) / (255, 255, 255)
        #             black / white rgb based list data set
        #            -parameters is of type Parameters
        #            -clearWhite is an integer, either 0 or 1
        #            -countWhite and saveImage is a bool
        # Effects : -segments a black / white image into distinct
        #            black / white regions and attempts to fill
        #            smaller black regions for increased fit
        #           -if clearWhite set to 1, segmentRegions
        #            will remove any white that is
        #            not connected to the largest sized foreground object
        #           -if countWhite set to True, returns the count of
        #            distinct white / foreground regions bigger than 200 pixels
        #           -if saveImage set to False, segmentRegions does not
        #            save image of new filled image as it does by default

        imageSize = parameters.imageSize

        imageMat = imaging.dataToMatrix(maskData, imageSize)

        # label matrix with "black"/"white" instead of rgb values for convenience
        for row in range(imageSize[1]):
            for col in range(imageSize[0]):
                if imageMat[row][col] == (0, 0, 0):
                    imageMat[row][col] = "black"
                else:
                    imageMat[row][col] = "white"

        #list of distinct white / black regions with the count of pixels in each
        blackRegions = []
        whiteRegions = []

        blackCount = 0
        whiteCount = 0

        # flood fill each pixel value with 'black' or 'white',
        # and mark them with distinct values
        for row in range(imageSize[1]):
            for col in range(imageSize[0]):
                if imageMat[row][col] == "black":
                    blackCount += 1
                    (count, border) = self.floodFill(imageMat, (col, row),
                                                     blackCount, parameters)
                    blackRegions.append((count, border))
                elif imageMat[row][col] == "white":
                    whiteCount -= 1
                    (count, border) = self.floodFill(imageMat, (col, row),
                                                     whiteCount, parameters)
                    whiteRegions.append((count, border))
        dataList = imaging.matrixToData(imageMat)

        # clear out any foreground not connected to the largest piece
        # of white foreground, executed after recursive call if clearWhite
        # set to 1 by user
        if clearWhite == 2:
            maxWhiteMarked = (whiteRegions.index(max(whiteRegions)) + 1) * -1

            for i in range(len(dataList)):
                if dataList[i] == maxWhiteMarked:
                    dataList[i] = (255, ) * 3
                else:
                    dataList[i] = (0, ) * 3

        # any black that is adjacent to border is background
        # otherwise surrounded by white, foreground
        else:
            for i in range(len(dataList)):
                if dataList[i] > 0 and blackRegions[abs(dataList[i]) -
                                                    1][1] == False:
                    dataList[i] = (255, ) * 3
                elif dataList[i] > 0:
                    dataList[i] = (0, ) * 3
                else:
                    dataList[i] = (255, ) * 3

        # count white regions
        if countWhite == True:
            totalCount = 0
            for i in range(len(whiteRegions)):
                if whiteRegions[i][0] > 200:
                    totalCount += 1
            print "Total foreground count is " + str(totalCount)

        # if clear white is its non default value of 0, recursively call self
        # to clear non connecting pieces
        if clearWhite == 1:
            self.segmentRegions(dataList,
                                parameters,
                                clearWhite=2,
                                saveImage=True)

        # export image if saveImage true
        # and clearWhite is either 0 or 2
        if saveImage == True and clearWhite != 1:
            imaging.dataToImage(dataList, parameters.imageSize)