Spaces:
Sleeping
Sleeping
Upload 6 files
Browse files- app.py +199 -0
- evidences_db.py +50 -0
- image_generation.py +23 -0
- login_db.py +26 -0
- models.py +61 -0
- secret.py +3 -0
app.py
ADDED
@@ -0,0 +1,199 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from flask import Flask, render_template, request, jsonify, redirect, url_for, session
|
2 |
+
from pymongo import MongoClient
|
3 |
+
import pickle
|
4 |
+
import random
|
5 |
+
import threading
|
6 |
+
import time
|
7 |
+
import pandas as pd
|
8 |
+
from bson import ObjectId
|
9 |
+
from flask_socketio import SocketIO, emit
|
10 |
+
from tensorflow.keras.models import load_model # type: ignore
|
11 |
+
from PIL import Image
|
12 |
+
import numpy as np
|
13 |
+
|
14 |
+
app = Flask(__name__)
|
15 |
+
app.secret_key = b'\xddhO\xc8\x05\xb8<\xa5m1\xa5\x9c\x11O5\xaf\x9e\t\xe8\xcd\x1bWv`'
|
16 |
+
socketio = SocketIO(app)
|
17 |
+
|
18 |
+
# MongoDB connection setup
|
19 |
+
client = MongoClient('mongodb://localhost:27017/')
|
20 |
+
db = client['risk_prediction_db']
|
21 |
+
users_collection = db['users']
|
22 |
+
evidence_collection = db['evidences']
|
23 |
+
|
24 |
+
# Load the pre-trained CNN model for evidence type classification (3 classes)
|
25 |
+
evidence_type_model = load_model('models/evidence_type_cnn.h5')
|
26 |
+
|
27 |
+
# Load the risk prediction model
|
28 |
+
with open('models/risk_prediction_model.pkl', 'rb') as f:
|
29 |
+
model = pickle.load(f)
|
30 |
+
|
31 |
+
# Load the scaler used during training for the risk prediction model
|
32 |
+
with open('models/scaler.pkl', 'rb') as f:
|
33 |
+
scaler = pickle.load(f)
|
34 |
+
|
35 |
+
# Default variables based on evidence type (updated with correct classes)
|
36 |
+
evidence_defaults = {
|
37 |
+
'fingerprint': {'Temperature': '28', 'Humidity': '55', 'Vibration': '0', 'Light_Intensity': '250', 'Battery_Level': '85'},
|
38 |
+
'gun': {'Temperature': '22', 'Humidity': '40', 'Vibration': '1', 'Light_Intensity': '300', 'Battery_Level': '90'},
|
39 |
+
'stained_cloth': {'Temperature': '25', 'Humidity': '50', 'Vibration': '0', 'Light_Intensity': '200', 'Battery_Level': '80'}
|
40 |
+
}
|
41 |
+
|
42 |
+
# Global flag to track simulation state
|
43 |
+
simulation_running = False
|
44 |
+
|
45 |
+
# Login route
|
46 |
+
@app.route('/', methods=['GET', 'POST'])
|
47 |
+
def login():
|
48 |
+
if request.method == 'POST':
|
49 |
+
username = request.form['username']
|
50 |
+
password = request.form['password']
|
51 |
+
|
52 |
+
user = users_collection.find_one({'username': username, 'password': password})
|
53 |
+
if user:
|
54 |
+
session['username'] = username
|
55 |
+
return redirect(url_for('home'))
|
56 |
+
else:
|
57 |
+
return 'Invalid login credentials'
|
58 |
+
|
59 |
+
return render_template('login.html')
|
60 |
+
|
61 |
+
# Route for predicting the evidence type when the image is uploaded
|
62 |
+
@app.route('/predict_evidence', methods=['POST'])
|
63 |
+
def predict_evidence():
|
64 |
+
if 'username' not in session:
|
65 |
+
return jsonify({'error': 'Unauthorized'}), 401
|
66 |
+
|
67 |
+
if 'evidence_image' not in request.files:
|
68 |
+
return jsonify({'error': 'No image uploaded'}), 400
|
69 |
+
|
70 |
+
# Handle image upload for CNN prediction
|
71 |
+
evidence_image = request.files['evidence_image']
|
72 |
+
img = Image.open(evidence_image).resize((64, 64))
|
73 |
+
img_array = np.array(img) / 255.0 # Normalize the image
|
74 |
+
img_array = img_array.reshape(1, 64, 64, 3) # Add batch dimension
|
75 |
+
|
76 |
+
# Use the CNN model to predict the evidence type
|
77 |
+
prediction = evidence_type_model.predict(img_array)
|
78 |
+
predicted_class = np.argmax(prediction[0]) # Get class index
|
79 |
+
|
80 |
+
# Update the classes based on the correct evidence types
|
81 |
+
evidence_types = ['fingerprint', 'gun', 'stained_cloth']
|
82 |
+
predicted_evidence = evidence_types[predicted_class]
|
83 |
+
|
84 |
+
# Autofill variables based on the predicted evidence type
|
85 |
+
variables = evidence_defaults[predicted_evidence]
|
86 |
+
|
87 |
+
# Return predicted evidence type and variables as JSON
|
88 |
+
return jsonify({
|
89 |
+
'predicted_evidence': predicted_evidence,
|
90 |
+
'variables': variables
|
91 |
+
})
|
92 |
+
|
93 |
+
# Home route for submitting the final evidence and running risk prediction
|
94 |
+
@app.route('/home', methods=['GET', 'POST'])
|
95 |
+
def home():
|
96 |
+
global simulation_running
|
97 |
+
|
98 |
+
if 'username' not in session:
|
99 |
+
return redirect(url_for('login'))
|
100 |
+
|
101 |
+
if request.method == 'POST':
|
102 |
+
# Get variables from the form
|
103 |
+
variables = {
|
104 |
+
'Temperature': request.form['temperature'],
|
105 |
+
'Humidity': request.form['humidity'],
|
106 |
+
'Vibration': request.form['vibration'],
|
107 |
+
'Light_Intensity': request.form['light_intensity'],
|
108 |
+
'Battery_Level': request.form['battery_level']
|
109 |
+
}
|
110 |
+
|
111 |
+
# Run risk prediction using the ensemble model
|
112 |
+
features = pd.DataFrame([variables], columns=[
|
113 |
+
'Temperature', 'Humidity', 'Vibration', 'Light_Intensity', 'Battery_Level'
|
114 |
+
])
|
115 |
+
scaled_features = scaler.transform(features)
|
116 |
+
risk_prediction = model.predict(scaled_features)[0]
|
117 |
+
risk = 'High Risk' if risk_prediction == 1 else 'Low Risk'
|
118 |
+
|
119 |
+
# Store the evidence and prediction in MongoDB
|
120 |
+
evidence_id = str(ObjectId())
|
121 |
+
evidence_collection.insert_one({
|
122 |
+
'_id': evidence_id,
|
123 |
+
'username': session['username'],
|
124 |
+
'variables': variables,
|
125 |
+
'risk_prediction': risk
|
126 |
+
})
|
127 |
+
|
128 |
+
# Start the IoT simulation after the first prediction, if not already running
|
129 |
+
if not simulation_running:
|
130 |
+
simulation_running = True
|
131 |
+
threading.Thread(target=simulate_iot_data, daemon=True).start()
|
132 |
+
|
133 |
+
return redirect(url_for('dashboard'))
|
134 |
+
|
135 |
+
return render_template('home.html')
|
136 |
+
|
137 |
+
# Dashboard route to display evidence logs and risk status
|
138 |
+
@app.route('/dashboard')
|
139 |
+
def dashboard():
|
140 |
+
if 'username' not in session:
|
141 |
+
return redirect(url_for('login'))
|
142 |
+
|
143 |
+
evidences = list(evidence_collection.find({'username': session['username']}))
|
144 |
+
return render_template('dashboard.html', evidences=evidences)
|
145 |
+
|
146 |
+
# Simulate IoT Monitoring (Random data changes)
|
147 |
+
def simulate_iot_data():
|
148 |
+
global simulation_running
|
149 |
+
|
150 |
+
while simulation_running:
|
151 |
+
time.sleep(10) # Simulate IoT update every 10 seconds (for testing purposes)
|
152 |
+
|
153 |
+
# Retrieve all evidences from MongoDB
|
154 |
+
all_evidences = evidence_collection.find()
|
155 |
+
|
156 |
+
for evidence in all_evidences:
|
157 |
+
# Randomly update numerical variables to simulate IoT changes
|
158 |
+
updated_values = {
|
159 |
+
'Temperature': random.uniform(10, 50), # Simulate temperature (°C)
|
160 |
+
'Humidity': random.uniform(30, 90), # Simulate humidity (%)
|
161 |
+
'Vibration': random.randint(0, 1), # Simulate vibration (0 or 1)
|
162 |
+
'Light_Intensity': random.uniform(100, 1000),# Simulate light intensity (lx)
|
163 |
+
'Battery_Level': random.uniform(0, 100), # Simulate battery level (%)
|
164 |
+
}
|
165 |
+
|
166 |
+
# Update evidence with new simulated values in MongoDB
|
167 |
+
evidence_collection.update_one(
|
168 |
+
{'_id': evidence['_id']},
|
169 |
+
{'$set': {'variables': updated_values}}
|
170 |
+
)
|
171 |
+
|
172 |
+
# Create features DataFrame with correct column names
|
173 |
+
features = pd.DataFrame([updated_values], columns=[
|
174 |
+
'Temperature', 'Humidity', 'Vibration', 'Light_Intensity',
|
175 |
+
'Battery_Level'
|
176 |
+
])
|
177 |
+
scaled_features = scaler.transform(features)
|
178 |
+
|
179 |
+
# Run the risk prediction with updated data
|
180 |
+
risk_prediction = model.predict(scaled_features)[0] # Use DataFrame
|
181 |
+
new_risk = 'High Risk' if risk_prediction == 1 else 'Low Risk'
|
182 |
+
|
183 |
+
# If risk status changes, update it
|
184 |
+
if new_risk != evidence['risk_prediction']:
|
185 |
+
evidence_collection.update_one(
|
186 |
+
{'_id': evidence['_id']},
|
187 |
+
{'$set': {'risk_prediction': new_risk}}
|
188 |
+
)
|
189 |
+
|
190 |
+
# Emit real-time risk updates to all connected clients
|
191 |
+
socketio.emit('risk_update', {
|
192 |
+
'evidence_id': str(evidence['_id']),
|
193 |
+
'risk': new_risk,
|
194 |
+
'variables': updated_values
|
195 |
+
})
|
196 |
+
|
197 |
+
# Start the Flask app with SocketIO
|
198 |
+
if __name__ == '__main__':
|
199 |
+
socketio.run(app, debug=True)
|
evidences_db.py
ADDED
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from pymongo import MongoClient
|
2 |
+
|
3 |
+
# Connect to MongoDB
|
4 |
+
client = MongoClient('mongodb://localhost:27017/')
|
5 |
+
db = client['risk_prediction_db']
|
6 |
+
evidence_collection = db['evidences']
|
7 |
+
|
8 |
+
# Example evidence records to insert
|
9 |
+
sample_evidences = [
|
10 |
+
{
|
11 |
+
"username": "admin",
|
12 |
+
"image_filename": "evidence_image_1.png",
|
13 |
+
"temperature": 25.3,
|
14 |
+
"humidity": 60.5,
|
15 |
+
"vibration": 1, # 1 means "Yes"
|
16 |
+
"light_intensity": 400.0,
|
17 |
+
"battery_level": 85.0,
|
18 |
+
"latitude": 37.7749,
|
19 |
+
"longitude": -122.4194,
|
20 |
+
"risk_prediction": "High Risk"
|
21 |
+
},
|
22 |
+
{
|
23 |
+
"username": "user1",
|
24 |
+
"image_filename": "evidence_image_2.png",
|
25 |
+
"temperature": 22.1,
|
26 |
+
"humidity": 55.3,
|
27 |
+
"vibration": 0, # 0 means "No"
|
28 |
+
"light_intensity": 500.0,
|
29 |
+
"battery_level": 90.0,
|
30 |
+
"latitude": 40.7128,
|
31 |
+
"longitude": -74.0060,
|
32 |
+
"risk_prediction": "Low Risk"
|
33 |
+
},
|
34 |
+
{
|
35 |
+
"username": "user2",
|
36 |
+
"image_filename": "evidence_image_3.png",
|
37 |
+
"temperature": 35.7,
|
38 |
+
"humidity": 75.1,
|
39 |
+
"vibration": 1, # 1 means "Yes"
|
40 |
+
"light_intensity": 300.0,
|
41 |
+
"battery_level": 65.0,
|
42 |
+
"latitude": 51.5074,
|
43 |
+
"longitude": -0.1278,
|
44 |
+
"risk_prediction": "High Risk"
|
45 |
+
}
|
46 |
+
]
|
47 |
+
|
48 |
+
# Insert evidence records into MongoDB
|
49 |
+
evidence_collection.insert_many(sample_evidences)
|
50 |
+
print("inserted")
|
image_generation.py
ADDED
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from google_images_download import google_images_download
|
2 |
+
|
3 |
+
response = google_images_download.googleimagesdownload()
|
4 |
+
|
5 |
+
# Define the search keywords and the number of images to download for each
|
6 |
+
search_queries = ['blood', 'cloth', 'gun', 'fingerprint']
|
7 |
+
|
8 |
+
def download_images(query):
|
9 |
+
arguments = {
|
10 |
+
"keywords": query,
|
11 |
+
"limit": 100, # Number of images to download
|
12 |
+
"print_urls": True,
|
13 |
+
"output_directory": "C:/COLLEGE/web develop/Evidence_prediction/data/train",
|
14 |
+
"format": "jpg",
|
15 |
+
"no_directory": False
|
16 |
+
}
|
17 |
+
try:
|
18 |
+
response.download(arguments)
|
19 |
+
except Exception as e:
|
20 |
+
print(f"Error downloading images for {query}: {e}")
|
21 |
+
|
22 |
+
for query in search_queries:
|
23 |
+
download_images(query)
|
login_db.py
ADDED
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from pymongo import MongoClient
|
2 |
+
|
3 |
+
# Connect to MongoDB
|
4 |
+
client = MongoClient('mongodb://localhost:27017/')
|
5 |
+
db = client['risk_prediction_db']
|
6 |
+
users_collection = db['users']
|
7 |
+
|
8 |
+
# Example users to insert
|
9 |
+
sample_users = [
|
10 |
+
{
|
11 |
+
"username": "admin",
|
12 |
+
"password": "admin123" # Hashed password
|
13 |
+
},
|
14 |
+
{
|
15 |
+
"username": "user1",
|
16 |
+
"password": "user1234" # Hashed password
|
17 |
+
},
|
18 |
+
{
|
19 |
+
"username": "user2",
|
20 |
+
"password": "password5678" # Hashed password
|
21 |
+
}
|
22 |
+
]
|
23 |
+
|
24 |
+
# Insert users into MongoDB
|
25 |
+
users_collection.insert_many(sample_users)
|
26 |
+
print("Inserted")
|
models.py
ADDED
@@ -0,0 +1,61 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
import numpy as np
|
3 |
+
from tensorflow.keras.models import Sequential
|
4 |
+
from tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense
|
5 |
+
from tensorflow.keras.preprocessing.image import ImageDataGenerator
|
6 |
+
from tensorflow.keras.optimizers import Adam
|
7 |
+
|
8 |
+
# Define image dimensions
|
9 |
+
IMAGE_SIZE = (64, 64)
|
10 |
+
BATCH_SIZE = 32
|
11 |
+
EPOCHS = 10
|
12 |
+
|
13 |
+
# Paths for training and validation data
|
14 |
+
TRAIN_DIR = 'data/train'
|
15 |
+
VALIDATION_DIR = 'data/validation'
|
16 |
+
|
17 |
+
# Data augmentation and normalization for training
|
18 |
+
train_datagen = ImageDataGenerator(rescale=1./255)
|
19 |
+
validation_datagen = ImageDataGenerator(rescale=1./255)
|
20 |
+
|
21 |
+
train_generator = train_datagen.flow_from_directory(
|
22 |
+
TRAIN_DIR,
|
23 |
+
target_size=IMAGE_SIZE,
|
24 |
+
batch_size=BATCH_SIZE,
|
25 |
+
class_mode='categorical' # Use 'categorical' for multiple classes
|
26 |
+
)
|
27 |
+
|
28 |
+
validation_generator = validation_datagen.flow_from_directory(
|
29 |
+
VALIDATION_DIR,
|
30 |
+
target_size=IMAGE_SIZE,
|
31 |
+
batch_size=BATCH_SIZE,
|
32 |
+
class_mode='categorical'
|
33 |
+
)
|
34 |
+
|
35 |
+
# Check if data generators are correctly detecting 3 classes
|
36 |
+
assert train_generator.num_classes == 3, "Train generator is detecting more/less than 3 classes"
|
37 |
+
assert validation_generator.num_classes == 3, "Validation generator is detecting more/less than 3 classes"
|
38 |
+
|
39 |
+
# CNN Model Definition with 3 output classes
|
40 |
+
model = Sequential([
|
41 |
+
Conv2D(32, (3, 3), activation='relu', input_shape=(64, 64, 3)),
|
42 |
+
MaxPooling2D(pool_size=(2, 2)),
|
43 |
+
Conv2D(64, (3, 3), activation='relu'),
|
44 |
+
MaxPooling2D(pool_size=(2, 2)),
|
45 |
+
Flatten(),
|
46 |
+
Dense(128, activation='relu'),
|
47 |
+
Dense(3, activation='softmax') # 3 classes: blood, cloth, fingerprint
|
48 |
+
])
|
49 |
+
|
50 |
+
# Compile the model
|
51 |
+
model.compile(optimizer=Adam(), loss='categorical_crossentropy', metrics=['accuracy'])
|
52 |
+
|
53 |
+
# Train the model
|
54 |
+
model.fit(
|
55 |
+
train_generator,
|
56 |
+
epochs=EPOCHS,
|
57 |
+
validation_data=validation_generator
|
58 |
+
)
|
59 |
+
|
60 |
+
# Save the model to the 'models/' directory
|
61 |
+
model.save('models/evidence_type_cnn.h5')
|
secret.py
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
secret_key = os.urandom(24)
|
3 |
+
print("secret key is :",secret_key)
|