def computeTrainingData(args):
	
	#A list of the different file suffixes corresponding to the different face variants for each subject
	name = ['9326871','9336923','ahodki','anpage','doraj','ekavaz','jmedin','klclar','mbutle','moors','obeidn','pspliu']
	
	#For each person
	for i in name:
		
		imageStorage = []
		#We use the first 8 of 11 images as training data, and the final 3 as tests
		for j in range(1,7):
			
			img = dia.openImage('TrainingData/' + i + '.' + str(j) + '.jpg')[0]
			
			imageStorage.append(img)
		
		imageCube = np.array(imageStorage)

		PCImages = PCATrans(imageCube)
		
		#Save the component images to form the database of training data
		for l in range(len(PCImages)):
				
				
				dia.saveImage(np.uint8(255.0*(PCImages[l]-np.amin(PCImages[l]))/(np.amax(PCImages[l])-np.amin(PCImages[l]))), 'TrainingData/PrincipalComponents/' + i + '.' + str(l) + '.jpg')
				
				np.savetxt('TrainingData/PrincipalComponents/' + i + '.component' + str(l) + '.txt',PCImages[l])
		
		mean = np.sum(imageCube, axis=0)/(imageCube.shape[0])
	
		dia.saveImage(np.uint8(255.0*(mean - np.amin(mean))/(np.amax(mean) - np.amin(mean))), 'TrainingData/PrincipalComponents/' + str(i) + 'mean.jpg')
		
		mean = mean/np.sqrt(np.sum(mean*mean))
		np.savetxt('TrainingData/PrincipalComponents/' + i + 'mean.txt',mean)
def computeMeanValues(args):
	
	outfile = open("ImageMeanValues1.txt", 'w')
	
	goodMeans = []
	yellowedMeans = []
	
	for i in range(3118,4116):
		
		image = []
		
		try:
			if i < 10:
				
				image = dia.openImage("DJI0000" + str(i) + ".JPG")
				print "DJI0000" + str(i) + ".JPG"
				
			elif i >= 10 and i < 100:
				
				image = dia.openImage("DJI000" + str(i) + ".JPG")
				print "DJI000" + str(i) + ".JPG"	
				
			elif i >= 100 and i < 1000 :
				
				image = dia.openImage("DJI00" + str(i) + ".JPG")
				print "DJI00" + str(i) + ".JPG"
				
			else:
								
				image = dia.openImage("DJI0" + str(i) + ".JPG")
				print "DJI0" + str(i) + ".JPG"
			
			meanVector = dia.meanVector(image)
			
			if meanVector[2] > 80:
				
				goodMeans.append(meanVector[2])
				
			else:
				
				yellowedMeans.append(meanVector[2])
			
			
			outfile.write("Image Name: DJI00" + str(i) + ".JPG\n")
			outfile.write("Image Mean Vector\n")
			outfile.write(str(meanVector))
			outfile.write('\n\n')
			
		except AttributeError:
			
			print "DJI00" + str(i) + ".JPG not found"

	goodMeans = np.array(goodMeans, dtype='uint64')
	yellowedMeans = np.array(yellowedMeans, dtype='uint64')
			
	goodMeanGlobal = np.sum(1.0*goodMeans/goodMeans.shape[0])
	yellowedMeanGlobal = np.sum(1.0*yellowedMeans/yellowedMeans.shape[0])
def computeTrainingData(args):

    #A list of the different file suffixes corresponding to the different face variants for each subject
    name = [
        '9326871', '9336923', 'ahodki', 'anpage', 'doraj', 'ekavaz', 'jmedin',
        'klclar', 'mbutle', 'moors', 'obeidn', 'pspliu'
    ]

    #For each person
    for i in name:

        imageStorage = []
        #We use the first 8 of 11 images as training data, and the final 3 as tests
        for j in range(1, 7):

            img = dia.openImage('TrainingData/' + i + '.' + str(j) + '.jpg')[0]

            imageStorage.append(img)

        imageCube = np.array(imageStorage)

        PCImages = PCATrans(imageCube)

        #Save the component images to form the database of training data
        for l in range(len(PCImages)):

            dia.saveImage(
                np.uint8(255.0 * (PCImages[l] - np.amin(PCImages[l])) /
                         (np.amax(PCImages[l]) - np.amin(PCImages[l]))),
                'TrainingData/PrincipalComponents/' + i + '.' + str(l) +
                '.jpg')

            np.savetxt(
                'TrainingData/PrincipalComponents/' + i + '.component' +
                str(l) + '.txt', PCImages[l])

        mean = np.sum(imageCube, axis=0) / (imageCube.shape[0])

        dia.saveImage(
            np.uint8(255.0 * (mean - np.amin(mean)) /
                     (np.amax(mean) - np.amin(mean))),
            'TrainingData/PrincipalComponents/' + str(i) + 'mean.jpg')

        mean = mean / np.sqrt(np.sum(mean * mean))
        np.savetxt('TrainingData/PrincipalComponents/' + i + 'mean.txt', mean)
