Mini Project
Mini Project
Code:-
import numpy as np
import numpy.matlib as npm
import argparse
import json
import pprint
import exifread
import cv2 as cv
import os
import pywt
import math
import progressbar
import warnings
from scipy import ndimage
from PIL import Image
from PIL.ExifTags import TAGS, GPSTAGS
from matplotlib import pyplot as plt
from os.path import basename
def main():
argparser = argparse.ArgumentParser(description="Digital Image Forensics")
#argparser.add_argument("-e", help='export EXIF to XML')
argparser.add_argument("datafile", metavar='file',
help='name of the image file')
argparser.add_argument("-e", "--exif", help="exposing digital forgeries by EXIF
metadata",
action="store_true")
argparser.add_argument("-gm", "--jpegghostm", help="exposing digital forgeries by JPEG
Ghost (Multiple)",
action="store_true")
argparser.add_argument("-g", "--jpegghost", help="exposing digital forgeries by JPEG
Ghost",
action="store_true")
argparser.add_argument(
"-n1", "--noise1", help="exposing digital forgeries by using noise inconsistencies",
action="store_true")
argparser.add_argument(
"-n2", "--noise2", help="exposing digital forgeries by using Median-filter noise residue
inconsistencies", action="store_true")
argparser.add_argument(
"-el", "--ela", help="exposing digital forgeries by using Error Level Analysis",
action="store_true")
argparser.add_argument(
"-cf", "--cfa", help="Image tamper detection based on demosaicing artifacts",
action="store_true")
argparser.add_argument("-q", "--quality", help="resaved image quality",
type=int)
argparser.add_argument("-s", "--blocksize", help="block size kernel mask",
type=int)
# Parses arguments
args = argparser.parse_args()
if check_file(args.datafile) == False:
print("Invalid file. Please make sure the file is exist and the type is JPEG")
return
if args.exif:
exif_check(args.datafile)
elif args.jpegghostm:
jpeg_ghost_multiple(args.datafile)
elif args.jpegghost:
jpeg_ghost(args.datafile, args.quality)
##########################################################
### EXPOSING DIGITAL FORGERIES BY NOISE INCONSITENCIES ###
##########################################################
elif args.noise1:
noise_inconsistencies(args.datafile, args.blocksize)
#########################################################
### EXPOSING DIGITAL FORGERIES BY MEDIAN FILTER NOISE ###
#########################################################
elif args.noise2:
median_noise_inconsistencies(args.datafile, args.blocksize)
###########################################################
### EXPOSING DIGITAL FORGERIES BY DEMOSAICING ARTIFACTS ###
###########################################################
elif args.ela:
ela(args.datafile, args.quality, args.blocksize)
#########################################################
### EXPOSING DIGITAL FORGERIES BY MEDIAN FILTER NOISE ###
#########################################################
elif args.cfa:
cfa_tamper_detection(args.datafile)
else:
exif_check(args.datafile)
def check_file(data_path):
if os.path.isfile(data_path) == False:
return False
if data_path.lower().endswith(('.jpg', '.jpeg')) == False:
return False
return True
###############################################
### Functions for extracting EXIF Metadata ###
###############################################
def exif_check(file_path):
# Open image file for reading (binary mode)
f = open(file_path, 'rb')
# Return Exif tags
tags = exifread.process_file(f)
# Get the pure EXIF data of Image
exif_code_form = extract_pure_exif(file_path)
if exif_code_form == None:
print("The EXIF data has been stripped. Photo maybe is taken from facebook, twitter,
imgur")
return
# Check Modify Date
check_software_modify(exif_code_form)
check_modify_date(exif_code_form)
check_original_date(exif_code_form)
check_camera_information(tags)
check_gps_location(exif_code_form)
check_author_copyright(exif_code_form)
# Print Raw Image Metadata
print("\nRAW IMAGE METADATA")
print("=============================================================
\n")
print("EXIF Data")
# pprint.pprint(decode_exif_data(exif_code_form))
for tag in tags.keys():
if tag not in ('JPEGThumbnail', 'TIFFThumbnail', 'Filename', 'EXIF MakerNote'):
print("%-35s: %s" % (tag, tags[tag]))
def extract_pure_exif(file_name):
img = Image.open(file_name)
info = img._getexif()
return info
def decode_exif_data(info):
exif_data = {}
if info:
for tag, value in info.items():
decoded = TAGS.get(tag, tag)
exif_data[decoded] = value
return exif_data
def get_if_exist(data, key):
if key in data:
return data[key]
return None
def export_json(data):
with open('data.txt', 'w') as outfile:
json.dump(data, outfile, ensure_ascii=False)
print("\nCamera Infomation")
print("-------------------------------------------------------------- ")
print("Make: \t \t %s" % make)
print("Model: \t \t %s" % model)
print("Exposure: \t %s " % exposure)
print("Aperture: \t %s" % aperture)
print("Focal Length: \t %s mm" % focal_length)
print("ISO Speed: \t %s" % iso_speed)
print("Flash: \t \t %s" % flash)
print("\nLocation (GPS)")
print("-------------------------------------------------------------- ")
if gps_info == None:
print("GPS coordinates not found")
return False
# print gps_info
lat = None
lng = None
gps_latitude = get_if_exist(gps_info, 0x0002)
gps_latitude_ref = get_if_exist(gps_info, 0x0001)
gps_longitude = get_if_exist(gps_info, 0x0004)
gps_longitude_ref = get_if_exist(gps_info, 0x0003)
if gps_latitude and gps_latitude_ref and gps_longitude and gps_longitude_ref:
lat = convert_to_degress(gps_latitude)
if gps_latitude_ref != "N":
lat = 0 - lat
lng = convert_to_degress(gps_longitude)
if gps_longitude_ref != "E":
lng = 0 - lng
return True
def convert_to_degress(value):
"""Helper function to convert the GPS coordinates
stored in the EXIF to degress in float format"""
d = float(value[0])
m = float(value[1])
s = float(value[2])
return d + (m / 60.0) + (s / 3600.0)
def check_author_copyright(info):
author = get_if_exist(info, 0x9c9d)
copyright_tag = get_if_exist(info, 0x8298)
profile_copyright = get_if_exist(info, 0xc6fe)
print("\nAuthor and Copyright")
print("-------------------------------------------------------------- ")
print("Author \t \t %s " % author)
print("Copyright \t %s " % copyright_tag)
print("Profile: \t %s" % profile_copyright)
#########################################################################
##################################
#### Functions for JPEG Ghost ####
##################################
def jpeg_ghost_multiple(file_path):
print("Analyzing...")
bar = progressbar.ProgressBar(maxval=20,
widgets=[progressbar.Bar('=', '[', ']'), ' ', progressbar.Percentage()])
bar.start()
img = cv.imread(file_path)
img_rgb = img[:, :, ::-1]
# Compute the square different between original image and the resaved image
tmp = (img_rgb-img_low_rgb)**2
# Shift the pixel from the center of the block to the left-top
tmp = tmp[offset:(int(height-offset)), offset:(int(width-offset))]
# Nomalization
dst = tmp - nomalized
# print(dst)
# Plot the diffrent images
plt.subplot(5, 4, pos_q+2), plt.imshow(dst,
cmap='gray'), plt.title(quality)
plt.xticks([]), plt.yticks([])
quality = quality + 2
bar.update(pos_q+2)
bar.finish()
print("Done")
plt.suptitle('Exposing digital forgeries by JPEG Ghost')
plt.show()
os.remove(save_file_name)
print("Analyzing...")
bar = progressbar.ProgressBar(maxval=20,
widgets=[progressbar.Bar('=', '[', ']'), ' ', progressbar.Percentage()])
bar.start()
img = cv.imread(file_path)
img_rgb = img[:, :, ::-1]
bar.finish()
print("Done")
#########################################################################
###################################################################
#### Functions for Median-filter noise residue inconsistencies ####
###################################################################
img = cv.imread(file_path)
img_rgb = img[:, :, ::-1]
# print(interp_layer)
for k in range(bin_filter.shape[0]):
for h in range(bin_filter.shape[1]):
if bin_filter[k, h, i] == 0:
mixed_im[k, h] = interp_layer[k, h]
elif bin_filter[k, h, i] == 1:
mixed_im[k, h] = orig_layer[k, h]
# print(mixed_im.shape)
out_im[:, :, i] = mixed_im
out_im = np.round(out_im)
# print(out_im[:,:,0])
return out_im
def eval_block(data):
im = data
# print(Out)
return Out
if __name__ == "__main__":
main()
Output:-