Compare commits
5 Commits
master
...
feature/ba
Author | SHA1 | Date | |
---|---|---|---|
3d4cf9daa8 | |||
f82275df71 | |||
1712349965 | |||
6e0bc260d4 | |||
|
474586d6dc |
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
[submodule "TV2D"]
|
||||||
|
path = TV2D
|
||||||
|
url = https://git.wmi.amu.edu.pl/s426206/TV2D.git
|
8
.idea/.gitignore
vendored
Normal file
8
.idea/.gitignore
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
|
# Editor-based HTTP Client requests
|
||||||
|
/httpRequests/
|
||||||
|
# Datasource local storage ignored files
|
||||||
|
/dataSources/
|
||||||
|
/dataSources.local.xml
|
23
.idea/WTV2D.iml
Normal file
23
.idea/WTV2D.iml
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="PYTHON_MODULE" version="4">
|
||||||
|
<component name="FacetManager">
|
||||||
|
<facet type="django" name="Django">
|
||||||
|
<configuration>
|
||||||
|
<option name="rootFolder" value="$MODULE_DIR$" />
|
||||||
|
<option name="settingsModule" value="WTV2D/settings.py" />
|
||||||
|
<option name="manageScript" value="$MODULE_DIR$/manage.py" />
|
||||||
|
<option name="environment" value="<map/>" />
|
||||||
|
<option name="doNotUseTestRunner" value="false" />
|
||||||
|
<option name="trackFilePattern" value="migrations" />
|
||||||
|
</configuration>
|
||||||
|
</facet>
|
||||||
|
</component>
|
||||||
|
<component name="NewModuleRootManager">
|
||||||
|
<content url="file://$MODULE_DIR$" />
|
||||||
|
<orderEntry type="jdk" jdkName="Python 3.7 (dt2homDeep3060) (2)" jdkType="Python SDK" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
<component name="TemplatesService">
|
||||||
|
<option name="TEMPLATE_CONFIGURATION" value="Django" />
|
||||||
|
</component>
|
||||||
|
</module>
|
16
.idea/inspectionProfiles/Project_Default.xml
Normal file
16
.idea/inspectionProfiles/Project_Default.xml
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<component name="InspectionProjectProfileManager">
|
||||||
|
<profile version="1.0">
|
||||||
|
<option name="myName" value="Project Default" />
|
||||||
|
<inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
|
<inspection_tool class="PyPackageRequirementsInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<option name="ignoredPackages">
|
||||||
|
<value>
|
||||||
|
<list size="2">
|
||||||
|
<item index="0" class="java.lang.String" itemvalue="python-magic" />
|
||||||
|
<item index="1" class="java.lang.String" itemvalue="django-upload-validator" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</option>
|
||||||
|
</inspection_tool>
|
||||||
|
</profile>
|
||||||
|
</component>
|
6
.idea/inspectionProfiles/profiles_settings.xml
Normal file
6
.idea/inspectionProfiles/profiles_settings.xml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<component name="InspectionProjectProfileManager">
|
||||||
|
<settings>
|
||||||
|
<option name="USE_PROJECT_PROFILE" value="false" />
|
||||||
|
<version value="1.0" />
|
||||||
|
</settings>
|
||||||
|
</component>
|
4
.idea/misc.xml
Normal file
4
.idea/misc.xml
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.7 (dt2homDeep3060) (2)" project-jdk-type="Python SDK" />
|
||||||
|
</project>
|
8
.idea/modules.xml
Normal file
8
.idea/modules.xml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/WTV2D.iml" filepath="$PROJECT_DIR$/.idea/WTV2D.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
7
.idea/vcs.xml
Normal file
7
.idea/vcs.xml
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||||
|
<mapping directory="$PROJECT_DIR$/TV2D" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
1
TV2D
Submodule
1
TV2D
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit f031598c49cd8aebd94837693856bf181343eb4d
|
@ -37,6 +37,7 @@ INSTALLED_APPS = [
|
|||||||
'django.contrib.sessions',
|
'django.contrib.sessions',
|
||||||
'django.contrib.messages',
|
'django.contrib.messages',
|
||||||
'django.contrib.staticfiles',
|
'django.contrib.staticfiles',
|
||||||
|
'core.apps.CoreConfig',
|
||||||
]
|
]
|
||||||
|
|
||||||
MIDDLEWARE = [
|
MIDDLEWARE = [
|
||||||
@ -116,5 +117,8 @@ USE_TZ = True
|
|||||||
|
|
||||||
# Static files (CSS, JavaScript, Images)
|
# Static files (CSS, JavaScript, Images)
|
||||||
# https://docs.djangoproject.com/en/3.0/howto/static-files/
|
# https://docs.djangoproject.com/en/3.0/howto/static-files/
|
||||||
|
STATIC_ROOT = os.path.join(BASE_DIR, 'static/')
|
||||||
STATIC_URL = '/static/'
|
STATIC_URL = '/static/'
|
||||||
|
|
||||||
|
MEDIA_ROOT = os.path.join(BASE_DIR, 'media') #folder przechowywanych zdjec
|
||||||
|
MEDIA_URL = '/media/'
|
||||||
|
@ -14,8 +14,18 @@ Including another URLconf
|
|||||||
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
|
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
|
||||||
"""
|
"""
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from django.urls import path
|
from django.urls import path, include
|
||||||
|
from django.conf import settings
|
||||||
|
from django.conf.urls.static import static
|
||||||
|
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('admin/', admin.site.urls),
|
path('admin/', admin.site.urls),
|
||||||
|
path('', include('core.urls')),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
if settings.DEBUG:
|
||||||
|
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|
||||||
|
else:
|
||||||
|
urlpatterns += staticfiles_urlpatterns()
|
||||||
|
|
||||||
|
0
core/__init__.py
Executable file
0
core/__init__.py
Executable file
3
core/admin.py
Executable file
3
core/admin.py
Executable file
@ -0,0 +1,3 @@
|
|||||||
|
from django.contrib import admin
|
||||||
|
|
||||||
|
# Register your models here.
|
5
core/apps.py
Executable file
5
core/apps.py
Executable file
@ -0,0 +1,5 @@
|
|||||||
|
from django.apps import AppConfig
|
||||||
|
|
||||||
|
|
||||||
|
class CoreConfig(AppConfig):
|
||||||
|
name = 'core'
|
13
core/forms.py
Normal file
13
core/forms.py
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
from django import forms
|
||||||
|
from .models import VideoFile
|
||||||
|
|
||||||
|
# Form for upload video to the server
|
||||||
|
class VideoUploadForm(forms.ModelForm):
|
||||||
|
class Meta:
|
||||||
|
model = VideoFile
|
||||||
|
fields = ['file']
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
super(VideoUploadForm, self).__init__(*args, **kwargs)
|
||||||
|
# In html input only accept video uploads
|
||||||
|
self.fields['file'].widget.attrs.update({'class': 'form-control border-0', 'accept': 'video/*'})
|
0
core/migrations/__init__.py
Executable file
0
core/migrations/__init__.py
Executable file
37
core/models.py
Executable file
37
core/models.py
Executable file
@ -0,0 +1,37 @@
|
|||||||
|
from django.db import models
|
||||||
|
from enum import Enum
|
||||||
|
|
||||||
|
# Create your models here.
|
||||||
|
class VideoFile(models.Model):
|
||||||
|
"""
|
||||||
|
A class for uploading video to the server.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def forDjango(cls):
|
||||||
|
cls.do_not_call_in_templates = True
|
||||||
|
return cls
|
||||||
|
|
||||||
|
@forDjango
|
||||||
|
class VideoFileStatus(Enum):
|
||||||
|
NEW = 1
|
||||||
|
PROCESSING = 4
|
||||||
|
READY = 7
|
||||||
|
|
||||||
|
file = models.FileField(upload_to="", max_length=1024) # If upload_to=="" then file will be uploaded to the MEDIA_ROOT path set in settings.
|
||||||
|
uploaded_at = models.DateTimeField(auto_now_add=True)
|
||||||
|
fps = models.IntegerField(default=25)
|
||||||
|
video_width = models.IntegerField(default=0, blank=True)
|
||||||
|
video_height = models.IntegerField(default=0, blank=True)
|
||||||
|
status = models.IntegerField(default=VideoFileStatus.NEW.value)
|
||||||
|
output_file = models.FileField(upload_to="", max_length=1024, blank=True)
|
||||||
|
csv_file = models.FileField(upload_to="", max_length=1024, blank=True)
|
||||||
|
|
||||||
|
|
||||||
|
@property
|
||||||
|
def url(self):
|
||||||
|
return self.file.url
|
||||||
|
|
||||||
|
|
||||||
|
class WTV2D_data(models.Model):
|
||||||
|
processing = models.BooleanField(default=False, blank=False)
|
||||||
|
|
0
core/static/css/main.css
Normal file
0
core/static/css/main.css
Normal file
37
core/templates/core/home.html
Normal file
37
core/templates/core/home.html
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
{% load static %}
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet"
|
||||||
|
integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
|
||||||
|
<script type="text/javascript" src="/static/js/jquery-3.6.0.min.js"></script>
|
||||||
|
<link rel="stylesheet" href="{% static 'css/main.css' %}">
|
||||||
|
<title>Web-TV2D</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div>
|
||||||
|
<div class="d-flex flex-column min-vh-100 justify-content-center align-items-center">
|
||||||
|
{% if processing %}
|
||||||
|
<h1> Some video is still being processed</h1>
|
||||||
|
<a class="btn btn-primary" href="{% url 'videolist' %}">Video list</a>
|
||||||
|
{% else %}
|
||||||
|
<h1> Submit your video</h1>
|
||||||
|
<form id="form" method="POST" class="mt-4 text-center" enctype="multipart/form-data">
|
||||||
|
{% csrf_token %}
|
||||||
|
{% for message in messages %}
|
||||||
|
{% if message.level == DEFAULT_MESSAGE_LEVELS.ERROR %}
|
||||||
|
<span style="color: red">{{message}}</span>
|
||||||
|
{% elif message.level == DEFAULT_MESSAGE_LEVELS.SUCCESS %}
|
||||||
|
<span style="color: green">{{message}}</span>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{{ form.file }}
|
||||||
|
<input type="submit" class="btn btn-primary mt-2" value="Upload">
|
||||||
|
</form>
|
||||||
|
<a class="btn btn-primary mt-5" href="{% url 'videolist' %}">Video list</a>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
53
core/templates/core/video_list.html
Normal file
53
core/templates/core/video_list.html
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
{% load static %}
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet"
|
||||||
|
integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
|
||||||
|
<script type="text/javascript" src="/static/js/jquery-3.6.0.min.js"></script>
|
||||||
|
<link rel="stylesheet" href="{% static 'css/main.css' %}">
|
||||||
|
<title>Web-TV2D - Video list</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container my-5">
|
||||||
|
<a class="btn btn-primary" href="{% url 'home' %}">Upload video</a>
|
||||||
|
<a class="btn btn-primary ms-5" href="{% url 'videolist' %}">Refresh</a>
|
||||||
|
<div class="d-flex flex-column justify-content-center align-items-center">
|
||||||
|
<table class="table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th scope="col">#</th>
|
||||||
|
<th scope="col">Video original file</th>
|
||||||
|
<th scope="col">Video status</th>
|
||||||
|
<th scope="col">Video processed file</th>
|
||||||
|
<th scope="col">Video CSV file</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for video in videos %}
|
||||||
|
<tr>
|
||||||
|
<th scope="row"> {{ video.pk }}</th>
|
||||||
|
<td><a href="{{ video.file.url }}">{{ video.file }}</a></td>
|
||||||
|
{% if video.status == enum_video_file_status.NEW.value %}
|
||||||
|
<td>NEW</td>
|
||||||
|
{% elif video.status == enum_video_file_status.PROCESSING.value %}
|
||||||
|
<td>PROCESSING</td>
|
||||||
|
{% elif video.status == enum_video_file_status.READY.value %}
|
||||||
|
<td>READY</td>
|
||||||
|
{% endif %}
|
||||||
|
{% if video.output_file and video.csv_file %}
|
||||||
|
<td><a href="{{ video.output_file.url }}">{{ video.output_file }}</a></td>
|
||||||
|
<td><a href="{{ video.csv_file.url }}">{{ video.csv_file }}</a></td>
|
||||||
|
{% else %}
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
{% endif %}
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
3
core/tests.py
Executable file
3
core/tests.py
Executable file
@ -0,0 +1,3 @@
|
|||||||
|
from django.test import TestCase
|
||||||
|
|
||||||
|
# Create your tests here.
|
8
core/urls.py
Normal file
8
core/urls.py
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
from django.contrib import admin
|
||||||
|
from django.urls import path
|
||||||
|
from . import views
|
||||||
|
|
||||||
|
urlpatterns = [
|
||||||
|
path('/', views.home, name="home"),
|
||||||
|
path('videolist/', views.video_list_view, name="videolist"),
|
||||||
|
]
|
72
core/views.py
Executable file
72
core/views.py
Executable file
@ -0,0 +1,72 @@
|
|||||||
|
import cv2
|
||||||
|
from django.http import HttpResponseRedirect
|
||||||
|
from django.shortcuts import render
|
||||||
|
from django.contrib import messages
|
||||||
|
from core.forms import VideoUploadForm
|
||||||
|
from core.models import VideoFile, WTV2D_data
|
||||||
|
from TV2D import TV2D
|
||||||
|
|
||||||
|
# Create your views here.
|
||||||
|
|
||||||
|
|
||||||
|
def home(request):
|
||||||
|
wtv2d_data = WTV2D_data.objects.first()
|
||||||
|
# For control processing videos some workers should be used like Celery
|
||||||
|
# if wtv2d_data.processing:
|
||||||
|
# context = {'processing': True}
|
||||||
|
# return render(request, 'core/home.html', context)
|
||||||
|
form = VideoUploadForm()
|
||||||
|
if request.method == "POST":
|
||||||
|
form = VideoUploadForm(request.POST, request.FILES)
|
||||||
|
if form.is_valid():
|
||||||
|
wtv2d_data.processing = True
|
||||||
|
wtv2d_data.save()
|
||||||
|
video_file = VideoFile(file=request.FILES['file'])
|
||||||
|
video_file.status = VideoFile.VideoFileStatus.NEW.value
|
||||||
|
video_file.save()
|
||||||
|
|
||||||
|
video = cv2.VideoCapture(video_file.file.path)
|
||||||
|
video_file.fps = video.get(cv2.CAP_PROP_FPS)
|
||||||
|
video_file.video_width = int(video.get(cv2.CAP_PROP_FRAME_WIDTH))
|
||||||
|
video_file.video_height = int(video.get(cv2.CAP_PROP_FRAME_HEIGHT))
|
||||||
|
video_file.status = VideoFile.VideoFileStatus.PROCESSING.value
|
||||||
|
video_file.save()
|
||||||
|
|
||||||
|
# object_detection_model_path = "COCO-InstanceSegmentation/mask_rcnn_X_101_32x8d_FPN_3x.yaml"
|
||||||
|
object_detection_model_path = "COCO-Detection/faster_rcnn_R_50_FPN_3x.yaml"
|
||||||
|
# Same as model by for now for config. If you use model from local sotrage you can still use config
|
||||||
|
## from Detectron2 Model Zoo and Baselines.
|
||||||
|
# object_detection_config_path = "COCO-InstanceSegmentation/mask_rcnn_X_101_32x8d_FPN_3x.yaml"
|
||||||
|
object_detection_config_path = "COCO-Detection/faster_rcnn_R_50_FPN_3x.yaml"
|
||||||
|
homography_keypoint_path = "TV2D/models/FPN_efficientnetb3_0.0001_4.h5"
|
||||||
|
homography_deephomo_path = "TV2D/models/HomographyModel_0.0001_4.h5"
|
||||||
|
deep_sort_model = "TV2D/models/market_bot_R50.pth"
|
||||||
|
deep_sort_model_config = "TV2D/deep_sort_pytorch/thirdparty/fast-reid/configs/Market1501/bagtricks_R50.yml"
|
||||||
|
|
||||||
|
tv2d = TV2D.TV2D(object_detection_model_path, object_detection_config_path=object_detection_config_path,
|
||||||
|
homography_on=True, team_detection_on=True,
|
||||||
|
tracker_on=True, no_gui=True,
|
||||||
|
homography_pretreined=False, homography_deephomo_path=homography_deephomo_path,
|
||||||
|
homography_keypoint_path=homography_keypoint_path,
|
||||||
|
deep_sort_model_path=deep_sort_model, deep_sort_model_config=deep_sort_model_config)
|
||||||
|
output_video_name = ".".join(video_file.file.name.split(".")[:-1]) + "_" + str(video_file.pk) + ".mkv"
|
||||||
|
export_data_file_path = ".".join(video_file.file.name.split(".")[:-1]) + "_" + str(video_file.pk) + ".csv"
|
||||||
|
video_file.output_file = output_video_name
|
||||||
|
video_file.csv_file = export_data_file_path
|
||||||
|
video_file.save()
|
||||||
|
tv2d(TV2D.TV2D.RunOn.VIDEO, video_file.file.path, export_output_path=f"media/{output_video_name}",
|
||||||
|
export_data_file_path=f"media/{export_data_file_path}")
|
||||||
|
video_file.status = VideoFile.VideoFileStatus.READY.value
|
||||||
|
video_file.save()
|
||||||
|
else:
|
||||||
|
messages.error(request, "Something went wrong")
|
||||||
|
|
||||||
|
wtv2d_data.processing = False
|
||||||
|
wtv2d_data.save()
|
||||||
|
context = {'form': form}
|
||||||
|
return render(request, 'core/home.html', context)
|
||||||
|
|
||||||
|
def video_list_view(request):
|
||||||
|
videos = VideoFile.objects.all().order_by("-pk")
|
||||||
|
context = {'videos': videos, 'enum_video_file_status': VideoFile.VideoFileStatus}
|
||||||
|
return render(request, 'core/video_list.html', context)
|
Loading…
Reference in New Issue
Block a user