def getScoring(data, mean, weights=False):
	"""
	Create a logistic regression filter for scoring how close the tracking is to the face
	"""

	positives = []
	negatives = []
	weighting = []

	scoringmodelWidth = 20
	scoringmodelHeight = 22

	# get how large window to crop, based on meandata
	mins = numpy.amin(mean, axis=0)
	maxs = numpy.amax(mean, axis=0)
	mean_width = int(round(maxs[0]-mins[0]))
	mean_height = int(round(maxs[1]-mins[1]))
	mins = mins+numpy.array([float(mean_width/4.5) , -float(mean_height)/12])
	maxs = maxs+numpy.array([-float(mean_width/4.5) , -float(mean_height)/6])

	# load positive examples
	i = 0
	print "getting positive examples from face images"
	for filename, values in data.iteritems():
		im = Image.open(join(data_folder, "cropped/", filename), "r")

		if weights:
			if re.match(r"i\d\d\d.*", filename):
				weighting.append(True)
			else:
				weighting.append(False)

		# convert image to grayscale
		im = im.convert("L")

		imins = mins + numpy.array(im.size)/2
		imaxs = maxs + numpy.array(im.size)/2

		p_crop = im.crop(( int(round(imins[0])), int(round(imins[1])), int(round(imaxs[0])), int(round(imaxs[1])) ))

		# reduce resolution
		p_crop = p_crop.resize((scoringmodelWidth,scoringmodelHeight),Image.BILINEAR)

		# do log of images
		p_crop = numpy.log(numpy.array(p_crop, dtype=numpy.uint16)+1.0)
		#p_crop = numpy.array(p_crop)

		p_crop_img = Image.fromarray((normalize(p_crop)*255.).astype("uint8"))
		p_crop_img.save(join(data_folder, "pcropped/", filename+"_mask.bmp"))

		positives.append(p_crop.flatten())

		if i % 1000 == 0:
			print i
		i += 1

	print "getting negative examples from face images"

	# get negative examples from face images
	negfiles = [f for f in listdir(join(data_folder , "images/")) if config.valid_file("images/",f)]

	for filename in negfiles:
		if filename.endswith(".jpg") or filename.endswith(".png"):
			try:
				im = Image.open(join(data_folder, "images/", filename), "r")
				im = im.convert("L")
				ranwidth = int(round(im.size[0]*0.3))
				ranheight = int(round(im.size[1]*0.3))
				for nr in range(0,1):

					x = random.randint(0, int(round(im.size[0]-ranwidth)))
					y = random.randint(0, int(round(im.size[1]-ranheight)))
					rpoints = numpy.array([x,y])
					p_crop = im.crop((rpoints[0], rpoints[1], rpoints[0]+ranwidth, rpoints[1]+ranheight))
					# reduce resolution
					p_crop = p_crop.resize((scoringmodelWidth,scoringmodelHeight),Image.BILINEAR)
					# do log of images
					p_crop2 = numpy.log(numpy.array(p_crop, dtype=numpy.uint16)+1)
					#p_crop2 = numpy.array(p_crop)

					p_crop_img = Image.fromarray((normalize(p_crop2)*255.).astype("uint8"))
					p_crop_img.save(join(data_folder, "pcropped/", "neg_"+filename+"_mask.bmp"))

					negatives.append(p_crop2.flatten())
			except IOError:
				print "could not load invalid image file: " + join(data_folder, "images/", filename)

	print "getting negative examples from landscape images"
	# get negative examples from landscape images

	negfiles = [f for f in listdir( join(data_folder, "negatives/") ) if config.valid_file("negatives/",f)]

	if len(negfiles) == 0:
		print "you have no 'negative' images in the ./negatives/ folder"
		exit(1)

	for filename in negfiles:
		im = Image.open( join(data_folder, "negatives/", filename) , "r")
		im = im.convert("L")
		for nr in range(0,10):
			x = random.randint(0, im.size[0]-mean_width)
			y = random.randint(0, im.size[1]-mean_height)
			rpoints = numpy.array([x,y])
			p_crop = im.crop((rpoints[0], rpoints[1], rpoints[0]+mean_width, rpoints[1]+mean_height))
			# reduce resolution
			p_crop = p_crop.resize((scoringmodelWidth,scoringmodelHeight),Image.BILINEAR)
			# do log of images
			p_crop = numpy.log(numpy.array(p_crop, dtype=numpy.uint16)+1)
			#p_crop = numpy.array(p_crop)

			p_crop_img = Image.fromarray((normalize(p_crop)*255.).astype("uint8"))
			p_crop_img.save(join(data_folder, "pcropped/", "neg_"+filename+"_mask.bmp"))

			negatives.append(p_crop.flatten())

	# normalize image data
	positives = [preprocessing.scale(p) for p in positives]
	negatives = [preprocessing.scale(n) for n in negatives]

	if weights:
		# weighting
		num_positives = float(len(positives))
		num_weighted = float(sum(weighting))
		sample_weight = []
		if num_weighted > 0:
			for p in range(len(positives)):
				if weighting[p]:
					sample_weight.append(num_positives/(2*num_weighted))
				else:
					sample_weight.append(num_positives/(2*(num_positives-num_weighted)))
			for n in range(len(negatives)):
				sample_weight.append(1.)
		else:
			sample_weight = [1.0]*(len(positives)+len(negatives))
	else:
		#sample_weight = [1.0]*(len(positives)+len(negatives))
		sample_weight = [1.0]*(len(positives))
		sample_weight.extend([len(positives)/(2*float(len(negatives)))]*len(negatives))

	labels = [1.0 for p in positives]
	labels.extend([-1.0 for n in negatives])
	labels = numpy.array(labels)
	features = [p.flatten() for p in positives]
	features.extend([n.flatten() for n in negatives])
	features = numpy.vstack(features)

	#arr = numpy.arange(features.shape[0])
	#numpy.random.shuffle(arr)
	#from sklearn.grid_search import GridSearchCV
	#from sklearn.metrics import mean_squared_error
	#clfg = GridSearchCV(SVC(kernel="linear"), {'C':[0.005, 0.001, 0.0005]}, loss_func=mean_squared_error, verbose=100)
	#clfg.fit(features[arr,:], labels[arr], sample_weight=numpy.array(sample_weight)[arr])
	#clfg.fit(features[arr,:], labels[arr])
	#print "best params"+str(clfg.best_params_)
	#clf = clfg.best_estimator_
	#print "starting SVM"

	# do svm
	clf = SVC(C=0.0005, kernel="linear")
	clf.fit(features, labels, sample_weight=sample_weight)
	#clf.fit(features, labels)

	# optionally store filters as normalized images, for validation
	#coefficients = clf.coef_
	#coefficients = ((normalize((coefficients+clf.intercept_)))*255.).astype("uint8")
	#coefficients = coefficients.reshape((scoringmodelHeight,scoringmodelWidth))
	#coefImg = Image.fromarray(coefficients)
	#coefImg.save( join(data_folder, "svmImages/", "svmScoring.bmp") )

	scoringModel = {}
	scoringModel['bias'] = clf.intercept_.tolist()[0]
	scoringModel['coef'] = clf.coef_.flatten().tolist()
	scoringModel['size'] = [scoringmodelWidth,scoringmodelHeight]

	return scoringModel