def PCATrans(img):

    mean = np.sum(img, axis=0) / (img.shape[0])

    resImage = 1.0 * img - 1.0 * mean

    imgCov = dia.varCorrMatrix(img)[0]

    #Create a list containing the number of faces
    bands = []

    for i in range(img.shape[0]):

        bands.append(i + 1)

    #Compute the eigenvalues and eigenvectors of the covariance matrix
    covEigVal, covEigVec = np.linalg.eig(imgCov)

    #Output the eigenvalues, eigenvectors and %variance values to the output file
    #outfile.write("EigenValues:\n" + str(covEigVal))
    #outfile.write("\n\n%Variance:\n" + str(covEigVal/np.sum(covEigVal)))
    #outfile.write("\n\nEigenVectors:\n" + str(covEigVec))

    #Create an array of eigenvalue, eigenvector and band number pairs
    pairs = [(covEigVal[i], covEigVec[i], bands[i]) for i in range(len(bands))]

    #Sort the eigenvalue pairs in descending order
    pairs.sort()
    pairs.reverse()

    #Generate the eigenvector transformation matrix (G)
    G = []

    for i in range(len(pairs)):

        G.append(pairs[i][1])

    #Convert the images into a linear image
    linearImage = resImage.reshape(img.shape[0], img.shape[1] * img.shape[2])

    G = np.array(G)
    #Compute the principle components of the image
    linearPC = np.dot(G.T, linearImage)
    PC = []

    #Transform from a linear image to a square image
    for i in range(len(linearPC)):

        temp = linearPC[i] / np.sqrt(np.sum(linearPC[i] * linearPC[i]))
        PC.append(temp.reshape(img.shape[1], img.shape[2]))

    return np.array(PC)
def PCATrans(img):
	
	mean = np.sum(img, axis=0)/(img.shape[0])
	
	resImage = 1.0*img - 1.0*mean
	
	imgCov = dia.varCorrMatrix(img)[0]
	
	#Create a list containing the number of faces
	bands = []
	
	for i in range(img.shape[0]):
		
		bands.append(i + 1)
	
	#Compute the eigenvalues and eigenvectors of the covariance matrix
	covEigVal, covEigVec = np.linalg.eig(imgCov)
	
	#Output the eigenvalues, eigenvectors and %variance values to the output file
	#outfile.write("EigenValues:\n" + str(covEigVal))
	#outfile.write("\n\n%Variance:\n" + str(covEigVal/np.sum(covEigVal)))
	#outfile.write("\n\nEigenVectors:\n" + str(covEigVec))

	#Create an array of eigenvalue, eigenvector and band number pairs
	pairs = [(covEigVal[i],covEigVec[i],bands[i]) for i in range(len(bands))]

	#Sort the eigenvalue pairs in descending order
	pairs.sort()
	pairs.reverse()
 
	#Generate the eigenvector transformation matrix (G)
	G = []

	for i in range(len(pairs)):
 
		G.append(pairs[i][1])

	#Convert the images into a linear image
	linearImage = resImage.reshape(img.shape[0],img.shape[1]*img.shape[2])

	G = np.array(G)
	#Compute the principle components of the image
	linearPC = np.dot(G.T,linearImage)
	PC = []
 
	#Transform from a linear image to a square image
	for i in range(len(linearPC)):
		
		temp = linearPC[i]/np.sqrt(np.sum(linearPC[i]*linearPC[i]))
		PC.append(temp.reshape(img.shape[1],img.shape[2]))

	return np.array(PC)
