SanyaAhmed commited on
Commit
b1fc48a
·
verified ·
1 Parent(s): 3ff2242

Upload 7 files

Browse files
Files changed (7) hide show
  1. .gitattributes +1 -35
  2. .gitignore +161 -0
  3. app.py +83 -0
  4. function.py +124 -0
  5. model.pt +3 -0
  6. packages.txt +1 -0
  7. requirements.txt +8 -0
.gitattributes CHANGED
@@ -1,35 +1 @@
1
- *.7z filter=lfs diff=lfs merge=lfs -text
2
- *.arrow filter=lfs diff=lfs merge=lfs -text
3
- *.bin filter=lfs diff=lfs merge=lfs -text
4
- *.bz2 filter=lfs diff=lfs merge=lfs -text
5
- *.ckpt filter=lfs diff=lfs merge=lfs -text
6
- *.ftz filter=lfs diff=lfs merge=lfs -text
7
- *.gz filter=lfs diff=lfs merge=lfs -text
8
- *.h5 filter=lfs diff=lfs merge=lfs -text
9
- *.joblib filter=lfs diff=lfs merge=lfs -text
10
- *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
- *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
- *.model filter=lfs diff=lfs merge=lfs -text
13
- *.msgpack filter=lfs diff=lfs merge=lfs -text
14
- *.npy filter=lfs diff=lfs merge=lfs -text
15
- *.npz filter=lfs diff=lfs merge=lfs -text
16
- *.onnx filter=lfs diff=lfs merge=lfs -text
17
- *.ot filter=lfs diff=lfs merge=lfs -text
18
- *.parquet filter=lfs diff=lfs merge=lfs -text
19
- *.pb filter=lfs diff=lfs merge=lfs -text
20
- *.pickle filter=lfs diff=lfs merge=lfs -text
21
- *.pkl filter=lfs diff=lfs merge=lfs -text
22
- *.pt filter=lfs diff=lfs merge=lfs -text
23
- *.pth filter=lfs diff=lfs merge=lfs -text
24
- *.rar filter=lfs diff=lfs merge=lfs -text
25
- *.safetensors filter=lfs diff=lfs merge=lfs -text
26
- saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
- *.tar.* filter=lfs diff=lfs merge=lfs -text
28
- *.tar filter=lfs diff=lfs merge=lfs -text
29
- *.tflite filter=lfs diff=lfs merge=lfs -text
30
- *.tgz filter=lfs diff=lfs merge=lfs -text
31
- *.wasm filter=lfs diff=lfs merge=lfs -text
32
- *.xz filter=lfs diff=lfs merge=lfs -text
33
- *.zip filter=lfs diff=lfs merge=lfs -text
34
- *.zst filter=lfs diff=lfs merge=lfs -text
35
- *tfevents* filter=lfs diff=lfs merge=lfs -text
 
