Skip to content

Commit

Permalink
add shebang, change argparse, add pre-commit-hooks (tfaehse#10)
Browse files Browse the repository at this point in the history
* add pre commit hooks, make cli.py executable add shebang

* changing argparse

* add ffmpeg flag for sperical video, remove added .pt extension if it exists twice

* change isort config to multi_line_output=5, remove imported but unused

* add shebang to main, signal
  • Loading branch information
joshinils authored and tfaehse committed Jul 24, 2022
1 parent 8eaf3cd commit 06666cb
Show file tree
Hide file tree
Showing 15 changed files with 122 additions and 76 deletions.
5 changes: 5 additions & 0 deletions .flake8
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[flake8]
max_line_length=300
in-place = true
ignore=W503, # ignore old opposite of W504
E266, #####
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
__pycache__
*.log
.vscode
Empty file removed .gitmodules
Empty file.
3 changes: 3 additions & 0 deletions .isort.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[settings]
multi_line_output=5
overwrite_in_place=true
3 changes: 3 additions & 0 deletions .pep8
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[pycodestyle]
max_line_length=300
in-place = true
32 changes: 32 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# See https://pre-commit.com for more information
# See https://pre-commit.com/hooks.html for more hooks
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.1.0
hooks:
- id: trailing-whitespace
- id: check-yaml
- id: check-added-large-files
- id: check-ast
- id: check-case-conflict
- id: check-docstring-first
- id: check-executables-have-shebangs
- id: check-json
- id: check-shebang-scripts-are-executable
- id: check-merge-conflict
- id: check-xml
- id: mixed-line-ending
- id: requirements-txt-fixer
- repo: https://github.com/PyCQA/flake8
rev: '4.0.1'
hooks:
- id: flake8
- repo: https://github.com/pycqa/isort
rev: '5.10.1'
hooks:
- id: isort
name: isort
# - repo: https://github.com/pre-commit/mirrors-mypy
# rev: 'v0.931' # Use the sha / tag you want to point at
# hooks:
# - id: mypy
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
<!-- ABOUT THE PROJECT -->
## About The Project

This project is a result of data protection laws that require identifiable information to be censored in media that is posted to the internet. Dashcam videos in particular tend to be fairly cumbersome to manually edit, so this tool aims to automate the task.
This project is a result of data protection laws that require identifiable information to be censored in media that is posted to the internet. Dashcam videos in particular tend to be fairly cumbersome to manually edit, so this tool aims to automate the task.

The goal is to release a simple to use application with simple settings and acceptable performance that does not require any knowledge about image processing, neural networks or even programming as a whole on the end user's part.

Expand Down
41 changes: 23 additions & 18 deletions dashcamcleaner/cli.py
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
import inspect
import os
import sys
from glob import glob
#!/usr/bin/env python3

import signal
from argparse import ArgumentParser
from tqdm import tqdm

from src.blurrer import VideoBlurrer

# makes it possible to interrupt while running in other thread
signal.signal(signal.SIGINT, signal.SIG_DFL)


class CLI():

def __init__(self, opt):
"""
Constructor
"""
self.opt = opt
self.blurrer = None

Expand Down Expand Up @@ -48,19 +47,25 @@ def start_blurring(self):
else:
print("Blurring resulted in errors.")


def parse_arguments():
parser = ArgumentParser()
parser.add_argument("input", help="input video file path", type=str)
parser.add_argument("output", help="output video file path", type=str)
parser.add_argument("weights", help="weights file name", type=str)
parser.add_argument("inference_size", help="vertical inference size, e.g. 1080 or fHD", type=int)
parser.add_argument("threshold", help="detection threshold", type=float)
parser.add_argument("blur_size", help="granularitay of the blurring filter", type=int)
parser.add_argument("frame_memory", help="blur objects in the last x frames too", type=int)
parser.add_argument("roi_multi", help="increase/decrease area that will be blurred - 1 means no change", type=float)
parser.add_argument("quality", help="quality of the resulting video", type=int)
parser = ArgumentParser(description=" This tool allows you to automatically censor faces and number plates on dashcam footage.")

required_named = parser.add_argument_group('required named arguments')

required_named.add_argument("-i", "--input", metavar="INPUT_PATH", required=True, help="input video file path", type=str)
required_named.add_argument("-o", "--output", metavar="OUTPUT_NAME", required=True, help="output video file path", type=str)
required_named.add_argument("-w", "--weights", metavar="WEIGHTS_FILE_NAME", required=True, help="", type=str)
required_named.add_argument("--threshold", required=True, help="detection threshold", type=float)
required_named.add_argument("--blur_size", required=True, help="granularity of the blurring filter", type=int)
required_named.add_argument("--frame_memory", required=True, help="blur objects in the last x frames too", type=int)

parser.add_argument("--inference_size", help="vertical inference size, e.g. 1080 or fHD", type=int, default=1080)
parser.add_argument("--roi_multi", required=False, help="increase/decrease area that will be blurred - 1 means no change", type=float, default=1.0)
parser.add_argument("-q", "--quality", metavar="[1, 10]", required=False, help="quality of the resulting video. in range [1, 10] from 1 - bad to 10 - best, default: 10", type=int, choices=range(1, 11), default=10)
return parser.parse_args()


if __name__ == "__main__":
opt = parse_arguments()
cli = CLI(opt)
Expand Down
12 changes: 9 additions & 3 deletions dashcamcleaner/main.py
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
#!/usr/bin/env python3
import inspect
import os
import signal
import sys
from glob import glob

from PySide6.QtCore import QSettings
from PySide6.QtWidgets import QApplication, QMainWindow, QFileDialog
from PySide6.QtWidgets import QSpinBox, QDoubleSpinBox, QLineEdit, QRadioButton, QMessageBox, QComboBox

from PySide6.QtWidgets import (
QApplication, QComboBox, QDoubleSpinBox, QFileDialog, QLineEdit,
QMainWindow, QMessageBox, QRadioButton, QSpinBox
)
from src.blurrer import VideoBlurrer
from src.ui_mainwindow import Ui_MainWindow

# makes it possible to interrupt while running in other thread
signal.signal(signal.SIGINT, signal.SIG_DFL)


class MainWindow(QMainWindow):

Expand Down
14 changes: 7 additions & 7 deletions dashcamcleaner/src/blurrer.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import os
import subprocess
from shutil import which
from timeit import default_timer as timer

import cv2
Expand All @@ -8,7 +9,6 @@
import torch
from PySide6.QtCore import QThread, Signal
from src.box import Box
from shutil import which


class VideoBlurrer(QThread):
Expand All @@ -25,7 +25,7 @@ def __init__(self, weights_name, parameters=None):
super(VideoBlurrer, self).__init__()
self.parameters = parameters
self.detections = []
weights_path = os.path.join("weights", f"{weights_name}.pt")
weights_path = os.path.join("weights", f"{weights_name}.pt".replace(".pt.pt", ".pt"))
self.detector = setup_detector(weights_path)
self.result = {"success": False, "elapsed_time": 0}
print("Worker created")
Expand Down Expand Up @@ -133,9 +133,9 @@ def run(self):
# open video file
cap = cv2.VideoCapture(input_path)

# get the height and width of each frame
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
# get the height and width of each frame for future debug outputs on frame
# width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
# height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
length = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
fps = cap.get(cv2.CAP_PROP_FPS)

Expand Down Expand Up @@ -201,9 +201,9 @@ def run(self):
# delete temporary output that had no audio track
try:
os.remove(temp_output)
except:
except Exception as e:
self.alert.emit(
"Could not delete temporary, muted video. Maybe another process (like a cloud service or antivirus) is using it already."
f"Could not delete temporary, muted video. Maybe another process (like a cloud service or antivirus) is using it already. \n{str(e)}"
)

# store success and elapsed time
Expand Down
2 changes: 1 addition & 1 deletion dashcamcleaner/src/box.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from math import sqrt, floor
from math import floor, sqrt


class Box:
Expand Down
23 changes: 11 additions & 12 deletions dashcamcleaner/src/generate_training_data.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
import os
import random
import sys
from argparse import ArgumentParser
from glob import glob
from math import floor, sqrt

import cv2

# hack to add Anonymizer submodule to PYTHONPATH
sys.path.append(os.path.join(os.path.dirname(__file__), "anonymizer"))
import pandas as pd
from anonymizer.anonymization.anonymizer import Anonymizer
from anonymizer.detection.detector import Detector
from anonymizer.detection.weights import download_weights, get_weights_path
from argparse import ArgumentParser
from anonymizer.obfuscation.obfuscator import Obfuscator
from math import sqrt, floor
from glob import glob
from tqdm import tqdm
import pandas as pd
from pascal_voc_writer import Writer
import random
from tqdm import tqdm

# hack to add Anonymizer submodule to PYTHONPATH
sys.path.append(os.path.join(os.path.dirname(__file__), "anonymizer"))


def setup_anonymizer(weights_path: str, obfuscation_parameters: str):
Expand Down Expand Up @@ -95,7 +95,6 @@ def batch_processing(self, input_folder, image_folder, label_folder, train_split
for index, vid in enumerate(tqdm(randomized_videos[train_videos:], desc="Processing validation video file")):
self.labeled_data_from_video(vid, index, label_format, "val")


def labeled_data_from_video(self, video_path: str, vid_num: int, label_format, folder_suffix, roi_multi=1.2):
"""
Extract frames and labels from a video
Expand All @@ -119,7 +118,7 @@ def labeled_data_from_video(self, video_path: str, vid_num: int, label_format, f
"plate": 0.2
}

if cap.isOpened() == False:
if cap.isOpened() is False:
print('error file not found')
return

Expand All @@ -128,7 +127,7 @@ def labeled_data_from_video(self, video_path: str, vid_num: int, label_format, f
while cap.isOpened():
# returns each frame
ret, frame = cap.read()
if ret == True:
if ret is True:
# skip frames to avoid too similar frames
if counter % (self.skip_frames) == 0:
_, new_detections = self.anonymizer.anonymize_image(frame, detection_thresholds)
Expand Down
24 changes: 7 additions & 17 deletions dashcamcleaner/src/ui_mainwindow.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,13 @@
## WARNING! All changes made in this file will be lost when recompiling UI file!
################################################################################

from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale,
QMetaObject, QObject, QPoint, QRect,
QSize, QTime, QUrl, Qt)
from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor,
QFont, QFontDatabase, QGradient, QIcon,
QImage, QKeySequence, QLinearGradient, QPainter,
QPalette, QPixmap, QRadialGradient, QTransform)
from PySide6.QtWidgets import (QApplication, QComboBox, QDoubleSpinBox, QFrame,
QHBoxLayout, QLabel, QLineEdit, QMainWindow,
QProgressBar, QPushButton, QSizePolicy, QSpacerItem,
QSpinBox, QVBoxLayout, QWidget)
from PySide6.QtCore import QCoreApplication, QMetaObject
from PySide6.QtWidgets import (
QComboBox, QDoubleSpinBox, QFrame, QHBoxLayout, QLabel, QLineEdit,
QProgressBar, QPushButton, QSizePolicy, QSpacerItem, QSpinBox, QVBoxLayout,
QWidget
)


class Ui_MainWindow(object):
def setupUi(self, MainWindow):
Expand All @@ -43,7 +39,6 @@ def setupUi(self, MainWindow):

self.horizontalLayout.addWidget(self.button_source)


self.verticalLayout.addLayout(self.horizontalLayout)

self.horizontalLayout_2 = QHBoxLayout()
Expand All @@ -60,7 +55,6 @@ def setupUi(self, MainWindow):

self.horizontalLayout_2.addWidget(self.button_target)


self.verticalLayout.addLayout(self.horizontalLayout_2)

self.line = QFrame(self.centralwidget)
Expand Down Expand Up @@ -120,7 +114,6 @@ def setupUi(self, MainWindow):

self.horizontalLayout_3.addWidget(self.double_spin_roimulti)


self.verticalLayout.addLayout(self.horizontalLayout_3)

self.line_2 = QFrame(self.centralwidget)
Expand Down Expand Up @@ -171,7 +164,6 @@ def setupUi(self, MainWindow):

self.horizontalLayout_4.addItem(self.horizontalSpacer)


self.verticalLayout.addLayout(self.horizontalLayout_4)

self.line_3 = QFrame(self.centralwidget)
Expand Down Expand Up @@ -201,7 +193,6 @@ def setupUi(self, MainWindow):

self.horizontalLayout_5.addWidget(self.button_abort)


self.verticalLayout.addLayout(self.horizontalLayout_5)

MainWindow.setCentralWidget(self.centralwidget)
Expand Down Expand Up @@ -230,4 +221,3 @@ def retranslateUi(self, MainWindow):
self.button_start.setText(QCoreApplication.translate("MainWindow", u"Start", None))
self.button_abort.setText(QCoreApplication.translate("MainWindow", u"Abort", None))
# retranslateUi

16 changes: 8 additions & 8 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
imageio>=2.9.0
imageio-ffmpeg>=0.4.5
matplotlib>=3.2.2
numpy>=1.18.5
opencv-python>=4.1.2
Pillow
pandas>=1.2.3
Pillow
pyside6>=6.2.2.1
PyYAML>=5.3.1
requests>=2.25.1
scipy>=1.4.1
seaborn>=0.11.1
tensorboard>=2.4.1
torch==1.8.1
torchaudio==0.8.1
imageio>=2.9.0
imageio-ffmpeg>=0.4.5
torchvision>=0.8.1
tqdm>=4.41.0
pyside6>=6.2.2.1
requests>=2.25.1
pandas>=1.2.3
seaborn>=0.11.1
tensorboard>=2.4.1
18 changes: 9 additions & 9 deletions requirements_gpu.txt
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@

--find-links https://download.pytorch.org/whl/torch_stable.html
imageio>=2.9.0
imageio-ffmpeg>=0.4.5
matplotlib>=3.2.2
numpy>=1.18.5
opencv-python>=4.1.2
pandas>=1.2.3
Pillow
pyside6>=6.2.2.1
PyYAML>=5.3.1
requests>=2.25.1
scipy>=1.4.1
seaborn>=0.11.1
tensorboard>=2.4.1
torch==1.8.1+cu111
torchaudio==0.8.1
torchvision>=0.8.1
imageio>=2.9.0
imageio-ffmpeg>=0.4.5
tqdm>=4.41.0
pyside6>=6.2.2.1
requests>=2.25.1
pandas>=1.2.3
seaborn>=0.11.1
tensorboard>=2.4.1

--find-links https://download.pytorch.org/whl/torch_stable.html

0 comments on commit 06666cb

Please sign in to comment.