def computeWeights():

    #A list of the different file suffixes corresponding to the different face variants for each subject
    name = [
        '9326871', '9336923', 'ahodki', 'anpage', 'doraj', 'ekavaz', 'jmedin',
        'klclar', 'mbutle', 'moors', 'obeidn', 'pspliu'
    ]

    weightDB = {}

    #For each person
    for i in name:

        imageStorage = []

        weights = []

        for j in range(1, 5):

            img = np.loadtxt('TrainingData/PrincipalComponents/' + i +
                             '.component' + str(j) + '.txt')

            imageStorage.append(img)

        imageStorage = np.array(imageStorage)

        mean = np.loadtxt('TrainingData/PrincipalComponents/' + i + 'mean.txt')

        for j in range(1, 4):

            img = dia.openImage('TrainingData/' + i + '.' + str(j) + '.jpg')[0]

            img = img / np.sqrt(np.sum(img * img))

            temp = []

            for k in range(imageStorage.shape[0]):

                temp.append(imageStorage[k] * (img - mean))

            weights.append(np.array(temp))

        weights = np.array(weights)
        weightDB[i] = np.sum(weights, axis=0) / weights.shape[0]

        ##np.savetxt('RegularPrincipalComponents/subject' + str(i) + 'weights.txt',avgWeight)
    return weightDB
def computeWeights():
	
	#A list of the different file suffixes corresponding to the different face variants for each subject
	name = ['9326871','9336923','ahodki','anpage','doraj','ekavaz','jmedin','klclar','mbutle','moors','obeidn','pspliu']
	
	weightDB = {}
	
	#For each person
	for i in name:
		
		imageStorage = []
		
		weights = []
		
		for j in range(1,5):
			
			img = np.loadtxt('TrainingData/PrincipalComponents/' + i + '.component' + str(j) + '.txt')

			imageStorage.append(img)
		
		imageStorage = np.array(imageStorage)
		
		mean = np.loadtxt('TrainingData/PrincipalComponents/' + i + 'mean.txt')
		
		for j in range(1,4):
			
			img = dia.openImage('TrainingData/' + i + '.' + str(j) + '.jpg')[0]
			
			img = img/np.sqrt(np.sum(img*img))
			
			temp = []
			
			for k in range(imageStorage.shape[0]):
				
				temp.append(imageStorage[k]*(img-mean))

			weights.append(np.array(temp))
			
		weights = np.array(weights)
		weightDB[i] = np.sum(weights, axis=0)/weights.shape[0]
		
		##np.savetxt('RegularPrincipalComponents/subject' + str(i) + 'weights.txt',avgWeight)		
	return weightDB
        '9326871', '9336923', 'ahodki', 'anpage', 'doraj', 'ekavaz', 'jmedin',
        'klclar', 'mbutle', 'moors', 'obeidn', 'pspliu'
    ]

    computeTrainingData(sys.argv)
    weightDB = computeWeights()
    #For each person

    summ = 0
    total = 0

    for i in name:

        for j in range(7, 9):

            image = dia.openImage('TrainingData/' + i + '.' + str(j) +
                                  '.jpg')[0]

            face = computeFace(image, weightDB, name)
            print 'Image Name: subject ' + i + '.' + str(
                j) + '\nIdentified as: subject0' + str(face) + '\n\n\n'
            #input()

            total += 1

            if face == i:

                summ += 1

    print 1.0 * summ / total
if __name__=='__main__':
	
	#A list of the different file suffixes corresponding to the different face variants for each subject
	name = ['9326871','9336923','ahodki','anpage','doraj','ekavaz','jmedin','klclar','mbutle','moors','obeidn','pspliu']
	
	computeTrainingData(sys.argv)
	weightDB = computeWeights()
	#For each person
	
	summ = 0
	total = 0
	
	for i in name:
		
		for j in range(7,9):
			
			image = dia.openImage('TrainingData/' + i + '.' + str(j) + '.jpg')[0]
				
			face = computeFace(image, weightDB, name)
			print 'Image Name: subject ' + i + '.' + str(j) + '\nIdentified as: subject0' + str(face) + '\n\n\n'
			#input()
			
			total += 1
			
			if face == i:
				
				summ += 1
				
	
	print 1.0*summ/total
