Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ build/

# Virtual environments
venv/
env/
.env/
ENV/

# IDE files
Expand All @@ -26,7 +26,7 @@ data/NC16/
data
# Uploaded images
website/static/uploads/

node_modules/
# Large model files
*.pt
*.pth
Expand Down
77 changes: 42 additions & 35 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,48 +1,55 @@
### Base image for Python backend
FROM python:3.9 AS backend
# Dockerfile (single container serving both backend & frontend)
FROM ubuntu:20.04

# Set working directory
WORKDIR /app

# Copy and install dependencies
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# Copy the entire project
COPY . .

# Expose the backend port
EXPOSE 5000
# Avoid interactive prompts during package installation
ENV DEBIAN_FRONTEND=noninteractive

# Command to run backend
CMD ["python", "backend/app.py"]
# Update packages and install Python 3.8, pip, curl, and other dependencies
RUN apt-get update && apt-get install -y \
python3.8 \
python3-pip \
curl \
&& rm -rf /var/lib/apt/lists/*

### Base image for Node.js frontend
FROM node:18 AS frontend
# Install Node 18.x from NodeSource
RUN curl -fsSL https://deb.nodesource.com/setup_18.x | bash - \
&& apt-get install -y nodejs

# Set working directory
WORKDIR /frontend
# Set the working directory
WORKDIR /app

# Copy frontend code
COPY react-frontend/ ./
# Copy the entire project into the container
COPY . /app

# Install dependencies and build
# -------------------------
# Build the frontend (production build)
# -------------------------
WORKDIR /app/frontend
RUN npm install && npm run build

### Final production image
FROM python:3.9
# -------------------------
# Prepare Flask to serve the built frontend
# -------------------------
# Create directories if they don't exist
RUN mkdir -p /app/backend/templates && mkdir -p /app/backend/static

# Set working directory
WORKDIR /app
# Copy the built index.html into the Flask templates folder
RUN cp /app/frontend/dist/index.html /app/backend/templates/index.html

# Copy all static assets into the Flask static folder
RUN cp -r /app/frontend/dist/assets /app/backend/static/

# Copy backend and trained models from backend stage
COPY --from=backend /app /app
# -------------------------
# Setup backend
# -------------------------
WORKDIR /app/backend
RUN pip3 install --upgrade pip && pip3 install -r requirements.txt

# Copy built frontend from frontend stage
COPY --from=frontend /frontend/dist /app/backend/static
# Make sure Flask uses the PORT environment variable (default to 5000)
ENV PORT 5000

# Expose the backend port
EXPOSE 5000
# Expose the port that Render will use
EXPOSE $PORT

# Command to run the application
CMD ["python", "backend/app.py"]
# Start the Flask server
CMD ["python3.8", "app.py"]
63 changes: 36 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,33 +5,42 @@ This project implements image forgery detection using Convolutional Neural Netwo
## Project Structure

```
├── configs/ # Configuration files
│ └── model_config.py # Model parameters and settings
├── data/ # Data directory
│ ├── raw/ # Original, immutable data
│ ├── processed/ # Cleaned and processed data ready for modeling
│ ├── interim/ # Intermediate data
│ └── external/ # External data sources
├── docs/ # Documentation
│ ├── images/ # Images for documentation
│ └── plots/ # Generated plots and visualizations
├── models/ # Model implementations
│ └── weights/ # Saved model weights
├── scripts/ # Utility scripts
│ ├── minimal_demo.py # Minimal demo script
│ ├── run_improved_model.py # Improved model runner
│ └── ... # Other scripts
├── tests/ # Tests
│ ├── test_models.py # Model tests
│ └── generate_test_report.py # Test report generator
├── utils/ # Utility functions
│ ├── common.py # Common utility functions
│ ├── feature_extraction.py # Feature extraction utilities
│ └── extract_patches.py # Image patch extraction utilities
├── backend/ # Backend server implementation
│ └── app.py # Flask API
└── react-frontend/ # React frontend application
└── src/ # Frontend source code
Image-Forgery-Detection-CNN-Updated/
├── .github/
│ └── workflows/ # GitHub Actions workflow files
├── Documents/ # Supplementary documents
├── backend/ # Backend server implementation
│ └── app.py # Flask API entry point
├── configs/ # Configuration files
│ └── model_config.py # Model parameters and settings
├── data/ # Data directory
│ ├── raw/ # Original, immutable data
│ ├── processed/ # Cleaned and processed data ready for modeling
│ ├── interim/ # Intermediate data
│ └── external/ # External data sources
├── docs/ # Project documentation
│ ├── images/ # Documentation images
│ └── plots/ # Generated plots and visualizations
├── frontend/ # React frontend application
│ └── src/ # Frontend source code
├── models/ # Model implementations
│ └── weights/ # Saved model weights
├── reports/ # Test reports and analysis outputs
├── scripts/ # Utility scripts
│ ├── minimal_demo.py # Minimal demo script
│ ├── run_improved_model.py # Script to run the improved model
│ └── ... # Other supporting scripts
├── tests/ # Test suites
│ ├── test_models.py # Model test cases
│ └── generate_test_report.py # Test report generator
├── utils/ # Utility functions and helpers
│ ├── common.py # Common utility functions
│ ├── feature_extraction.py # Feature extraction utilities
│ └── extract_patches.py # Image patch extraction utilities
├── .gitignore # Git ignore file
├── Dockerfile # Docker build configuration
├── README.md # Project overview and instructions
└── requirements.txt # Python dependency list
```

## Installation
Expand Down
29 changes: 29 additions & 0 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Docker
# Build a Docker image
# https://docs.microsoft.com/azure/devops/pipelines/languages/docker

trigger:
- main

resources:
- repo: self

variables:
tag: '$(Build.BuildId)'

stages:
- stage: Build
displayName: Build image
jobs:
- job: Build
displayName: Build
pool:
vmImage: ubuntu-latest
steps:
- task: Docker@2
displayName: Build an image
inputs:
command: build
dockerfile: '$(Build.SourcesDirectory)/Dockerfile'
tags: |
$(tag)
23 changes: 15 additions & 8 deletions backend/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,11 @@
from models.cnn import CNN
from utils.feature_vector_generation import get_patch_yi

app = Flask(__name__, static_url_path='/static', static_folder='static')
app = Flask(__name__, static_folder='static', static_url_path='/static')
# Enable CORS for all routes
CORS(app, resources={r"/*": {"origins": "*", "supports_credentials": True}})
app.config['UPLOAD_FOLDER'] = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'static', 'uploads')
#app.config['UPLOAD_FOLDER'] = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'static', 'uploads')
app.config['UPLOAD_FOLDER'] = os.path.join(app.root_path, 'static/uploads')
app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024 # 16MB max upload size

# Create upload folder if it doesn't exist
Expand Down Expand Up @@ -496,13 +497,19 @@ def localize_tampering(image_path, model, patch_size=64, stride=16, localization
traceback.print_exc()
return {}

@app.route('/')
def index():
# @app.route('/')
# def index():
# return render_template('index.html')
@app.route('/', defaults={'path': ''})
@app.route('/<path:path>')
def catch_all(path):
# Optionally, you can log the requested path for debugging
print(f"Catch-all route reached with path: {path}")
return render_template('index.html')

@app.route('/about')
def about():
return render_template('about.html')
# @app.route('/about')
# def about():
# return render_template('about.html')

@app.route('/api/analyze', methods=['POST'])
def api_analyze():
Expand Down Expand Up @@ -1418,4 +1425,4 @@ def api_analyze_ensemble():
return jsonify({'error': 'Invalid file type'}), 400

if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0', port=5000)
app.run(debug=True, host='0.0.0.0', port=5000)
26 changes: 22 additions & 4 deletions backend/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,12 +1,30 @@
flask==2.3.3
werkzeug==2.3.7
torch==1.8.1
torchvision==0.9.1
joblib==1.0.0
scikit-image==0.18.1
opencv-python==4.5.1.48
opencv-python-headless==4.11.0.86 # Replaced opencv-python with headless version
cycler==0.10.0
graphviz==0.16
imbalanced-learn==0.8.0
imblearn==0.0
kiwisolver==1.3.1
matplotlib==3.3.3
numpy==1.22.4
pandas==1.5.3
pyparsing==2.4.7
python-dateutil==2.8.1
pytz==2020.5
scikit-learn==0.24.1
scipy==1.6.0
seaborn==0.11.1
six==1.15.0
xgboost==1.5.0
tqdm==4.62.3
efficientnet-pytorch==0.7.1
albumentations==1.1.0
tensorboard==2.8.0
flask==2.3.3
flask_cors
werkzeug==2.3.7
pillow==9.5.0
gunicorn==21.2.0
gunicorn==21.2.0
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 13 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
version: '3.8'

services:
app:
build: .
ports:
- "5000:5000"
environment:
- PORT=5000
restart: always
volumes:
- .:/app
command: ["gunicorn", "-w", "4", "-b", "0.0.0.0:5000", "app:app"]
4 changes: 2 additions & 2 deletions frontend/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<link rel="icon" type="image/svg+xml" href="/frontend/public/favicon.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + React</title>
<title>ForgeDetect</title>
</head>
<body>
<div id="root"></div>
Expand Down
Loading