def build_patches(data, gradient=True, lbp=True, weights=None, optimize_params=False):
    filters = []
    grad_filters = []
    lbp_filters = []
    raw_bias = []
    grad_bias = []
    lbp_bias = []

    #if gradient or lbp:
    grad_patchcrop = [(patch_size+1)/2, (patch_size+3)/2]
    patchcrop = [(patch_size-1)/2, (patch_size+1)/2]

    for r in range(0, num_patches):
        print("training patch:" + str(r))

        positives = []
        negatives = []
        grad_positives = []
        grad_negatives = []
        lbp_positives = []
        lbp_negatives = []
        weighting = []

        # load positive examples
        i = 0
        for filename, values in data.iteritems():
            im = Image.open( join(data_folder, "cropped/", filename) , "r")
            mask = Image.open( join(data_folder, "cropped/", filename[:-4]+"_mask.bmp") , "r")

            # convert image to grayscale
            im = im.convert("L")
            if not numpy.isnan(values[r][0]):
                # TODO : check that there is not missing data:
                points = numpy.around(values[r]+(numpy.array(im.size)/2))
                points = points.astype(numpy.uint8)
                # check whether cropping goes outside image
                m_crop = mask.crop((points[0]-grad_patchcrop[0], points[1]-grad_patchcrop[0], points[0]+grad_patchcrop[1], points[1]+grad_patchcrop[1]))
                m_crop = numpy.array(m_crop)
                if not numpy.all(m_crop == 255):
                    print "cropping of patch "+str(r)+" in image '"+filename+"' was outside original image bounds. Dropping this patch from training."
                else:
                    if weights:
                        if r in weights and filename in weights[r]:
                            weighting.append(True)
                        else:
                            weighting.append(False)
                    if gradient:
                        grad_crop = getGradientCrop(im, points)
                        #Image.fromarray(grad_crop.astype('uint8')).save( join(data_folder, "pcropped/", "grad_"+filename) )
                        grad_positives.append(grad_crop.flatten())
                    if lbp:
                        lbp_crop = getLBPCrop(im, points)
                        #Image.fromarray(lbp_crop.astype('uint8')).save( join(data_folder, "pcropped/", "lbp_"+filename) )
                        lbp_positives.append(lbp_crop.flatten())
                    raw_crop = getRawCrop(im, points)
                    positives.append(raw_crop.flatten())
                # get negative examples from randomization
                for nr in range(0,10):
                    rpoints = random_coord(im.size, patch_size+2, points)
                    # check whether cropping goes outside image
                    m_crop = mask.crop((rpoints[0]-grad_patchcrop[0], rpoints[1]-grad_patchcrop[0], rpoints[0]+grad_patchcrop[1], rpoints[1]+grad_patchcrop[1]))
                    m_crop = numpy.array(m_crop)
                    if not numpy.all(m_crop == 255):
                        pass
                    else:
                        if gradient:
                            grad_crop = getGradientCrop(im, rpoints)
                            #Image.fromarray(grad_crop.astype('uint8')).save( join(data_folder, "pcropped/", "grad_neg_"+filename) )
                            grad_negatives.append(grad_crop.flatten())
                        if lbp:
                            lbp_crop = getLBPCrop(im, rpoints)
                            lbp_negatives.append(lbp_crop.flatten())
                        raw_crop = getRawCrop(im, rpoints)
                        negatives.append(raw_crop.flatten())

            if i % 1000 == 0:
                print i
            i += 1

        # get negative examples from landscape images
        negfiles = [f for f in listdir( join(data_folder, "negatives/") ) if config.valid_file("negatives/",f)]
        for filename in negfiles:
            im = Image.open( join(data_folder, "negatives/", filename) , "r")
            im = im.convert("L")
            diff = grad_patchcrop[0]
            for nr in range(0,100):
                x = random.randint(1+diff, im.size[0]-diff)
                y = random.randint(1+diff, im.size[1]-diff)
                rpoints = array([x,y])
                if gradient:
                    grad_crop = getGradientCrop(im, rpoints)
                    #Image.fromarray(grad_crop.astype('uint8')).save( join(data_folder, "pcropped/", "grad_neg_"+filename) )
                    grad_negatives.append(grad_crop.flatten())
                if lbp:
                    lbp_crop = getLBPCrop(im, rpoints)
                    lbp_negatives.append(lbp_crop.flatten())
                raw_crop = getRawCrop(im, rpoints)
                negatives.append(raw_crop.flatten())

        # maybe use some other nature photos for negative examples?

        # maybe use uniform images for negative examples?

        # normalize image data to 0,1 interval
        positives = [normalize(p) for p in positives]
        negatives = [normalize(n) for n in negatives]
        if gradient:
            grad_positives = [normalize(p) for p in grad_positives]
            grad_negatives = [normalize(n) for n in grad_negatives]
        if lbp:
            lbp_positives = [normalize(p) for p in lbp_positives]
            lbp_negatives = [normalize(n) for n in lbp_negatives]

        labels = [1.0 for p in positives]
        labels.extend([-1.0 for n in negatives])
        labels = numpy.array(labels)
        features = [p.flatten() for p in positives]
        features.extend([n.flatten() for n in negatives])
        features = numpy.vstack(features)
        if gradient:
            grad_features = [p.flatten() for p in grad_positives]
            grad_features.extend([n.flatten() for n in grad_negatives])
            grad_features = numpy.vstack(grad_features)
        if lbp:
            lbp_features = [p.flatten() for p in lbp_positives]
            lbp_features.extend([n.flatten() for n in lbp_negatives])
            lbp_features = numpy.vstack(lbp_features)

        if weights:
            # weighting
            num_positives = float(len(positives))
            num_weighted = float(sum(weighting))
            sample_weight = []
            if num_weighted > 0:
                for p in range(len(positives)):
                    if weighting[p]:
                        sample_weight.append(num_positives/(2*num_weighted))
                    else:
                        sample_weight.append(num_positives/(2*(num_positives-num_weighted)))
                for n in range(len(negatives)):
                    sample_weight.append(1.)
            else:
                sample_weight = [1.0]*(len(positives)+len(negatives))
        else:
            sample_weight = [1.0]*(len(positives)+len(negatives))

        if optimize_params:
            # use grid search/cross-validation to set C, epsilon parameter on each patch?
            arr = numpy.arange(features.shape[0])
            numpy.random.shuffle(arr)
            from sklearn.grid_search import GridSearchCV
            from sklearn.metrics import mean_squared_error
            clfg = GridSearchCV(SVR(kernel="linear"), {'C':[0.1], 'epsilon' : [0.4, 0.3, 0.2, 0.1]}, verbose=100)
            clfg.fit(features[arr,:], labels[arr])
            print clfg.best_params_
            clf = clfg.best_estimator_
        else:
            clf = SVR(C=0.1, epsilon=0.3, kernel="linear")
        #clf = LogisticRegression(penalty='L2', dual=False, C=0.00001)

        clf.fit(features, labels, sample_weight=sample_weight)

        # store filters as normalized images, for validation
        #saveAsImage(clf.coef_, join(data_folder, "svmImages/", "raw"+str(r)+".bmp"))

        filters.append(clf.coef_.flatten().tolist())
        raw_bias.append(clf.intercept_[0])

        if gradient:
            if optimize_params:
                clfg = GridSearchCV(SVR(kernel="linear"), {'C':[0.1], 'epsilon' : [0.4, 0.3, 0.2, 0.1]}, verbose=100)
                clfg.fit(grad_features[arr,:], labels[arr])
                print "gradient best params"+str(clfg.best_params_)
                clf = clfg.best_estimator_
            else:
                clf = SVR(C=0.1, epsilon=0.3, kernel="linear")
            clf.fit(grad_features, labels, sample_weight=sample_weight)
            grad_filters.append(clf.coef_.flatten().tolist())
            grad_bias.append(clf.intercept_[0])

            #saveAsImage(clf.coef_, join(data_folder, "svmImages/", "grad"+str(r)+".bmp"))
        if lbp:
            if optimize_params:
                clfg = GridSearchCV(SVR(kernel="linear"), {'C':[0.1], 'epsilon' : [0.4, 0.3, 0.2, 0.1]}, verbose=100)
                clfg.fit(lbp_features[arr,:], labels[arr])
                print "lbp best params"+str(clfg.best_params_)
                clf = clfg.best_estimator_
            else:
                clf = SVR(C=0.1, epsilon=0.3, kernel="linear")
            clf.fit(lbp_features, labels, sample_weight=sample_weight)
            lbp_filters.append(clf.coef_.flatten().tolist())
            lbp_bias.append(clf.intercept_[0])

            #saveAsImage(clf.coef_, join(data_folder, "svmImages/", "lbp"+str(r)+".bmp"))

    # output for standard model:
    filteroutput = {
        'raw' : [[-filters[f][r] for r in range(0, patch_size*patch_size)] for f in range(0, num_patches)],
    }
    biasoutput = {
        'raw' : raw_bias
    }
    if gradient:
        filteroutput['sobel'] = [[-grad_filters[f][r] for r in range(0, patch_size*patch_size)] for f in range(0, num_patches)]
        biasoutput['sobel'] = grad_bias
    if lbp:
        filteroutput['lbp'] = [[-lbp_filters[f][r] for r in range(0, patch_size*patch_size)] for f in range(0, num_patches)]
        biasoutput['lbp'] = lbp_bias

    # output result as dictionary with entries
    patchModel = {}
    patchModel['patchSize'] = [patch_size, patch_size]
    patchModel['weights'] = filteroutput
    patchModel['bias'] = biasoutput
    patchModel['numPatches'] = num_patches
    patchModel['patchType'] = 'SVM'

    return patchModel
