forked from travis-miller/Forgery_Detection_0
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPCA_Method.py
More file actions
143 lines (126 loc) · 4.95 KB
/
PCA_Method.py
File metadata and controls
143 lines (126 loc) · 4.95 KB
1
"""ECE 520 Project - Image Forgery DetectionPCA Forgery DetectionTravis MillerNarasimha N. Chakravarty"""from numpy import *from scipy import statsfrom math import floorfrom math import sqrt"""Reads in image to tested"""image_file = open ( 'Forge_2.txt', 'r' )image = image_file.read()image_file.close() #test"""Resizes data from txt file to be the dimensions of the image"""image = image.split()image = np.reshape(image, (512, 512))image = image.transpose()im_size = np.shape(image)"""Variables used in this program"""blocks = zeros( (255025,64) ) #Matrix U with image blocksblocks_norm = zeros( (255025,64) ) #Image Blocks with mean subtractedblocks_cov = [] #Covariance Matrix of Image Blocksoffsets= zeros( (2295144,4))new_offsets= zeros( (2295144,3))offset_save = []max_freq = 0a = []k = 0"""Creates the image for the blocks"""for i in range(im_size[0] - 7):for j in range(im_size[1] - 7):blk = array(image[i:i+8, j:j+8], dtype = single) #Takes out a 8x8 block out of the imageblk = np.reshape(blk, (1, 64)) #Forms the blocks into a vectorblocks[k] = blk #Stores the block vector into the matrixk += 1"""Calculation of Covariance and Eigenvectors"""blk_avg = np.mean(blocks, axis=0) #Finds the mean of the columnsblk_avg = np.reshape(blk_avg, (1, 64)) #reshapes the matrix of the mean blocks_norm = blocks - blk_avg #subtracts out the mean from the columns blocks_norm_t = blocks_norm.transpose()blocks_cov = np.dot(blocks_norm_t, blocks_norm)/255024 #Finds the covariance of the blocks matrixw, v = linalg.eig(blocks_cov) #Finds the eigenvalues and eignevector of the covariance matrix pca_v = v[: , 0:4] #Creates the Principal Component Matrix"""Tranforms the Block Vectors into new block representation"""new_blocks = np.dot(blocks_norm, pca_v) #Multiplies block vector with new_blocks_t = new_blocks.transpose() #Transpose new_blocks = np.around(new_blocks) #Round the values to nearest integer"""Attaches coordinate to every block"""position = zeros( (255025,1) ) x_cor = zeros( (255025,1) )new_position = zeros( (255025,1) )y_cor = zeros( (255025,1) )for i in range(255025):position[i] = i + 1 #Makes vector for of matrix positionsnew_blocks = np.hstack((new_blocks, position)) #Attaches matrix posisiton to rows"""Sorts the matrix with new representation vectors"""ind = np.lexsort((new_blocks[:,2], new_blocks[:,1], new_blocks[:,0])) #Sorts rows based of column valuessorted_blks = new_blocks[ind] #Rearranges matrix with new indicenew_position[:,0] = sorted_blks[:,4] #Takes the block coordinates of the """Finds x and y corrdinate of row"""k=0for i in range(255025):point = new_position[i]x_cor[i] = (point - 1) % 505 #Finds x coordinate of block in imagey_cor[i] = np.floor((point - 1) / 505) #Finds y coordinate of block in imagenew_position = np.hstack((x_cor, y_cor,new_position)) #Attaches y and x coordinate to row"""Calculating neighboring row offsets"""for i in range(255025 - 9):for j in range(1,10):if new_position[i][0] - new_position[i+j][0] > 0: offsets[k][0] = new_position[i][0] - new_position[i+j][0]offsets[k][1] = new_position[i][1] - new_position[i+j][1]elif new_position[i][0] - new_position[i+j][0] < 0:offsets[k][0] = new_position[i+j][0] - new_position[i][0]offsets[k][1] = new_position[i][1] - new_position[i+j][1]else:offsets[k][0] = 0offsets[k][1] = abs(new_position[i][1] - new_position[i+j][1])offsets[k][2] = new_position[i][0]offsets[k][3] = new_position[i][1]k += 1"""Searches for most occuring offset"""ind = np.lexsort((offsets[:,1],offsets[:,0])) #Sorts for most occuring offsetoffsets = offsets[ind] #Rearrenges offsets in order of most frequentoffsets = offsets.astype(int) #Changes offset type to integeroff_group = offsets[:,0] * 1000 + offsets[:,1] #Creates Offset to one number to count frequencyfreq_count = np.bincount(off_group)"""Checks if the most occuring offset mets the threshold and is far enough apart"""for i in range(len(freq_count)):x = i/1000y = i%1000x_2 = 0y_2 = 0if x > 0:x_2 = long(x * x) y_2 = long(y*y)if y > 500:x += 1x_2 = long(x)y = 1000 - yy_2 = long(y)y_2 = y_2 * y_2y = -yif freq_count[i] > 320 and sqrt(x_2 + y_2)>25: #Threshold and magnitude checkprint i print freq_count[i]print ""if max_freq < freq_count[i]:max_freq = freq_count[i] max_cor = x*1000+y #Stores matrix row location of most occuring offsetcopy_x = x #Stores x offsetcopy_y = y #Stores y offsetnew_offsets[:,0] = off_groupnew_offsets[:,1] = offsets[:,2]new_offsets[:,2] = offsets[:,3]"""Outputs coordinates of the forged region for visual display"""condition = np.where( new_offsets == max_cor ) output_cor = new_offsets[condition[0]]output_corx = output_cor[:,1]output_cory = output_cor[:,2]offset_save.append(copy_x)offset_save.append(copy_y) np.savetxt('x_cor.txt', output_corx) #Outputs x coordinates of forged pixelsnp.savetxt('y_cor.txt', output_cory) #Outputs y coordinates of forged pixelsnp.savetxt('offset.txt', offset_save) #Outputs the offset value between pixels