noumanjavaid commited on
Commit
f0b3888
Β·
verified Β·
1 Parent(s): 2e0fe12

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +719 -0
app.py ADDED
@@ -0,0 +1,719 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from PIL import Image, ImageDraw, ImageFont, ExifTags
3
+ import requests
4
+ from io import BytesIO
5
+ import cv2
6
+ import numpy as np
7
+ import pandas as pd
8
+ import fitz # PyMuPDF for PDF handling = jls_extract_def()
9
+ import docx # For handling Word documents
10
+ from difflib import HtmlDiff, SequenceMatcher # For text comparison
11
+ import os
12
+ import logging
13
+ import base64
14
+ import zipfile
15
+ from typing import Dict
16
+ from deepface import DeepFace # For deepfake detection
17
+ import pytesseract # For OCR in watermark detection
18
+
19
+ # Page configuration with custom theme
20
+ st.set_page_config(
21
+ page_title="Centurion Analysis Tool", # Title of the web app
22
+ page_icon="https://raw.githubusercontent.com/noumanjavaid96/ai-as-an-api/refs/heads/master/image%20(39).png", # Icon displayed in the browser tab
23
+ layout="wide", # Layout of the app# Initial state of the sidebar
24
+ )
25
+
26
+
27
+
28
+ # Apply custom theme using CSS
29
+ st.markdown(
30
+ """
31
+ <style>
32
+ {
33
+ --primary-color: #aba9aa; # Primary color for the theme
34
+ --background-color: #fdfdfd; # Background color
35
+ --secondary-background-color: #4a4c56; # Secondary background color
36
+ --text-color: #030104; # Text color
37
+ }
38
+ body {
39
+ background-color: var(--background-color); # Set background color
40
+ }
41
+ </style>
42
+ """,
43
+ unsafe_allow_html=True # Allow HTML in markdown
44
+ )
45
+
46
+ # Display the title with the icon
47
+ st.markdown(
48
+ """
49
+ <div class="title-container">
50
+ <img class="title-icon" src="https://raw.githubusercontent.com/noumanjavaid96/ai-as-an-api/refs/heads/master/image%20(39).png" alt="Icon" width="50" height="50">
51
+ <div class="title-text" style="font-size: 36px; font-weight: bold; color: var(--text-color);">Centurion</div>
52
+ </div>
53
+ """,
54
+ unsafe_allow_html=True # Allow HTML in markdown
55
+ )
56
+
57
+ # Configure logging
58
+ logging.basicConfig(level=logging.INFO) # Set logging level to INFO
59
+ logger = logging.getLogger(__name__) # Create a logger
60
+
61
+ UPLOAD_DIR = "uploaded_files" # Directory to store uploaded files
62
+ NVIDIA_API_KEY = "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" # Store API key securely
63
+
64
+ # Create upload directory if it doesn't exist
65
+ if not os.path.exists(UPLOAD_DIR):
66
+ os.makedirs(UPLOAD_DIR) # Create the directory
67
+
68
+ class NVIDIAOCRHandler:
69
+ def __init__(self):
70
+ self.api_key = NVIDIA_API_KEY # Initialize API key
71
+ self.nvai_url = "https://ai.api.nvidia.com/v1/cv/nvidia/ocdrnet" # NVIDIA OCR API URL
72
+ self.headers = {"Authorization": f"Bearer {self.api_key}"} # Set headers for API requests
73
+
74
+ def process_image(self, file_path: str) -> str:
75
+ try:
76
+ with open(file_path, "rb") as image_file: # Open the image file
77
+ files = {'image': image_file} # Prepare file for upload
78
+ response = requests.post(self.nvai_url, headers=self.headers, files=files) # Send POST request
79
+ response.raise_for_status() # Raise an error for bad responses
80
+ result = response.json() # Parse JSON response
81
+ return result.get("text", "") # Return extracted text
82
+ except Exception as e:
83
+ st.error(f"Error processing image: {str(e)}") # Display error message
84
+ return "" # Return empty string on error
85
+
86
+ def save_uploaded_file(uploaded_file):
87
+ file_path = os.path.join(UPLOAD_DIR, uploaded_file.name) # Create file path
88
+ with open(file_path, "wb") as f: # Open file for writing
89
+ f.write(uploaded_file.getbuffer()) # Write uploaded file to disk
90
+ return file_path # Return the file path
91
+
92
+ def upload_asset(input_data: bytes, description: str) -> str:
93
+ try:
94
+ assets_url = "https://api.nvcf.nvidia.com/v2/nvcf/assets" # NVIDIA asset upload URL
95
+ headers = {
96
+ "Authorization": f"Bearer {NVIDIA_API_KEY}", # Set authorization header
97
+ "Content-Type": "application/json", # Set content type
98
+ "accept": "application/json", # Accept JSON response
99
+ }
100
+
101
+ payload = {"contentType": "image/jpeg", "description": description} # Prepare payload for upload
102
+
103
+ response = requests.post(assets_url, headers=headers, json=payload)
104
+ response.raise_for_status()
105
+
106
+ asset_url = response.json()["uploadUrl"]
107
+ asset_id = response.json()["assetId"]
108
+
109
+ response = requests.put(
110
+ asset_url,
111
+ data=input_data,
112
+ headers={"x-amz-meta-nvcf-asset-description": description, "content-type": "image/jpeg"},
113
+ timeout=300,
114
+ )
115
+
116
+ response.raise_for_status()
117
+ return asset_id
118
+ except Exception as e:
119
+ st.error(f"Error uploading asset: {str(e)}")
120
+ return ""
121
+
122
+ def extract_text_pdf(file_path):
123
+ doc = fitz.open(file_path)
124
+ text = ""
125
+ for page in doc:
126
+ text += page.get_text()
127
+ return text
128
+
129
+ def extract_text_word(file_path):
130
+ doc = docx.Document(file_path)
131
+ text = "\n".join([para.text for para in doc.paragraphs])
132
+ return text
133
+
134
+ def compare_texts(text1, text2):
135
+ differ = HtmlDiff()
136
+ return differ.make_file(
137
+ text1.splitlines(), text2.splitlines(),
138
+ fromdesc="Original", todesc="Modified", context=True, numlines=2
139
+ )
140
+
141
+ def calculate_similarity(text1, text2):
142
+ matcher = SequenceMatcher(None, text1, text2)
143
+ return matcher.ratio()
144
+
145
+ logging.basicConfig(
146
+ level=logging.INFO,
147
+ format='%(asctime)s - %(levelname)s: %(message)s'
148
+ )
149
+ logger = logging.getLogger(__name__)
150
+
151
+ class NvidiaDeepfakeDetector:
152
+ def __init__(self):
153
+ """
154
+ Initialize Deepfake Detection with configuration
155
+ """
156
+ self.api_key = f"Bearer NVIDIA_API_KEY"
157
+ self.upload_dir = os.getenv('UPLOAD_DIR', '/tmp')
158
+ self.max_image_size = 5 * 1024 * 1024 # 5MB
159
+ self.invoke_url = "https://ai.api.nvidia.com/v1/cv/hive/deepfake-image-detection"
160
+
161
+ # Validate critical configurations
162
+ self._validate_config()
163
+
164
+ def _validate_config(self):
165
+ """
166
+ Validate critical configuration parameters
167
+ """
168
+ if not self.api_key:
169
+ raise ValueError("NVIDIA API Key is not configured")
170
+
171
+ if not os.path.exists(self.upload_dir):
172
+ os.makedirs(self.upload_dir, exist_ok=True)
173
+
174
+ def validate_image(self, image_bytes: bytes) -> bool:
175
+ """
176
+ Validate image before processing
177
+
178
+ Args:
179
+ image_bytes (bytes): Image data
180
+
181
+ Returns:
182
+ bool: Image validation status
183
+ """
184
+ try:
185
+ # Check image size
186
+ if len(image_bytes) > self.max_image_size:
187
+ st.error(f"Image exceeds maximum size of {self.max_image_size} bytes")
188
+ return False
189
+
190
+ # Try opening image
191
+ Image.open(BytesIO(image_bytes))
192
+ return True
193
+
194
+ except Exception as e:
195
+ st.error(f"Image validation failed: {e}")
196
+ return False
197
+
198
+ def upload_asset(self, path: str, desc: str) -> str:
199
+ """
200
+ Upload asset to NVIDIA's asset management system
201
+
202
+ Args:
203
+ path (str): Image file path
204
+ desc (str): Asset description
205
+
206
+ Returns:
207
+ str: Asset ID
208
+ """
209
+ try:
210
+ assets_url = "https://api.nvcf.nvidia.com/v2/nvcf/assets"
211
+ headers = {
212
+ "Content-Type": "application/json",
213
+ "Authorization": f"Bearer {self.api_key}",
214
+ "accept": "application/json",
215
+ }
216
+
217
+ # Create asset
218
+ payload = {
219
+ "contentType": "image/png",
220
+ "description": desc
221
+ }
222
+
223
+ response = requests.post(assets_url, headers=headers, json=payload, timeout=30)
224
+ response.raise_for_status()
225
+
226
+ upload_url = response.json()["uploadUrl"]
227
+ asset_id = response.json()["assetId"]
228
+
229
+ # Upload image
230
+ with open(path, "rb") as input_data:
231
+ upload_response = requests.put(
232
+ upload_url,
233
+ data=input_data,
234
+ headers={"Content-Type": "image/png"},
235
+ timeout=300
236
+ )
237
+ upload_response.raise_for_status()
238
+
239
+ return asset_id
240
+
241
+ except requests.exceptions.RequestException as e:
242
+ logger.error(f"Asset upload failed: {e}")
243
+ st.error("Failed to upload image asset")
244
+ return ""
245
+ """
246
+ Detect deepfake using NVIDIA API
247
+
248
+ Args:
249
+ image_bytes (bytes): Image data
250
+
251
+ Returns:
252
+ Optional[Dict]: Detection results
253
+ """
254
+ # Validate image
255
+ if not self.validate_image(image_bytes):
256
+ return None
257
+
258
+ try:
259
+ # Temporary image path
260
+ temp_path = os.path.join(self.upload_dir, "temp_deepfake_image.png")
261
+ with open(temp_path, "wb") as f:
262
+ f.write(image_bytes)
263
+
264
+ # Encode image
265
+ image_b64 = base64.b64encode(image_bytes).decode()
266
+
267
+ # Payload preparation
268
+ if len(image_b64) < 180_000:
269
+ payload = {"input": [f"data:image/png;base64,{image_b64}"]}
270
+ headers = {
271
+ "Content-Type": "application/json",
272
+ "Authorization": f"Bearer {self.api_key}",
273
+ "Accept": "application/json",
274
+ }
275
+ else:
276
+ # Large image asset upload
277
+ asset_id = self.upload_asset(temp_path, "Deepfake Detection")
278
+ payload = {"input": [f"data:image/png;asset_id,{asset_id}"]}
279
+ headers = {
280
+ "Content-Type": "application/json",
281
+ "NVCF-INPUT-ASSET-REFERENCES": asset_id,
282
+ "Authorization": f"Bearer {self.api_key}",
283
+ }
284
+
285
+ # API Call
286
+ response = requests.post(self.invoke_url, headers=headers, json=payload)
287
+ response.raise_for_status()
288
+
289
+ # Clean up temporary file
290
+ os.remove(temp_path)
291
+
292
+ return response.json()
293
+
294
+ except requests.exceptions.RequestException as e:
295
+ logger.error(f"Deepfake detection error: {e}")
296
+ st.error("Deepfake detection failed")
297
+ return None
298
+ except Exception as e:
299
+ logger.error(f"Unexpected error: {e}")
300
+ st.error("An unexpected error occurred")
301
+ return None
302
+
303
+ # Streamlit Integration Function
304
+ def nvidia_deepfake_detection_app():
305
+ st.header("πŸ•΅οΈ Deepfake Detection")
306
+
307
+ # Initialize detector
308
+ detector = NvidiaDeepfakeDetector()
309
+
310
+ # File uploader
311
+ uploaded_file = st.file_uploader(
312
+ "Upload an image",
313
+ type=["jpg", "jpeg", "png"],
314
+ key="deepfake_nvidia"
315
+ )
316
+
317
+ if uploaded_file is not None:
318
+ # Read image
319
+ image_bytes = uploaded_file.getvalue()
320
+ image = Image.open(BytesIO(image_bytes))
321
+
322
+ # Layout
323
+ col1, col2 = st.columns([2, 1])
324
+
325
+ with col1:
326
+ st.image(image, caption="Uploaded Image", use_column_width=True)
327
+
328
+ with col2:
329
+ st.write("### Detection Results")
330
+
331
+ # Detect deepfake
332
+ with st.spinner("Analyzing image..."):
333
+ result = detector.detect_deepfake(image_bytes)
334
+
335
+ # Process and display results
336
+ if result and 'data' in result and result['data']: # Check data list too
337
+
338
+ deepfake_data = result['data'][0] # Access the data list inside the 'data' key
339
+ is_deepfake = deepfake_data.get('isDeepfake', False) # Access isDeepfake from deepfake_data
340
+ confidence = deepfake_data.get('confidence', 0.0)
341
+
342
+ with col2:
343
+ # Confidence metrics
344
+ st.metric(
345
+ label="Deepfake Probability",
346
+ value=f"{confidence:.2f}%",
347
+ delta="High Risk" if confidence >= 70 else "Low Risk"
348
+ )
349
+
350
+ # Risk assessment
351
+ if is_deepfake or confidence > 90:
352
+ st.error("🚨 HIGH RISK: Likely a Deepfake")
353
+ elif confidence > 70:
354
+ st.warning("⚠️ MODERATE RISK: Potential Deepfake")
355
+ else:
356
+ st.success("βœ… LOW RISK: Likely Authentic")
357
+ else:
358
+ st.error("Unable to perform deepfake detection")
359
+
360
+ # Main execution
361
+
362
+ def detect_watermark(image, text):
363
+ try:
364
+ gray_image = cv2.cvtColor(np.array(image), cv2.COLOR_RGB2GRAY)
365
+ detected_text = pytesseract.image_to_string(gray_image)
366
+ return text.strip().lower() in detected_text.strip().lower()
367
+ except Exception as e:
368
+ st.error(f"Error in watermark detection: {str(e)}")
369
+ return False
370
+
371
+ def get_metadata(image):
372
+ exif_data = {}
373
+ info = image.getexif()
374
+ if info:
375
+ for tag, value in info.items():
376
+ decoded = ExifTags.TAGS.get(tag, tag)
377
+ exif_data[decoded] = value
378
+ return exif_data
379
+
380
+ def compare_metadata(meta1, meta2):
381
+ keys = set(meta1.keys()).union(set(meta2.keys()))
382
+ data = []
383
+ for key in keys:
384
+ value1 = meta1.get(key, "Not Available")
385
+ value2 = meta2.get(key, "Not Available")
386
+ if value1 != value2:
387
+ data.append({"Metadata Field": key, "Original Image": value1, "Compared Image": value2})
388
+ if data:
389
+ df = pd.DataFrame(data)
390
+ return df
391
+ else:
392
+ return None
393
+
394
+ def detect_deepfake(image):
395
+ try:
396
+ analysis = DeepFace.analyze(img_path=np.array(image), actions=['emotion'], enforce_detection=False)
397
+ if analysis and 'emotion' in analysis:
398
+ return "Real Face Detected", 0.99
399
+ else:
400
+ return "No Face Detected", 0.0
401
+ except Exception as e:
402
+ st.error(f"Error in deepfake detection: {str(e)}")
403
+ return "Error", 0.0
404
+
405
+ def image_comparison_app():
406
+ st.header("πŸ” Image Analysis for Differences")
407
+ st.write("Upload two images to compare them and find differences.")
408
+
409
+ col1, col2 = st.columns(2)
410
+ with col1:
411
+ st.subheader("Original Image")
412
+ uploaded_file1 = st.file_uploader("Choose the original image", type=["png", "jpg", "jpeg"], key="comp1")
413
+
414
+ with col2:
415
+ st.subheader("Image to Compare")
416
+ uploaded_file2 = st.file_uploader("Choose the image to compare", type=["png", "jpg", "jpeg"], key="comp2")
417
+
418
+ if uploaded_file1 and uploaded_file2:
419
+ image1 = Image.open(uploaded_file1)
420
+ image2 = Image.open(uploaded_file2)
421
+
422
+ img1 = cv2.cvtColor(np.array(image1), cv2.COLOR_RGB2BGR)
423
+ img2 = cv2.cvtColor(np.array(image2), cv2.COLOR_RGB2BGR)
424
+
425
+ if img1.shape != img2.shape:
426
+ st.warning("Images are not the same size. Resizing the second image to match the first.")
427
+ img2 = cv2.resize(img2, (img1.shape[1], img1.shape[0]))
428
+
429
+ gray1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
430
+ gray2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
431
+ score, diff = ssim(gray1, gray2, full=True)
432
+ st.write(f"**Structural Similarity Index (SSIM): {score:.4f}**")
433
+ diff = (diff * 255).astype("uint8")
434
+
435
+ thresh = cv2.threshold(diff, 0, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)[1]
436
+ contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
437
+
438
+ img1_diff = img1.copy()
439
+ img2_diff = img2.copy()
440
+
441
+ for cnt in contours:
442
+ x, y, w, h = cv2.boundingRect(cnt)
443
+ cv2.rectangle(img1_diff, (x, y), (x + w, y + h), (0, 0, 255), 2)
444
+ cv2.rectangle(img2_diff, (x, y), (x + w, y + h), (0, 0, 255), 2)
445
+
446
+ img1_display = cv2.cvtColor(img1_diff, cv2.COLOR_BGR2RGB)
447
+ img2_display = cv2.cvtColor(img2_diff, cv2.COLOR_BGR2RGB)
448
+ diff_display = cv2.cvtColor(diff, cv2.COLOR_GRAY2RGB)
449
+ thresh_display = cv2.cvtColor(thresh, cv2.COLOR_GRAY2RGB)
450
+
451
+ st.write("## Results")
452
+ st.write("Differences are highlighted in red boxes.")
453
+ st.image([img1_display, img2_display], caption=["Original Image with Differences", "Compared Image with Differences"], width=300)
454
+ st.write("## Difference Image")
455
+ st.image(diff_display, caption="Difference Image", width=300)
456
+ st.write("## Thresholded Difference Image")
457
+ st.image(thresh_display, caption="Thresholded Difference Image", width=300)
458
+
459
+ else:
460
+ st.info("Please upload both images.")
461
+
462
+ def image_comparison_and_watermarking_app():
463
+ st.header("πŸ’§ Watermark Adding and Detecting")
464
+ st.write("Upload an image to add a watermark, and detect if a watermark is present.")
465
+
466
+ def add_watermark(image, text):
467
+ txt = Image.new('RGBA', image.size, (255, 255, 255, 0))
468
+ draw = ImageDraw.Draw(txt)
469
+
470
+ font_size = max(20, image.size[0] // 20)
471
+ try:
472
+ font = ImageFont.truetype("arial.ttf", font_size)
473
+ except IOError:
474
+ font = ImageFont.load_default() # Fallback if font not found
475
+
476
+ bbox = font.getbbox(text)
477
+ textwidth = bbox[2] - bbox[0]
478
+ textheight = bbox[3] - bbox[1]
479
+
480
+ x = image.size[0] - textwidth - 10
481
+ y = image.size[1] - textheight - 10
482
+
483
+ draw.text((x, y), text, font=font, fill=(255, 255, 255, 128))
484
+ watermarked = Image.alpha_composite(image.convert('RGBA'), txt)
485
+
486
+ return watermarked.convert('RGB')
487
+
488
+ uploaded_file = st.file_uploader("Choose an image", type=["png", "jpg", "jpeg"], key="wm1")
489
+ watermark_text = st.text_input("Enter watermark text:", value="Sample Watermark")
490
+
491
+ if uploaded_file:
492
+ image = Image.open(uploaded_file).convert("RGB")
493
+ st.image(image, caption="Original Image", width=300)
494
+
495
+ st.write("### Watermarked Image")
496
+ watermarked_image = add_watermark(image, watermark_text)
497
+ st.image(watermarked_image, caption="Watermarked Image", width=300)
498
+
499
+ st.write("### Watermark Detection")
500
+ if detect_watermark(watermarked_image, watermark_text):
501
+ st.success("Watermark detected in the image.")
502
+ else:
503
+ st.warning("Watermark not detected in the image.")
504
+
505
+ st.write("### Metadata")
506
+ metadata = get_metadata(image)
507
+ st.write(metadata if metadata else "No metadata available.")
508
+
509
+ else:
510
+ st.info("Please upload an image.")
511
+
512
+ def process_deepfake_detection_nvidia(image_bytes):
513
+ header_auth = f"Bearer {NVIDIA_API_KEY}"
514
+ invoke_url = "https://ai.api.nvidia.com/v1/cv/hive/deepfake-image-detection"
515
+
516
+ try:
517
+ if image_bytes is not None:
518
+ image_b64 = base64.b64encode(image_bytes).decode()
519
+ payload = {"input": [f"data:image/jpeg;base64,{image_b64}"]}
520
+ headers = {
521
+ "Content-Type": "application/json",
522
+ "Authorization": header_auth,
523
+ "Accept": "application/json",
524
+ }
525
+
526
+ response = requests.post(invoke_url, headers=headers, json= payload)
527
+ response.raise_for_status()
528
+ response_json = response.json()
529
+ return response_json # Return the result
530
+ except requests.exceptions.RequestException as e:
531
+ st.error(f"Error with NVIDIA API: {e}")
532
+ return None
533
+
534
+ def nvidia_deepfake_detection_app():
535
+ st.header("NVIDIA Deepfake Detection")
536
+ uploaded_file = st.file_uploader("Choose an image...", type=["jpg", "jpeg", "png"], key="deepfake_nvidia")
537
+
538
+ if uploaded_file is not None:
539
+ image_bytes = uploaded_file.getvalue()
540
+ image = Image.open(BytesIO(image_bytes))
541
+ st.image(image, caption="Uploaded Image", use_column_width=True)
542
+
543
+ col1, col2 = st.columns([2, 1])
544
+
545
+ with col1:
546
+ # Display original image
547
+ st.image(image, caption="Uploaded Image", use_column_width=True)
548
+
549
+ with col2:
550
+ # Placeholder for detection results
551
+ st.write("### Detection Results")
552
+
553
+ # Perform deepfake detection
554
+ with st.spinner("Analyzing image for deepfake..."):
555
+ result = process_deepfake_detection_nvidia(image_bytes)
556
+
557
+ if result and 'data' in result and result['data']:
558
+ deepfake_data = result['data'][0]
559
+
560
+ # Deepfake confidence
561
+ is_deepfake = deepfake_data.get('isDeepfake', 0)
562
+ deepfake_confidence = is_deepfake * 100
563
+
564
+ # Face detection confidence
565
+ face_confidence = deepfake_data.get('confidence', 0) * 100
566
+
567
+ # Update the second column with detailed results
568
+ with col2:
569
+ # Deepfake Probability Card
570
+ st.markdown("""
571
+ <div style="background-color:#f0f2f6;padding:20px;border-radius:10px;">
572
+ <h3 style="color:#333;margin-bottom:15px;">Deepfake Analysis</h3>
573
+ """, unsafe_allow_html=True)
574
+
575
+ # Deepfake Confidence Metric
576
+ st.metric(
577
+ label="Deepfake Probability",
578
+ value=f"{deepfake_confidence:.1f}%",
579
+ delta="High Risk" if deepfake_confidence > 70 else "Low Risk"
580
+ )
581
+
582
+ # Face Detection Confidence Metric
583
+ st.metric(
584
+ label="Face Detection Confidence",
585
+ value=f"{face_confidence:.1f}%"
586
+ )
587
+
588
+ # Risk Assessment
589
+ if deepfake_confidence > 90:
590
+ st.error("🚨 HIGH RISK: Likely a Deepfake")
591
+ elif deepfake_confidence > 70:
592
+ st.warning("⚠️ MODERATE RISK: Potential Deepfake")
593
+ else:
594
+ st.success("βœ… LOW RISK: Likely Authentic")
595
+
596
+ st.markdown("</div>", unsafe_allow_html=True)
597
+
598
+ # Detailed Explanation
599
+ st.markdown("### Detailed Analysis")
600
+
601
+ # Create expandable sections for more information
602
+ with st.expander("Deepfake Detection Explanation"):
603
+ st.write("""
604
+ - **Deepfake Probability**: Indicates the likelihood of the image being artificially generated.
605
+ - **Face Detection Confidence**: Measures the model's confidence in detecting a face in the image.
606
+ - High probabilities suggest potential manipulation.
607
+ """)
608
+
609
+ # Raw JSON for technical users
610
+ with st.expander("Technical Details"):
611
+ if result:
612
+ st.json(result)
613
+
614
+ else:
615
+ st.error("Unable to perform deepfake detection. Please try another image.")
616
+
617
+ else:
618
+ st.info("Please upload an image to perform deepfake detection.")
619
+
620
+
621
+ def document_comparison_tool():
622
+ st.header("πŸ“„ Document In-Depth Comparison")
623
+ st.markdown("Compare documents and detect changes with OCR highlighting.")
624
+
625
+ col1, col2 = st.columns(2)
626
+
627
+ with col1:
628
+ st.markdown("### Original Document")
629
+ original_file = st.file_uploader(
630
+ "Upload original document",
631
+ type=["pdf", "docx", "jpg", "jpeg", "png"],
632
+ key='doc_original_file',
633
+ help="Supported formats: PDF, DOCX, JPG, PNG"
634
+ )
635
+
636
+ with col2:
637
+ st.markdown("### Modified Document")
638
+ modified_file = st.file_uploader(
639
+ "Upload modified document",
640
+ type=["pdf", "docx", "jpg", "jpeg", "png"],
641
+ key='doc_modified_file',
642
+ help="Supported formats: PDF, DOCX, JPG, PNG"
643
+ )
644
+
645
+ if original_file and modified_file:
646
+ ocr_handler = NVIDIAOCRHandler()
647
+
648
+ original_file_path = save_uploaded_file(original_file)
649
+ modified_file_path = save_uploaded_file(modified_file)
650
+
651
+ original_ext = os.path.splitext(original_file.name)[1].lower()
652
+ modified_ext = os.path.splitext(modified_file.name)[1].lower()
653
+
654
+ if original_ext in ['.jpg', '.jpeg', '.png']:
655
+ original_text = ocr_handler.process_image(original_file_path)
656
+ elif original_ext == '.pdf':
657
+ original_text = extract_text_pdf(original_file_path)
658
+ else:
659
+ original_text = extract_text_word(original_file_path)
660
+
661
+ if modified_ext in ['.jpg', '.jpeg', '.png']:
662
+ modified_text = ocr_handler.process_image(modified_file_path)
663
+ elif modified_ext == '.pdf':
664
+ modified_text = extract_text_pdf(modified_file_path)
665
+ else:
666
+ modified_text = extract_text_word(modified_file_path)
667
+
668
+ similarity_score = calculate_similarity(original_text, modified_text)
669
+
670
+ st.markdown("### πŸ“Š Analysis Results")
671
+ metrics_col1, metrics_col2 = st.columns(2)
672
+ with metrics_col1:
673
+ st.metric("Similarity Score", f"{similarity_score:.2%}")
674
+ with metrics_col2:
675
+ st.metric("Changes Detected", "Yes" if similarity_score < 1 else "No")
676
+
677
+ st.markdown("### πŸ” Detailed Comparison")
678
+ diff_html = compare_texts(original_text, modified_text)
679
+ st.components.v1.html(diff_html, height=600, scrolling=True)
680
+
681
+ st.markdown("### πŸ’Ύ Download Results")
682
+ if st.button("Generate Report"):
683
+ st.success("Report generated successfully!")
684
+ st.download_button(
685
+ label="Download Report",
686
+ data=diff_html,
687
+ file_name="comparison_report.html",
688
+ mime="text/html"
689
+ )
690
+
691
+ else:
692
+ st.info("Please upload both documents to begin comparison.")
693
+
694
+ def main():
695
+ st.write("""
696
+ Welcome to the Centurion Analysis Tool! Use the tabs below to navigate through the different functionalities.
697
+ """)
698
+
699
+ tabs = st.tabs([
700
+ "Image Comparison",
701
+ "Watermark Adding & Detecting",
702
+ "Deepfake Detection (NVIDIA)",
703
+ "Document Comparison Tool"
704
+ ])
705
+
706
+ with tabs[0]:
707
+ image_comparison_app()
708
+
709
+ with tabs[1]:
710
+ image_comparison_and_watermarking_app()
711
+
712
+ with tabs[2]:
713
+ nvidia_deepfake_detection_app()
714
+
715
+ with tabs[3]:
716
+ document_comparison_tool()
717
+
718
+ if __name__ == "__main__":
719
+ main()