Exemple #3
0
def build_patches(data, gradient=True, lbp=True, weights=None, optimize_params=False):
	filters = []
	grad_filters = []
	lbp_filters = []
	raw_bias = []
	grad_bias = []
	lbp_bias = []

	#if gradient or lbp:
	grad_patchcrop = [(patch_size+1)/2, (patch_size+3)/2]
	patchcrop = [(patch_size-1)/2, (patch_size+1)/2]

	for r in range(0, num_patches):
		print "training patch:"+str(r)

		positives = []
		negatives = []
		grad_positives = []
		grad_negatives = []
		lbp_positives = []
		lbp_negatives = []
		weighting = []

		# load positive examples
		i = 0
		for filename, values in data.iteritems():
			im = Image.open( join(data_folder, "cropped/", filename) , "r")
			mask = Image.open( join(data_folder, "cropped/", filename[:-4]+"_mask.bmp") , "r")

			# convert image to grayscale
			im = im.convert("L")
			if not numpy.isnan(values[r][0]):
				# TODO : check that there is not missing data:
				points = numpy.around(values[r]+(numpy.array(im.size)/2))
				points = points.astype(numpy.uint8)
				# check whether cropping goes outside image
				m_crop = mask.crop((points[0]-grad_patchcrop[0], points[1]-grad_patchcrop[0], points[0]+grad_patchcrop[1], points[1]+grad_patchcrop[1]))
				m_crop = numpy.array(m_crop)
				if not numpy.all(m_crop == 255):
					print "cropping of patch "+str(r)+" in image '"+filename+"' was outside original image bounds. Dropping this patch from training."
				else:
					if weights:
						if r in weights and filename in weights[r]:
							weighting.append(True)
						else:
							weighting.append(False)
					if gradient:
						grad_crop = getGradientCrop(im, points)
						#Image.fromarray(grad_crop.astype('uint8')).save( join(data_folder, "pcropped/", "grad_"+filename) )
						grad_positives.append(grad_crop.flatten())
					if lbp:
						lbp_crop = getLBPCrop(im, points)
						#Image.fromarray(lbp_crop.astype('uint8')).save( join(data_folder, "pcropped/", "lbp_"+filename) )
						lbp_positives.append(lbp_crop.flatten())
					raw_crop = getRawCrop(im, points)
					positives.append(raw_crop.flatten())
				# get negative examples from randomization
				for nr in range(0,10):
					rpoints = random_coord(im.size, patch_size+2, points)
					# check whether cropping goes outside image
					m_crop = mask.crop((rpoints[0]-grad_patchcrop[0], rpoints[1]-grad_patchcrop[0], rpoints[0]+grad_patchcrop[1], rpoints[1]+grad_patchcrop[1]))
					m_crop = numpy.array(m_crop)
					if not numpy.all(m_crop == 255):
						pass
					else:
						if gradient:
							grad_crop = getGradientCrop(im, rpoints)
							#Image.fromarray(grad_crop.astype('uint8')).save( join(data_folder, "pcropped/", "grad_neg_"+filename) )
							grad_negatives.append(grad_crop.flatten())
						if lbp:
							lbp_crop = getLBPCrop(im, rpoints)
							lbp_negatives.append(lbp_crop.flatten())
						raw_crop = getRawCrop(im, rpoints)
						negatives.append(raw_crop.flatten())

			if i % 1000 == 0:
				print i
			i += 1

		# get negative examples from landscape images
		negfiles = [f for f in listdir( join(data_folder, "negatives/")	) if config.valid_file("negatives/",f)]
		for filename in negfiles:
			im = Image.open( join(data_folder, "negatives/", filename) , "r")
			im = im.convert("L")
			diff = grad_patchcrop[0]
			for nr in range(0,100):
				x = random.randint(1+diff, im.size[0]-diff)
				y = random.randint(1+diff, im.size[1]-diff)
				rpoints = array([x,y])
				if gradient:
					grad_crop = getGradientCrop(im, rpoints)
					#Image.fromarray(grad_crop.astype('uint8')).save( join(data_folder, "pcropped/", "grad_neg_"+filename) )
					grad_negatives.append(grad_crop.flatten())
				if lbp:
					lbp_crop = getLBPCrop(im, rpoints)
					lbp_negatives.append(lbp_crop.flatten())
				raw_crop = getRawCrop(im, rpoints)
				negatives.append(raw_crop.flatten())

		# maybe use some other nature photos for negative examples?

		# maybe use uniform images for negative examples?

		# normalize image data to 0,1 interval
		positives = [normalize(p) for p in positives]
		negatives = [normalize(n) for n in negatives]
		if gradient:
			grad_positives = [normalize(p) for p in grad_positives]
			grad_negatives = [normalize(n) for n in grad_negatives]
		if lbp:
			lbp_positives = [normalize(p) for p in lbp_positives]
			lbp_negatives = [normalize(n) for n in lbp_negatives]

		labels = [1.0 for p in positives]
		labels.extend([-1.0 for n in negatives])
		labels = numpy.array(labels)
		features = [p.flatten() for p in positives]
		features.extend([n.flatten() for n in negatives])
		features = numpy.vstack(features)
		if gradient:
			grad_features = [p.flatten() for p in grad_positives]
			grad_features.extend([n.flatten() for n in grad_negatives])
			grad_features = numpy.vstack(grad_features)
		if lbp:
			lbp_features = [p.flatten() for p in lbp_positives]
			lbp_features.extend([n.flatten() for n in lbp_negatives])
			lbp_features = numpy.vstack(lbp_features)

		if weights:
			# weighting
			num_positives = float(len(positives))
			num_weighted = float(sum(weighting))
			sample_weight = []
			if num_weighted > 0:
				for p in range(len(positives)):
					if weighting[p]:
						sample_weight.append(num_positives/(2*num_weighted))
					else:
						sample_weight.append(num_positives/(2*(num_positives-num_weighted)))
				for n in range(len(negatives)):
					sample_weight.append(1.)
			else:
				sample_weight = [1.0]*(len(positives)+len(negatives))
		else:
			sample_weight = [1.0]*(len(positives)+len(negatives))

		if optimize_params:
			# use grid search/cross-validation to set C, epsilon parameter on each patch?
			arr = numpy.arange(features.shape[0])
			numpy.random.shuffle(arr)
			from sklearn.grid_search import GridSearchCV
			from sklearn.metrics import mean_squared_error
			clfg = GridSearchCV(SVR(kernel="linear"), {'C':[0.1], 'epsilon' : [0.4, 0.3, 0.2, 0.1]}, scoring='mean_squared_error', verbose=100)
			clfg.fit(features[arr,:], labels[arr])
			print clfg.best_params_
			clf = clfg.best_estimator_
		else:
			clf = SVR(C=0.1, epsilon=0.3, kernel="linear")
		#clf = LogisticRegression(penalty='L2', dual=False, C=0.00001)

		clf.fit(features, labels, sample_weight=sample_weight)

		# store filters as normalized images, for validation
		#saveAsImage(clf.coef_, join(data_folder, "svmImages/", "raw"+str(r)+".bmp"))

		filters.append(clf.coef_.flatten().tolist())
		raw_bias.append(clf.intercept_[0])

		if gradient:
			if optimize_params:
				clfg = GridSearchCV(SVR(kernel="linear"), {'C':[0.1], 'epsilon' : [0.4, 0.3, 0.2, 0.1]}, scoring='mean_squared_error', verbose=100)
				clfg.fit(grad_features[arr,:], labels[arr])
				print "gradient best params"+str(clfg.best_params_)
				clf = clfg.best_estimator_
			else:
				clf = SVR(C=0.1, epsilon=0.3, kernel="linear")
			clf.fit(grad_features, labels, sample_weight=sample_weight)
			grad_filters.append(clf.coef_.flatten().tolist())
			grad_bias.append(clf.intercept_[0])

			#saveAsImage(clf.coef_, join(data_folder, "svmImages/", "grad"+str(r)+".bmp"))
		if lbp:
			if optimize_params:
				clfg = GridSearchCV(SVR(kernel="linear"), {'C':[0.1], 'epsilon' : [0.4, 0.3, 0.2, 0.1]}, scoring='mean_squared_error', verbose=100)
				clfg.fit(lbp_features[arr,:], labels[arr])
				print "lbp best params"+str(clfg.best_params_)
				clf = clfg.best_estimator_
			else:
				clf = SVR(C=0.1, epsilon=0.3, kernel="linear")
			clf.fit(lbp_features, labels, sample_weight=sample_weight)
			lbp_filters.append(clf.coef_.flatten().tolist())
			lbp_bias.append(clf.intercept_[0])

			#saveAsImage(clf.coef_, join(data_folder, "svmImages/", "lbp"+str(r)+".bmp"))

	# output for standard model:
	filteroutput = {
		'raw' : [[-filters[f][r] for r in range(0, patch_size*patch_size)] for f in range(0, num_patches)],
	}
	biasoutput = {
		'raw' : raw_bias
	}
	if gradient:
		filteroutput['sobel'] = [[-grad_filters[f][r] for r in range(0, patch_size*patch_size)] for f in range(0, num_patches)]
		biasoutput['sobel'] = grad_bias
	if lbp:
		filteroutput['lbp'] = [[-lbp_filters[f][r] for r in range(0, patch_size*patch_size)] for f in range(0, num_patches)]
		biasoutput['lbp'] = lbp_bias

	# output result as dictionary with entries
	patchModel = {}
	patchModel['patchSize'] = [patch_size, patch_size]
	patchModel['weights'] = filteroutput
	patchModel['bias'] = biasoutput
	patchModel['numPatches'] = num_patches
	patchModel['patchType'] = 'SVM'

	return patchModel
