-
Notifications
You must be signed in to change notification settings - Fork 3
/
app.py
163 lines (132 loc) · 6.48 KB
/
app.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
import streamlit as st
import cv2
import os
import numpy as np
from keras.models import load_model
from helper import prepare_image_for_ela, prerpare_img_for_weather
from fetchOriginal import image_coordinates, get_weather
from PIL import Image as PILImage
import io
# Constants
class_weather = ['Lightning', 'Rainy', 'Snow', 'Sunny']
class_ELA = ['Real', 'Tampered']
outdoor = False
# Functions
def check_img(image_name):
img = cv2.resize(cv2.imread(image_name), (750, 750))
return img
def detect_ELA(img_name):
global ela_result
np_img_input, ela_result = prepare_image_for_ela(img_name)
ELA_model = load_model('ELA_Training/model_ela.h5')
Y_predicted = ELA_model.predict(np_img_input, verbose=0)
return "Model shows {}% accuracy of image being {}".format(round(np.max(Y_predicted[0]) * 100), class_ELA[np.argmax(Y_predicted[0])])
def detect_weather(img_name):
np_img_input = prerpare_img_for_weather(img_name)
model_Weather = load_model('WeatherCNNTraining/Weather_Model.h5')
Y_predicted = model_Weather.predict(np_img_input, verbose=0)
return "Model shows weather in Image is {} ({}% accurate)".format(class_weather[np.argmax(Y_predicted[0])],round(np.max(Y_predicted[0]) * 100))
def org_weather(img_name):
global outdoor
date_time, lat, long, outdoor = image_coordinates(img_name)
if not outdoor:
return
print(lat)
location, date, weather = get_weather(date_time, lat, long)
if lat == 0.0:
return "Not able to fetch location. (some devices may mask location exif info)."
if weather == "NA":
return "The Image was taken at {} on {}; weather data not available".format(location, date)
return "The Image was taken at {} and weather there on {} was {}".format(location, date, weather)
# Streamlit Interface
st.title("Image Tampering Detection Using ELA and Metadata Analysis")
st.markdown("""
### Welcome to the Image Tampering Detector!
**What This Project Does:**
This tool helps you determine whether an image has been altered or manipulated. Try it out and see if your images hold up under scrutiny!
""")
with st.expander("How it Works?"):
st.markdown("""
There are two parallels that are being used to identify an image's authenticity:
1. **Error Level Analysis (ELA):**
- Images that are edited often show different compression artifacts compared to the original ones. ELA highlights these discrepancies, making tampering visible.
""")
# Create columns for horizontal layout
col1, col2 = st.columns(2)
# Display ELA images in columns
with col1:
st.image("rsc/real.jpg", caption="ELA of a Real Image", use_column_width=True)
with col2:
st.image("rsc/fake.jpg", caption="ELA of a Tampered Image", use_column_width=True)
st.markdown("""
Notice how ELA on real image shows consistency across the image but on fake image, ELA shows discrepancy across some regions.
2. **Weather Validation:**
- **Purpose:** Weather Validation examines the metadata embedded in the image to cross-check if the depicted weather conditions are consistent with historical weather data from the image's recorded location and time.
- **How?:**
Images often contain metadata that includes information about the location, date, and time when the image was taken.
Using this metadata, historical weather databases are queried to retrieve the weather conditions for the recorded location and date.
Then actual weather conditions in the image are compared (as identified by a Weather CNN model) with the historical data to determine if they match.
- **Why It Matters:** This helps in verifying the authenticity of outdoor images by ensuring that the weather depicted matches what was recorded historically for that location and time. Discrepancies can indicate tampering or misrepresentation.
""")
with st.expander("How to use it?"):
st.markdown("""
1. **Upload an Image:** Choose an image to analyze.
2. **Select the Outdoor Option:** Indicate whether the image is taken outdoors.
3. **View Results:** Get insights into the image’s authenticity with detailed analysis.
""")
with st.expander("Got a Query?"):
st.markdown("""
Hi, I'm Jayant
If you have any questions, feedback, suggestions, or just want to chat, feel free to reach out!
- [Linkedin](https://www.linkedin.com/in/jayantmeshram/)
- [Github](https://github.com/jayant1211)
you can also email me at jayantmeshram398@gmail.com.
""")
# Initialize session state
if 'step' not in st.session_state:
st.session_state.step = 0
# Handle file upload
uploaded_file = st.file_uploader("Choose a .jpg/.jpeg image...", type=["jpg", "jpeg"])
if uploaded_file is not None:
with open("temp.jpg", "wb") as f:
f.write(uploaded_file.getbuffer())
st.image(uploaded_file, caption="Uploaded Image", use_column_width=True)
flag = st.radio("Is weather visible in the image? (requires image metadata)", ('Yes', 'No'))
if st.button("Proceed") and st.session_state.step == 0:
st.session_state.step = 1
# Show results if step > 0
if st.session_state.step > 0:
org = check_img("temp.jpg")
res1 = detect_ELA("temp.jpg")
res2, res3 = '', ''
if flag == 'Yes':
res2 = org_weather("temp.jpg")
res3 = detect_weather("temp.jpg")
st.write("### Results:")
st.write("1. " + res1)
if flag == "Yes":
if not outdoor:
st.write("Trouble fetching exif. Image do not have location or time metadata. (some devices may mask location exif info).")
else:
st.write("2. " + res2)
st.write("3. " + res3)
if st.button("Show Error Level Analysis") and st.session_state.step == 1:
# Display ELA result image
st.image(ela_result, caption="ELA Analysis")
#TODO ela img goes away, add session step here
# Save ELA result image to a BytesIO object
buffer = io.BytesIO()
ela_result.save(buffer, format="JPEG") # ela_result should be a PIL Image
buffer.seek(0)
# Add a download button for the ELA result image
st.download_button(
label="Save ELA Result Image",
data=buffer,
file_name="ela_result.jpg",
mime="image/jpeg"
)
# Button to reset the session state and allow new image upload
if st.button("Try New Image"):
st.session_state.step = 0
#st.experimental_rerun() is not working
st.rerun()