def shiftImages(args):
	
	outfile = open("ImageMeanValues1.txt", 'a')
	yellowedMeans = []
	goodMeans = []
	redMeans = []
	redGoodMeans = []
	
	means = []
	
	for i in range(3118,4116):
		
		image = []
		
		try:
			if i < 10:
				
				image = dia.openImage("DJI0000" + str(i) + ".JPG")
				print "DJI0000" + str(i) + ".JPG"
				
			elif i >= 10 and i < 100:
				
				image = dia.openImage("DJI000" + str(i) + ".JPG")
				print "DJI000" + str(i) + ".JPG"	
				
			elif i >= 100 and i < 1000 :
				
				image = dia.openImage("DJI00" + str(i) + ".JPG")
				print "DJI00" + str(i) + ".JPG"
			else:
								
				image = dia.openImage("DJI0" + str(i) + ".JPG")
				print "DJI0" + str(i) + ".JPG"
			
			meanVector = dia.meanVector(image)
			means.append(meanVector)
			
			if meanVector[2] > 80:
				
				goodMeans.append(meanVector[2])
				
			else:
				
				yellowedMeans.append(meanVector[2])
				
			if meanVector[0] < 145:
				
				redGoodMeans.append(meanVector[0])
				
			else:
				
				redMeans.append(meanVector[0])
				
		except AttributeError:
			
			print "DJI00" + str(i) + ".JPG not found"
	
	means = np.array(means)
	
	plt.plot(range(0,means.shape[0]), means[:,0], c='red')
	plt.plot(range(0,means.shape[0]), means[:,1], c='green')
	plt.plot(range(0,means.shape[0]), means[:,2], c='blue')
	plt.title('Image Mean Values')
	plt.xlabel('Image Number')
	plt.ylabel('Mean DN')
	plt.show()
	
	goodMeans = np.array(goodMeans, dtype='uint64')
	yellowedMeans = np.array(yellowedMeans, dtype='uint64')
		
	goodMeanGlobal = np.sum(1.0*goodMeans/goodMeans.shape[0])
	yellowedMeanGlobal = np.sum(1.0*yellowedMeans/yellowedMeans.shape[0])
	meanDifference = goodMeanGlobal - yellowedMeanGlobal
	
	outfile.write("\n\n\n\n These are the global statistics of the blue band using a value of 80 to separate the \"good images\" from the \"yellowed images\". The value was obtained by inspection of the output mean values.\n\n")
	outfile.write('\nGood Mean = ' + str(goodMeanGlobal))
	outfile.write('\nYellow Mean = ' + str(yellowedMeanGlobal))
			
	goodVar = np.sum(np.power(goodMeans - goodMeanGlobal,2))/(goodMeans.shape[0] - 1)
	yellowedVar = np.sum(np.power(yellowedMeans - yellowedMeanGlobal,2))/(yellowedMeans.shape[0] - 1)
			
	outfile.write('\nGood Standard Deviation = ' + str(np.sqrt(goodVar)))
	outfile.write('\nYellowed Standard Deviaiton = ' + str(np.sqrt(yellowedVar)))
	
	outfile.write('\nYellowed Range = ' + str(np.amax(yellowedMeans) - np.amin(yellowedMeans)))
	outfile.write('\nGood Range = ' + str(np.amax(goodMeans) - np.amin(goodMeans)))

	redGoodMeans = np.array(redGoodMeans, dtype='uint64')
	redMeans = np.array(redMeans, dtype='uint64')
		
	redGoodMeanGlobal = np.sum(1.0*redGoodMeans/redGoodMeans.shape[0])
	redMeanGlobal = np.sum(1.0*redMeans/redMeans.shape[0])
	redMeanDifference = redGoodMeanGlobal - redMeanGlobal
	
	outfile.write("\n\n\n\n These are the global statistics of the Red band using a value of 145 to separate the \"good images\" from the \"yellowed images\". The value was obtained by inspection of the output mean values.\n\n")
	outfile.write('\nGood Mean = ' + str(redGoodMeanGlobal))
	outfile.write('\nYellow Mean = ' + str(redMeanGlobal))
			
	goodVar = np.sum(np.power(redGoodMeans - redGoodMeanGlobal,2))/(redGoodMeans.shape[0] - 1)
	yellowedVar = np.sum(np.power(redMeans - redMeanGlobal,2))/(redMeans.shape[0] - 1)
			
	outfile.write('\nGood Standard Deviation = ' + str(np.sqrt(goodVar)))
	outfile.write('\nYellowed Standard Deviaiton = ' + str(np.sqrt(yellowedVar)))
	
	outfile.write('\nYellowed Range = ' + str(np.amax(redMeans) - np.amin(redMeans)))
	outfile.write('\nGood Range = ' + str(np.amax(redGoodMeans) - np.amin(redGoodMeans)))
	
	refImage = dia.openImage("DJI03790.JPG")
	
	for i in range(3118,4116):
		
		image = []
		
		try:
			if i < 10:
				
				image = dia.openImage("DJI0000" + str(i) + ".JPG")
				print "DJI0000" + str(i) + ".JPG"
				
			elif i >= 10 and i < 100:
				
				image = dia.openImage("DJI000" + str(i) + ".JPG")
				print "DJI000" + str(i) + ".JPG"	
				
			elif i >= 100 and i < 1000 :
				
				image = dia.openImage("DJI00" + str(i) + ".JPG")
				print "DJI00" + str(i) + ".JPG"
			else:
								
				image = dia.openImage("DJI0" + str(i) + ".JPG")
				print "DJI0" + str(i) + ".JPG"
			
			print "Processing Image" + str(i)
			
			meanVector = dia.meanVector(image)
			
			if meanVector[2] < 80:
				
				print "Correcting Image" + str(i)
				
				newImage = np.array([image[0] + redMeanDifference,image[1],image[2] + meanDifference],dtype='uint8')
				
				x = newImage[0] > image[0]
				y = newImage[2] < image[2]
				
				b = newImage[0]
				c = newImage[2]
				
				b[x] = 0
				c[y] = 255
				
				correctedImage = np.array([b,image[1],c], dtype='uint8')
				
				if i < 10:
					
					dia.outputImage(correctedImage, "corrected/CorDJI0000" + str(i) + ".JPG")
				
					dia.georefImage("corrected/CorDJI0000" + str(i) + ".JPG", "DJI0000" + str(i) + ".JPG")
					
				elif i >= 10 and i < 100:
					
					dia.outputImage(correctedImage, "corrected/CorDJI000" + str(i) + ".JPG")
				
					dia.georefImage("corrected/CorDJI000" + str(i) + ".JPG", "DJI000" + str(i) + ".JPG")	
					
				elif i >= 100 and i < 1000 :
					
					dia.outputImage(correctedImage, "corrected/CorDJI00" + str(i) + ".JPG")
				
					dia.georefImage("corrected/CorDJI00" + str(i) + ".JPG", "DJI00" + str(i) + ".JPG")
					
				else:
					
					dia.outputImage(correctedImage, "corrected/CorDJI0" + str(i) + ".JPG")
				
					dia.georefImage("corrected/CorDJI0" + str(i) + ".JPG", "DJI0" + str(i) + ".JPG")
				
			else:
								
				if i < 10:
					
					dia.outputImage(image, "corrected/CorDJI0000" + str(i) + ".JPG")
				
					dia.georefImage("corrected/CorDJI0000" + str(i) + ".JPG", "DJI0000" + str(i) + ".JPG")
					
				elif i >= 10 and i < 100:
					
					dia.outputImage(image, "corrected/CorDJI000" + str(i) + ".JPG")
				
					dia.georefImage("corrected/CorDJI000" + str(i) + ".JPG", "DJI000" + str(i) + ".JPG")	
					
				elif i >= 100 and i < 1000 :
					
					dia.outputImage(image, "corrected/CorDJI00" + str(i) + ".JPG")
				
					dia.georefImage("corrected/CorDJI00" + str(i) + ".JPG", "DJI00" + str(i) + ".JPG")
					
				else:
					
					dia.outputImage(image, "corrected/CorDJI0" + str(i) + ".JPG")
				
					dia.georefImage("corrected/CorDJI0" + str(i) + ".JPG", "DJI0" + str(i) + ".JPG")
					
		except AttributeError as e:
			
			print e
			print "DJI00" + str(i) + ".JPG not found"