Exemple #4
0
def getScoring(data, mean, weights=False):
    """
	Create a logistic regression filter for scoring how close the tracking is to the face
	"""

    positives = []
    negatives = []
    weighting = []

    scoringmodelWidth = 20
    scoringmodelHeight = 22

    # get how large window to crop, based on meandata
    mins = numpy.amin(mean, axis=0)
    maxs = numpy.amax(mean, axis=0)
    mean_width = int(round(maxs[0] - mins[0]))
    mean_height = int(round(maxs[1] - mins[1]))
    mins = mins + numpy.array(
        [float(mean_width / 4.5), -float(mean_height) / 12])
    maxs = maxs + numpy.array(
        [-float(mean_width / 4.5), -float(mean_height) / 6])

    # load positive examples
    i = 0
    print "getting positive examples from face images"
    for filename, values in data.iteritems():
        im = Image.open(join(data_folder, "cropped/", filename), "r")

        if weights:
            if re.match(r"i\d\d\d.*", filename):
                weighting.append(True)
            else:
                weighting.append(False)

        # convert image to grayscale
        im = im.convert("L")

        imins = mins + numpy.array(im.size) / 2
        imaxs = maxs + numpy.array(im.size) / 2

        p_crop = im.crop((int(round(imins[0])), int(round(imins[1])),
                          int(round(imaxs[0])), int(round(imaxs[1]))))

        # reduce resolution
        p_crop = p_crop.resize((scoringmodelWidth, scoringmodelHeight),
                               Image.BILINEAR)

        # do log of images
        p_crop = numpy.log(numpy.array(p_crop, dtype=numpy.uint16) + 1.0)
        #p_crop = numpy.array(p_crop)

        p_crop_img = Image.fromarray(
            (normalize(p_crop) * 255.).astype("uint8"))
        p_crop_img.save(join(data_folder, "pcropped/", filename + "_mask.bmp"))

        positives.append(p_crop.flatten())

        if i % 1000 == 0:
            print i
        i += 1

    print "getting negative examples from face images"

    # get negative examples from face images
    negfiles = [
        f for f in listdir(join(data_folder, "images/"))
        if config.valid_file("images/", f)
    ]

    for filename in negfiles:
        if filename.endswith(".jpg") or filename.endswith(".png"):
            try:
                im = Image.open(join(data_folder, "images/", filename), "r")
                im = im.convert("L")
                ranwidth = int(round(im.size[0] * 0.3))
                ranheight = int(round(im.size[1] * 0.3))
                for nr in range(0, 1):

                    x = random.randint(0, int(round(im.size[0] - ranwidth)))
                    y = random.randint(0, int(round(im.size[1] - ranheight)))
                    rpoints = numpy.array([x, y])
                    p_crop = im.crop(
                        (rpoints[0], rpoints[1], rpoints[0] + ranwidth,
                         rpoints[1] + ranheight))
                    # reduce resolution
                    p_crop = p_crop.resize(
                        (scoringmodelWidth, scoringmodelHeight),
                        Image.BILINEAR)
                    # do log of images
                    p_crop2 = numpy.log(
                        numpy.array(p_crop, dtype=numpy.uint16) + 1)
                    #p_crop2 = numpy.array(p_crop)

                    p_crop_img = Image.fromarray(
                        (normalize(p_crop2) * 255.).astype("uint8"))
                    p_crop_img.save(
                        join(data_folder, "pcropped/",
                             "neg_" + filename + "_mask.bmp"))

                    negatives.append(p_crop2.flatten())
            except IOError:
                print "could not load invalid image file: " + join(
                    data_folder, "images/", filename)

    print "getting negative examples from landscape images"
    # get negative examples from landscape images

    negfiles = [
        f for f in listdir(join(data_folder, "negatives/"))
        if config.valid_file("negatives/", f)
    ]

    if len(negfiles) == 0:
        print "you have no 'negative' images in the ./negatives/ folder"
        exit(1)

    for filename in negfiles:
        im = Image.open(join(data_folder, "negatives/", filename), "r")
        im = im.convert("L")
        for nr in range(0, 10):
            x = random.randint(0, im.size[0] - mean_width)
            y = random.randint(0, im.size[1] - mean_height)
            rpoints = numpy.array([x, y])
            p_crop = im.crop((rpoints[0], rpoints[1], rpoints[0] + mean_width,
                              rpoints[1] + mean_height))
            # reduce resolution
            p_crop = p_crop.resize((scoringmodelWidth, scoringmodelHeight),
                                   Image.BILINEAR)
            # do log of images
            p_crop = numpy.log(numpy.array(p_crop, dtype=numpy.uint16) + 1)
            #p_crop = numpy.array(p_crop)

            p_crop_img = Image.fromarray(
                (normalize(p_crop) * 255.).astype("uint8"))
            p_crop_img.save(
                join(data_folder, "pcropped/",
                     "neg_" + filename + "_mask.bmp"))

            negatives.append(p_crop.flatten())

    # normalize image data
    positives = [preprocessing.scale(p) for p in positives]
    negatives = [preprocessing.scale(n) for n in negatives]

    if weights:
        # weighting
        num_positives = float(len(positives))
        num_weighted = float(sum(weighting))
        sample_weight = []
        if num_weighted > 0:
            for p in range(len(positives)):
                if weighting[p]:
                    sample_weight.append(num_positives / (2 * num_weighted))
                else:
                    sample_weight.append(num_positives /
                                         (2 * (num_positives - num_weighted)))
            for n in range(len(negatives)):
                sample_weight.append(1.)
        else:
            sample_weight = [1.0] * (len(positives) + len(negatives))
    else:
        #sample_weight = [1.0]*(len(positives)+len(negatives))
        sample_weight = [1.0] * (len(positives))
        sample_weight.extend([len(positives) / (2 * float(len(negatives)))] *
                             len(negatives))

    labels = [1.0 for p in positives]
    labels.extend([-1.0 for n in negatives])
    labels = numpy.array(labels)
    features = [p.flatten() for p in positives]
    features.extend([n.flatten() for n in negatives])
    features = numpy.vstack(features)

    #arr = numpy.arange(features.shape[0])
    #numpy.random.shuffle(arr)
    #from sklearn.grid_search import GridSearchCV
    #from sklearn.metrics import mean_squared_error
    #clfg = GridSearchCV(SVC(kernel="linear"), {'C':[0.005, 0.001, 0.0005]}, loss_func=mean_squared_error, verbose=100)
    #clfg.fit(features[arr,:], labels[arr], sample_weight=numpy.array(sample_weight)[arr])
    #clfg.fit(features[arr,:], labels[arr])
    #print "best params"+str(clfg.best_params_)
    #clf = clfg.best_estimator_
    #print "starting SVM"

    # do svm
    clf = SVC(C=0.0005, kernel="linear")
    clf.fit(features, labels, sample_weight=sample_weight)
    #clf.fit(features, labels)

    # optionally store filters as normalized images, for validation
    #coefficients = clf.coef_
    #coefficients = ((normalize((coefficients+clf.intercept_)))*255.).astype("uint8")
    #coefficients = coefficients.reshape((scoringmodelHeight,scoringmodelWidth))
    #coefImg = Image.fromarray(coefficients)
    #coefImg.save( join(data_folder, "svmImages/", "svmScoring.bmp") )

    scoringModel = {}
    scoringModel['bias'] = clf.intercept_.tolist()[0]
    scoringModel['coef'] = clf.coef_.flatten().tolist()
    scoringModel['size'] = [scoringmodelWidth, scoringmodelHeight]

    return scoringModel