1
+ *.pt filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
.gitignore ADDED
@@ -0,0 +1,161 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.pt
6
+
7
+ # C extensions
8
+ *.so
9
+
10
+ # Distribution / packaging
11
+ .Python
12
+ build/
13
+ develop-eggs/
14
+ dist/
15
+ downloads/
16
+ eggs/
17
+ .eggs/
18
+ lib/
19
+ lib64/
20
+ parts/
21
+ sdist/
22
+ var/
23
+ wheels/
24
+ share/python-wheels/
25
+ *.egg-info/
26
+ .installed.cfg
27
+ *.egg
28
+ MANIFEST
29
+
30
+ # PyInstaller
31
+ # Usually these files are written by a python script from a template
32
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
33
+ *.manifest
34
+ *.spec
35
+
36
+ # Installer logs
37
+ pip-log.txt
38
+ pip-delete-this-directory.txt
39
+
40
+ # Unit test / coverage reports
41
+ htmlcov/
42
+ .tox/
43
+ .nox/
44
+ .coverage
45
+ .coverage.*
46
+ .cache
47
+ nosetests.xml
48
+ coverage.xml
49
+ *.cover
50
+ *.py,cover
51
+ .hypothesis/
52
+ .pytest_cache/
53
+ cover/
54
+
55
+ # Translations
56
+ *.mo
57
+ *.pot
58
+
59
+ # Django stuff:
60
+ *.log
61
+ local_settings.py
62
+ db.sqlite3
63
+ db.sqlite3-journal
64
+
65
+ # Flask stuff:
66
+ instance/
67
+ .webassets-cache
68
+
69
+ # Scrapy stuff:
70
+ .scrapy
71
+
72
+ # Sphinx documentation
73
+ docs/_build/
74
+
75
+ # PyBuilder
76
+ .pybuilder/
77
+ target/
78
+
79
+ # Jupyter Notebook
80
+ .ipynb_checkpoints
81
+
82
+ # IPython
83
+ profile_default/
84
+ ipython_config.py
85
+
86
+ # pyenv
87
+ # For a library or package, you might want to ignore these files since the code is
88
+ # intended to run in multiple environments; otherwise, check them in:
89
+ # .python-version
90
+
91
+ # pipenv
92
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
93
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
94
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
95
+ # install all needed dependencies.
96
+ #Pipfile.lock
97
+
98
+ # poetry
99
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
100
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
101
+ # commonly ignored for libraries.
102
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
103
+ #poetry.lock
104
+
105
+ # pdm
106
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
107
+ #pdm.lock
108
+ # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
109
+ # in version control.
110
+ # https://pdm.fming.dev/#use-with-ide
111
+ .pdm.toml
112
+
113
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
114
+ __pypackages__/
115
+
116
+ # Celery stuff
117
+ celerybeat-schedule
118
+ celerybeat.pid
119
+
120
+ # SageMath parsed files
121
+ *.sage.py
122
+
123
+ # Environments
124
+ .env
125
+ .venv
126
+ env/
127
+ venv/
128
+ ENV/
129
+ env.bak/
130
+ venv.bak/
131
+
132
+ # Spyder project settings
133
+ .spyderproject
134
+ .spyproject
135
+
136
+ # Rope project settings
137
+ .ropeproject
138
+
139
+ # mkdocs documentation
140
+ /site
141
+
142
+ # mypy
143
+ .mypy_cache/
144
+ .dmypy.json
145
+ dmypy.json
146
+
147
+ # Pyre type checker
148
+ .pyre/
149
+
150
+ # pytype static type analyzer
151
+ .pytype/
152
+
153
+ # Cython debug symbols
154
+ cython_debug/
155
+
156
+ # PyCharm
157
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
158
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
159
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
160
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
161
+ .idea
app.py ADDED
@@ -0,0 +1,83 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import torch
3
+ import torchvision.transforms as transforms
4
+ # from torch import nn
5
+ # import cv2
6
+ # import numpy as np
7
+ # import torch
8
+ # import torchvision
9
+ # from torchvision import models, transforms
10
+ # from torch.utils.data import DataLoader
11
+ # from torch.utils.data.dataset import Dataset
12
+ # import os
13
+ # import matplotlib.pyplot as plt
14
+ # import face_recognition
15
+ # import sys
16
+ # import time
17
+ # from torch.autograd import Variable
18
+ from function import Model, validation_dataset, predict
19
+
20
+ # Set Streamlit page config
21
+ st.set_page_config(
22
+ page_title="DeepFake Detection",
23
+ layout="centered",
24
+ page_icon=":mask:"
25
+ )
26
+
27
+ # Load the pre-trained model
28
+ @st.cache_resource
29
+ def load_model():
30
+ model = Model(num_classes=2).cuda()
31
+ model_path = "model.pt" # Update with actual model path
32
+ model.load_state_dict(torch.load(model_path))
33
+ model.eval()
34
+ return model
35
+
36
+ model = load_model()
37
+
38
+ st.title("DeepFake Detection App")
39
+ st.divider()
40
+ st.sidebar.header("Upload Video")
41
+ uploaded_video = st.sidebar.file_uploader("Choose a video file", type=["mp4", "avi", "mov"])
42
+
43
+ if uploaded_video:
44
+ st.sidebar.write("Video uploaded successfully!")
45
+
46
+ # Save the uploaded video locally for processing
47
+ with open("uploaded_video.mp4", "wb") as f:
48
+ f.write(uploaded_video.getbuffer())
49
+
50
+ st.video("uploaded_video.mp4")
51
+
52
+ # Preprocess and analyze the video
53
+ with st.spinner("Processing video..."):
54
+
55
+ try:
56
+ # Validation dataset
57
+ video_dataset = validation_dataset(
58
+ video_names=["uploaded_video.mp4"],
59
+ sequence_length=20,
60
+ transform=transforms.Compose([
61
+ transforms.ToPILImage(),
62
+ transforms.Resize((112, 112)),
63
+ transforms.ToTensor(),
64
+ transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
65
+ ])
66
+ )
67
+
68
+ video_frames = video_dataset[0] # Extract frames from video
69
+ if video_frames is not None:
70
+ prediction = predict(model, video_frames)
71
+ st.subheader("Prediction: ")
72
+ st.write(f"{'REAL' if prediction[0] == 1 else 'FAKE'}")
73
+
74
+ st.subheader("Confidence: ")
75
+ st.write(f"{prediction[1]:.2f}%")
76
+ else:
77
+ st.error("No faces detected in the video.")
78
+
79
+ except Exception as e:
80
+ st.error(f"An error occurred during processing: {e}")
81
+
82
+ else:
83
+ st.sidebar.write("Upload a video file.")
function.py ADDED
@@ -0,0 +1,124 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ import torchvision
3
+ from torchvision import models, transforms
4
+ from torch.utils.data import DataLoader
5
+ from torch.utils.data.dataset import Dataset
6
+ import os
7
+ import numpy as np
8
+ import matplotlib.pyplot as plt
9
+ import cv2
10
+ import face_recognition
11
+ import sys
12
+ import time
13
+ from torch.autograd import Variable
14
+ from torch import nn
15
+
16
+ class Model(nn.Module):
17
+ def __init__(self, num_classes, latent_dim=2048, lstm_layers=1, hidden_dim=2048, bidirectional=False):
18
+ super(Model, self).__init__()
19
+ model = models.resnext50_32x4d(pretrained=True)
20
+ self.model = nn.Sequential(*list(model.children())[:-2])
21
+ self.lstm = nn.LSTM(latent_dim, hidden_dim, lstm_layers, bidirectional)
22
+ self.relu = nn.LeakyReLU()
23
+ self.dp = nn.Dropout(0.4)
24
+ self.linear1 = nn.Linear(2048, num_classes)
25
+ self.avgpool = nn.AdaptiveAvgPool2d(1)
26
+
27
+ def forward(self, x):
28
+ batch_size, seq_length, c, h, w = x.shape
29
+ x = x.view(batch_size * seq_length, c, h, w)
30
+ fmap = self.model(x)
31
+ x = self.avgpool(fmap)
32
+ x = x.view(batch_size, seq_length, 2048)
33
+ x_lstm, _ = self.lstm(x, None)
34
+ return fmap, self.dp(self.linear1(x_lstm[:, -1, :]))
35
+
36
+ im_size = 112
37
+ mean = [0.485, 0.456, 0.406]
38
+ std = [0.229, 0.224, 0.225]
39
+ sm = nn.Softmax()
40
+ inv_normalize = transforms.Normalize(mean=-1*np.divide(mean, std), std=np.divide([1,1,1], std))
41
+
42
+ def im_convert(tensor):
43
+ image = tensor.to('cpu').clone().detach()
44
+ image = image.squeeze()
45
+ image = inv_normalize(image)
46
+ image = image.numpy()
47
+ image = image.transpose(1, 2, 0)
48
+ image = image.clip(0, 1)
49
+ cv2.imwrite('./2.png', image*255)
50
+ return image
51
+
52
+ def predict(model, img, path = './'):
53
+ fmap, logits = model(img.to('cuda'))
54
+ params = list(model.parameters())
55
+ weight_softmax = model.linear1.weight.detach().cpu().numpy()
56
+ logits = sm(logits)
57
+ _, prediction = torch.max(logits,1)
58
+ confidence = logits[:, int(prediction.item())].item()*100
59
+ print('confidence of prediction', logits[:, int(prediction.item())].item()*100)
60
+ idx = np.argmax(logits.detach().cpu().numpy())
61
+ bz, nc, h, w = fmap.shape
62
+ out = np.dot(fmap[-1].detach().cpu().numpy().reshape((nc, h*w)).T, weight_softmax[idx, :].T)
63
+ predict = out.reshape(h, w)
64
+ predict = predict - np.min(predict)
65
+ predict_img = predict / np.max(predict)
66
+ predict_img = np.uint8(255*predict_img)
67
+ out = cv2.resize(predict_img, (im_size, im_size))
68
+ heatmap = cv2.applyColorMap(out, cv2.COLORMAP_JET)
69
+ img = im_convert(img[:, -1, :, :, :])
70
+ result = heatmap * 0.5 + img*0.8*255
71
+ cv2.imwrite('./1.png', result)
72
+ result1 = heatmap * 0.5/255 + img*0.8
73
+ r, g, b = cv2.split(result1)
74
+ result1 = cv2.merge((r, g, b))
75
+ plt.imshow(result1)
76
+ plt.show()
77
+ return [int(prediction.item()), confidence]
78
+
79
+ class validation_dataset(Dataset):
80
+ def __init__(self, video_names, sequence_length = 60, transform = None):
81
+ self.video_names = video_names
82
+ self.transform = transform
83
+ self.count = sequence_length
84
+ def __len__(self):
85
+ return len(self.video_names)
86
+ def __getitem__(self, idx):
87
+ video_path = self.video_names[idx]
88
+ frames = []
89
+ a = int(100/self.count)
90
+ first_frame = np.random.randint(0, a)
91
+ for i, frame in enumerate(self.frame_extract(video_path)):
92
+ faces = face_recognition.face_locations(frame)
93
+ try:
94
+ top, right, bottom, left = faces[0]
95
+ frame = frame[top:bottom, left:right, :]
96
+ except:
97
+ pass
98
+ if self.transform:
99
+ frames.append(self.transform(frame))
100
+ if(len(frames) == self.count):
101
+ break
102
+ if len(frames)==0:
103
+ print('no face found in the video')
104
+ return None
105
+ frames = torch.stack(frames)
106
+ frames = frames[:self.count]
107
+ return frames.unsqueeze(0)
108
+
109
+ def frame_extract(self, path):
110
+ vidObj = cv2.VideoCapture(path)
111
+ success = 1
112
+ while success:
113
+ success, image = vidObj.read()
114
+ if success:
115
+ yield image
116
+
117
+ def im_plot(tensor):
118
+ image = tensor.cpu().numpy().transpose(1,2,0)
119
+ b,g,r = cv2.split(image)
120
+ image = cv2.merge((r,g,b))
121
+ image = image*[0.22803, 0.22145, 0.216989] + [0.43216, 0.394666, 0.37645]
122
+ image = image*255.0
123
+ plt.imshow(image.astype(int))
124
+ plt.show()
model.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:bd1697b63ea963756fc603c33bbc27772d07548ce51e395b01b1bbdf7bcfe3f2
3
+ size 226547517
packages.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ cmake
requirements.txt ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ torch==2.5.1
2
+ torchvision==0.20.1
3
+ opencv-python
4
+ face_recognition
5
+ streamlit
6
+ matplotlib
7
+ numpy
8
+