Compare commits

...

44 Commits

Author SHA1 Message Date
179ee054a4 Merge pull request 'VIS-50' (#15) from VIS-50 into master
Reviewed-on: #15
2021-02-01 17:36:39 +01:00
511c873d60 Merge pull request 'added txt' (#14) from tests into master
Reviewed-on: #14
2021-02-01 17:36:07 +01:00
VanillaHellen
17194ad19b help fix 2021-02-01 17:35:26 +01:00
VanillaHellen
5a91ec638e added homepage 2021-02-01 17:30:30 +01:00
VanillaHellen
315bf28e63 added txt 2021-02-01 16:12:33 +01:00
cc1d42e4cd Merge pull request 'tests' (#13) from tests into master
Reviewed-on: #13
2021-01-27 14:09:10 +01:00
VanillaHellen
2bb6e3fda1 fix 2021-01-27 14:08:25 +01:00
VanillaHellen
3885dee017 added test for deleting file 2021-01-27 14:07:25 +01:00
2669185e60 Merge pull request 'VIS-47' (#12) from VIS-47 into master
Reviewed-on: #12
2021-01-25 17:47:06 +01:00
VanillaHellen
980b323a1d final cleanup 2021-01-25 17:37:24 +01:00
VanillaHellen
c4d6e9fd66 changes 2021-01-25 17:35:09 +01:00
VanillaHellen
418548cf65 fix 2021-01-25 17:33:58 +01:00
VanillaHellen
b94304aa6e changes 2021-01-25 17:33:20 +01:00
6cb77df335 cos tam sie srogo zepsulo 2021-01-25 17:20:29 +01:00
bcf7808cba Merge branch 'VIS-31' 2021-01-25 17:12:20 +01:00
c1663bb9e7 Merge pull request 'VIS-47' (#11) from VIS-47 into master
Reviewed-on: #11
2021-01-25 17:01:34 +01:00
0a204e6f74 added analize popup 2021-01-25 17:00:50 +01:00
VanillaHellen
002f2ae2b3 removed pass since its redundant now 2021-01-25 16:57:35 +01:00
VanillaHellen
e5b595a86d uncommented stuff 2021-01-25 16:52:04 +01:00
VanillaHellen
0864afb2b7 added post-vis table, fixed help, removed test input/output files 2021-01-25 16:50:27 +01:00
7a74c39e14 Merge pull request 'VIS-48' (#10) from VIS-48 into master
Reviewed-on: #10
2021-01-25 16:26:53 +01:00
VanillaHellen
681f434386 now adding timestamp 2021-01-25 16:25:31 +01:00
VanillaHellen
5ecd3cc79c Merge branch 'master' of https://git.wmi.amu.edu.pl/s406917/VisionScore into VIS-48 2021-01-25 15:47:35 +01:00
bednarco
c20509f16f help font resized 2021-01-25 15:00:58 +01:00
bednarco
a6a80f409c added link to detect.py 2021-01-25 13:35:24 +01:00
bednarco
b4d08d6d4e Merge branch 'VIS-29' 2021-01-23 11:13:53 +01:00
352a952d74 Merge branch 'VIS-39' 2021-01-18 17:01:45 +01:00
2e9af39f60 formatted help 2021-01-18 17:00:04 +01:00
VanillaHellen
5e24b10198 Merge remote-tracking branch 'origin/master' into VIS-40-VIS-41 2021-01-18 16:23:11 +01:00
cee755a4d6 Merge branch 'VIS-28' 2021-01-18 16:20:06 +01:00
a7a63366d9 added analyze button 2021-01-18 16:18:56 +01:00
e099f35953 Merge branch 'master' of https://git.wmi.amu.edu.pl/s406917/VisionScore 2021-01-18 16:15:46 +01:00
f812d68b36 Merge branch 'VIS-28' 2021-01-18 16:15:11 +01:00
8f98740280 Merge pull request 'VIS-40-VIS-41' (#9) from VIS-40-VIS-41 into master
Reviewed-on: #9
2021-01-18 16:14:37 +01:00
VanillaHellen
3156842621 Merge branch 'master' of https://git.wmi.amu.edu.pl/s406917/VisionScore into VIS-40-VIS-41 2021-01-18 16:14:22 +01:00
4544c8f398 Merge branch 'master' into VIS-40-VIS-41 2021-01-18 16:14:12 +01:00
e1a2b81a7f added analize button 2021-01-18 16:13:52 +01:00
VanillaHellen
1c7aa28ed0 fix 2021-01-18 16:13:21 +01:00
VanillaHellen
a4b04c7c8f added the view after uploading the file 2021-01-18 16:10:17 +01:00
0dd70ee9b7 Merge pull request 'VIS-37' (#8) from VIS-37 into master
Reviewed-on: #8
2021-01-11 16:25:46 +01:00
VanillaHellen
98c1768d4f fix 2021-01-11 16:24:30 +01:00
VanillaHellen
47a0a52475 refreshes the table after deleting the file 2021-01-11 16:22:46 +01:00
5cceb7c77f Merge branch 'VIS-38' 2021-01-11 10:25:27 +01:00
cf29bdc68b Added Help tab, changed Home to File 2021-01-11 10:24:05 +01:00
21 changed files with 218 additions and 65 deletions

BIN
files/input/contr.mp4 Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1 +0,0 @@
test txt file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,12 +1,12 @@
#import tkinter as tk
import sys
import os
import os, subprocess
import shutil
from datetime import datetime
import time
from PyQt5 import QtCore
from PyQt5.QtWidgets import *
from PyQt5.QtGui import QIcon, QPixmap
from PyQt5.QtGui import *
from PyQt5.QtCore import *
scriptPath = os.path.dirname(os.path.realpath(__file__))
@ -16,10 +16,38 @@ outputFilePath = scriptPath + '\\files\\output'
LIB_RAW = 0
LIB_VIS = 1
stylesheet = """
MainWindow {
background: qlineargradient(x1:0 y1:0, x2:1 y2:0, stop:0 rgba(255,218,113,1), stop:0.5 rgba(215,137,255,1), stop:1 rgba(105,126,255,1));
}
"""
def files(path):
for file in os.listdir(path):
if os.path.isfile(os.path.join(path, file)):
yield file
for subdir, dirs, files_list in os.walk(path):
for file in files_list:
yield os.path.join(subdir, file)
def delete_file(file):
os.remove(file)
def save_input(oldpath):
# add timestamp to the filename, so it wouln't overwrite but the user still knows which file's which
timestamp = str(int(time.time()))
basename = os.path.basename(oldpath)
try:
index_of_dot = basename.index('.')
basename_no_extension = basename[:index_of_dot]
extension = basename[index_of_dot:]
except ValueError:
basename_no_extension = basename
extension = ''
filename = basename_no_extension + '_' + timestamp + extension
newpath = inputFilePath + '\\' + filename
shutil.copy(oldpath, newpath)
return newpath
class deletePopup(QMessageBox):
def __init__(self, parent=None):
@ -29,17 +57,27 @@ class deletePopup(QMessageBox):
self.setWindowTitle("Confirm deletion")
self.setStandardButtons(self.Yes | self.No)
def save_input(oldpath):
# make timestampt the filename, so it wouln't overwrite
timestamp = str(int(time.time()))
filename = timestamp + '.' + oldpath.split('.')[-1]
newpath = inputFilePath + '\\' + filename
shutil.copy(oldpath, newpath)
return newpath
class analizePopup(QMessageBox):
def __init__(self, parent=None):
super(analizePopup, self).__init__(parent)
self.setStyleSheet("QLabel{min-width: 100px; max-width: 100px; qproperty-alignment: AlignCenter;}");
self.setWindowIcon(QIcon(scriptPath + os.path.sep + 'static/v_logo.jpg'))
self.setText("Analyzing file...")
self.setWindowTitle("File analysis")
# create Label
self.setIconPixmap(QPixmap(scriptPath + os.path.sep + 'static/loading.gif'))
icon_label = self.findChild(QLabel, "qt_msgboxex_icon_label")
movie = QMovie(scriptPath + os.path.sep + 'static/loading.gif')
# avoid garbage collector
setattr(self, 'icon_label', movie)
icon_label.setMovie(movie)
movie.start()
self.setStandardButtons(self.Cancel)
class LibraryTableButtons(QWidget):
def __init__(self, file, parent=None):
def __init__(self, file, table, type, mainWindow, parent=None):
super(LibraryTableButtons,self).__init__(parent)
def viewFile():
@ -47,15 +85,34 @@ class LibraryTableButtons(QWidget):
def deleteFile():
self.exPopup = deletePopup()
# self.exPopup.setGeometry(100, 200, 100, 100)
ret = self.exPopup.exec()
if ret == self.exPopup.Yes:
os.remove(file)
delete_file(file)
table.fillTable(type, mainWindow)
def analyzeFile():
self.exPopup = analizePopup()
#cmd = "py detect.py --source {} --view-img".format(str(file))
#popen = subprocess.Popen(cmd, cwd="../yolov5/", stdout=subprocess.PIPE)
cancel = self.exPopup.exec()
if cancel == self.exPopup.Cancel:
#popen.terminate()
pass
#popen.wait()
self.exPopup.close()
# mainWindow.showVisualisation(file) <- ALWAYS shows even if you cancel the process and we don't have time to fix that now
layout = QHBoxLayout()
layout.setContentsMargins(0,0,0,0)
layout.setSpacing(0)
if type == LIB_RAW:
analyze_btn = QPushButton('Analyze')
analyze_btn.clicked.connect(analyzeFile)
layout.addWidget(analyze_btn)
view_btn = QPushButton('View')
view_btn.clicked.connect(viewFile)
layout.addWidget(view_btn)
@ -69,24 +126,45 @@ class LibraryTableButtons(QWidget):
class LibraryTable(QTableWidget):
def __init__(self, type, parent=None):
def __init__(self, type, mainWindow, singleFilePath = None, parent = None):
QTableWidget.__init__(self)
self.fillTable(type, mainWindow, singleFilePath)
def fillTable(self, type, mainWindow, singleFilePath = None):
self.setColumnCount(3)
if singleFilePath != None:
self.setRowCount(1)
self.setHorizontalHeaderLabels(['Upload date', 'Filename', 'Options'])
filePath = inputFilePath
self.horizontalHeader().setSectionResizeMode(0, QHeaderView.Stretch)
self.horizontalHeader().setSectionResizeMode(1, QHeaderView.Stretch)
self.horizontalHeader().setSectionResizeMode(2, QHeaderView.ResizeToContents)
self.setItem(0,0,QTableWidgetItem(str(datetime.fromtimestamp(os.path.getmtime(singleFilePath)))))
self.setItem(0,1,QTableWidgetItem(str(os.path.basename(singleFilePath))))
self.setCellWidget(0,2,LibraryTableButtons(singleFilePath, self, type, mainWindow))
else:
if type == LIB_RAW:
self.setHorizontalHeaderLabels(['Upload date', 'Filename', 'Options'])
filePath = inputFilePath
else:
self.setHorizontalHeaderLabels(['Creation date', 'Filename', 'Options'])
filePath = outputFilePath
self.horizontalHeader().setSectionResizeMode(0, QHeaderView.Stretch)
self.horizontalHeader().setSectionResizeMode(1, QHeaderView.Stretch)
self.horizontalHeader().setSectionResizeMode(2, QHeaderView.ResizeToContents)
dates = []
names = []
for index, file in enumerate(files(filePath)):
dates.append(QTableWidgetItem(str(datetime.fromtimestamp(os.path.getmtime(filePath + '/' + file)))))
dates.append(QTableWidgetItem(str(datetime.fromtimestamp(os.path.getmtime(file)))))
names.append(QTableWidgetItem(str(file)))
self.setRowCount(len(dates))
@ -94,7 +172,19 @@ class LibraryTable(QTableWidget):
for index, date in enumerate(dates):
self.setItem(index,0,date)
self.setItem(index,1,names[index])
self.setCellWidget(index,2,LibraryTableButtons(filePath + '\\' + names[index].text()))
self.setCellWidget(index,2,LibraryTableButtons(names[index].text(), self, type, mainWindow))
class formatHelp(QLabel):
def __init__(self, parent=None):
QLabel.__init__(self)
with open(scriptPath + os.path.sep + 'static/help.txt', 'r', encoding='utf-8') as file:
help_text = file.read().replace('\n', '')
self.setText(help_text)
self.setStyleSheet("padding-left: 20px; padding-right: 20px; padding-top: 10px; padding-bottom: 10px; font-size:32px; background-color: white;")
self.adjustSize()
class MainWindow(QMainWindow):
@ -103,14 +193,39 @@ class MainWindow(QMainWindow):
super().__init__()
self.initUI()
# todo: split in multiply labels for richer formatting
# Show Help tab
def showHelp(self):
label = formatHelp()
self.setCentralWidget(label)
def showHomepage(self):
# Upload file button + instructions on homepage
label = QLabel('Welcome to VisionScore! Use the button below to upload a file and start analyzing it. If you need further help, please click the "help" item in the menu above.', self)
label.setFont(QFont('Arial', 14))
label.setStyleSheet('color: white;')
label.adjustSize()
label.move(200,200)
shadow = QGraphicsDropShadowEffect()
shadow.setBlurRadius(10)
shadow.setOffset(2)
label.setGraphicsEffect(shadow)
button = QPushButton('Upload file', self)
button.setToolTip('This is an example button')
button.move(850,270)
button.setFixedSize(220, 50)
button.clicked.connect(self.showUploadFile)
# Show raw uploaded files
def showInputLibrary(self):
libTable = LibraryTable(LIB_RAW)
libTable = LibraryTable(LIB_RAW, self)
self.setCentralWidget(libTable)
# Show visualisations
def showVisualisationsLibrary(self):
libTable = LibraryTable(LIB_VIS)
libTable = LibraryTable(LIB_VIS, self)
self.setCentralWidget(libTable)
def showUploadFile(self):
@ -119,23 +234,37 @@ class MainWindow(QMainWindow):
dialog.setFilter(QDir.Files)
if dialog.exec_():
file_path = dialog.selectedFiles()[0] # ['C:/Users/agatha/Desktop/SYI/VisionScore/win_venv/requirements.txt']
save_input(file_path)
newPath = save_input(file_path)
singleFileTable = LibraryTable(LIB_RAW, self, newPath)
self.setCentralWidget(singleFileTable)
def showVisualisation(self, path):
singleFileTable = LibraryTable(LIB_VIS, self, path)
self.setCentralWidget(singleFileTable)
def initUI(self):
self.setGeometry(0, 0, 600, 400)
self.setWindowTitle('VisionScore')
scriptDir = os.path.dirname(os.path.realpath(__file__))
self.setWindowIcon(QIcon(scriptDir + os.path.sep + 'static/v_logo.jpg'))
self.showHomepage()
# Toolbar
# File menu
menuBar = self.menuBar()
homeMenu = QMenu("&Home", self)
menuBar.addMenu(homeMenu)
fileMenu = QMenu("&File", self)
menuBar.addMenu(fileMenu)
# Upload file
uploadAct = QAction('&Upload new file', self)
uploadAct.triggered.connect(self.showUploadFile)
homeMenu.addAction(uploadAct)
fileMenu.addAction(uploadAct)
# Exit app
exitAct = QAction('&Exit', self)
exitAct.setShortcut('Ctrl+Q')
exitAct.setStatusTip('Exit')
exitAct.triggered.connect(qApp.quit)
fileMenu.addAction(exitAct)
# Library menu
libraryMenu = QMenu("&Library", self)
@ -151,20 +280,17 @@ class MainWindow(QMainWindow):
visAct.triggered.connect(self.showVisualisationsLibrary)
libraryMenu.addAction(visAct)
# Exit app
exitAct = QAction('&Exit', self)
exitAct.setShortcut('Ctrl+Q')
exitAct.setStatusTip('Exit')
exitAct.triggered.connect(qApp.quit)
homeMenu.addAction(exitAct)
# Help
helpAct = QAction('&Help', self)
helpAct.triggered.connect(self.showHelp)
menuBar.addAction(helpAct)
helpMenu = menuBar.addMenu("&Help")
self.show()
self.showMaximized()
def main():
app = QApplication(sys.argv)
app.setStyleSheet(stylesheet)
w = MainWindow()
sys.exit(app.exec_())

1
win_venv/static/help.txt Normal file
View File

@ -0,0 +1 @@
<p>VisionScore to program służący do generowania analizy nagrań lub zdjęć z mecz&oacute;w piłkarskich.<br /><br />By wygenerować taką analizę, należy postępować według następujących krok&oacute;w:<br /><br />1. Wgraj plik z plikiem do przeanalizowania<br /><em>File -&gt; Upload new file</em><br />2. Po wgraniu pliku pojawi się on w <br /><em>Library -&gt; Input files</em><br /> 3. By wygenerować analizę należy kliknąć przycisk<br /><em>Analyze</em><br />znajdujący się obok wgranego pliku. Analizę można wygenerować także do uprzednio wgranych plik&oacute;w.<br />4. Po wygenerowaniu, analiza znajdować się będzie w <br /><em>Library -&gt; Vizusalizations</em><br />możesz tam także zobaczyć wszystkie poprzednio wygenerowane analizy.<br /><br />Każdy plik źr&oacute;dłowy lub wygenerowaną analizę możesz w każdym momencie podejrzeć klikając<br /><em>View</em><br />obok pliku znajdującego się w bibliotekach. Plik możesz też w każdym momencie usunąć klikając<br /><em>Delete</em><br />obok odpowiedniego pliku.<br /><br /><br />Zakończ działanie aplikacji klikąc<br /><em>File -&gt; Exit</em><br />używając skr&oacute;tu klawiszowego Ctrl+Q lub bo prostu zamykając okienko aplikacji.<br /><br /><br /><strong>Kontakt: mikbed@st.amu.edu.pl</strong></p>

BIN
win_venv/static/loading.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

4
win_venv/test.txt Normal file
View File

@ -0,0 +1,4 @@
testing
more testing

View File

@ -22,6 +22,7 @@ class savingFileTest(unittest.TestCase):
new_file_content += line
self.assertEqual(old_file_content, new_file_content)
os.remove(newpath)
# test using mock checking if a file with analysis had been generated
@ -29,12 +30,33 @@ class generetingOutputFile(unittest.TestCase):
def test_output_file(self):
print('Moock testing outputfile')
print('Mock testing outputfile')
m = Mock()
m.output_file_path = scriptPath + '\\files\\output\\test.pdf'
assert Path(m.output_file_path).is_file()
# test deleting input file
class testDeleteFile(unittest.TestCase):
def test_delete_file(self):
print('Testing deleting the file')
new_file = inputFilePath + os.path.sep + 'new_file.txt'
with open(new_file, 'w') as file:
file.write('teeeest')
with open(new_file) as f:
content = f.read()
assert os.path.exists(new_file)
self.assertEqual(content, 'teeeest')
delete_file(new_file)
self.assertFalse(os.path.exists(new_file))
if __name__ == '__main__':
unittest.main()

View File

@ -237,7 +237,7 @@ def detect(save_img=False):
h = int(vid_cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
vid_writer = cv2.VideoWriter(save_path, cv2.VideoWriter_fourcc(*fourcc), fps, (w, h))
vid_writer.write(im0)
print(save_path)
if save_txt or save_img:
s = f"\n{len(list(save_dir.glob('labels/*.txt')))} labels saved to {save_dir / 'labels'}" if save_txt else ''
print(f"Results saved to {save_dir}{s}")
@ -260,7 +260,7 @@ if __name__ == '__main__':
parser.add_argument('--agnostic-nms', action='store_true', help='class-agnostic NMS')
parser.add_argument('--augment', action='store_true', help='augmented inference')
parser.add_argument('--update', action='store_true', help='update all models')
parser.add_argument('--project', default='../files/output', help='save results to project/name')
parser.add_argument('--project', default='../win_venv/files/output', help='save results to project/name')
parser.add_argument('--name', default='exp', help='save results to project/name')
parser.add_argument('--exist-ok', action='store_true', help='existing project/name ok, do not increment')
parser.add_argument("--config_deepsort", type=str, default="deep_sort_pytorch/configs/deep_sort.yaml")

View File

@ -170,7 +170,8 @@ class LoadImages: # for inference
ret_val, img0 = self.cap.read()
self.frame += 1
print('video %g/%g (%g/%g) %s: ' % (self.count + 1, self.nf, self.frame, self.nframes, path), end='')
# print('video %g/%g (%g/%g) %s: ' % (self.count + 1, self.nf, self.frame, self.nframes, path), end='')
print('video %g/%g (%g/%g) : ' % (self.count + 1, self.nf, self.frame, self.nframes), end='')
else:
# Read image