-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathadversarialApp.py
executable file
·129 lines (111 loc) · 5.57 KB
/
adversarialApp.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# Callum Arthurs - ADVERSARIAL APP PROJECT - MADE FOR the LYNCHLAB- JAN2020
# MAC BUILD - run this to deploy the app on a MAC. note colon instead of semicolon. uses pyinstaller
# sudo pyinstaller -F --windowed --add-data "/Users/callum/callum/AdversarialScanner/images:images" --onefile --icon=images/icon.icns adversarialApp.py
# PC BUILD - remember the semicolon vs colon issue - .ico file instead of .icns for the KCL logo
# pyinstaller -F --windowed --add-data "C:/Users/Admin/callum/AdversarialScanner/images;images" --onefile --icon=images/icon.ico adversarialApp.py
from PyQt5.QtGui import QPixmap
import csv
from PyQt5 import uic
import qdarkgraystyle # - https://github.com/mstuttgart/qdarkgraystyle
import sys
import os
import pickle
from PyQt5.QtWidgets import QFileDialog, QMessageBox, QApplication, QMainWindow
from PyQt5 import QtCore, QtWidgets
# sys._MEIPASS is only used to deploy the app with pyinstaller, to deploy comment next line:
sys._MEIPASS = "."
class AdversarialApp(QMainWindow):
def __init__(self):
super().__init__()
uic.loadUi(sys._MEIPASS + os.sep + "images" + os.sep + "adversarial_scanner_layout.ui", self) # for deployment
self.imagesloc = sys._MEIPASS + os.sep + "images" + os.sep # for deployment
self.statusBar()
self.setWindowTitle('Dermoscopic Images Study')
self.scores = []
with open(self.imagesloc + 'fileorder.pkl', 'rb') as f: # load file order
self.files = pickle.load(f)
# self.files = natsorted([f for f in os.listdir(self.imagesloc) if f.endswith(".jpg") and not f.startswith('.')])
print("files - ", self.files)
self.iter = 0
self.total = len(self.files)
self.statusbar.showMessage(f'Select a diagnosis 1 of {self.total}')
self.btn1.clicked.connect(lambda: self.score(0))
self.btn2.clicked.connect(lambda: self.score(1))
self.delete_button.clicked.connect(lambda: self.deletebutton())
self.delete_button.setStyleSheet("background-color:rgb(80,0,0)");
# loading progress
if os.path.exists(self.imagesloc + 'progressfile.dat'):
with open(self.imagesloc + 'progressfile.dat', 'rb') as f:
self.iter, self.scores = pickle.load(f)
self.progressBar.setValue(self.iter)
self.statusbar.showMessage(f'Select a diagnosis {self.iter + 1} of {self.total}')
self.show()
scene = QtWidgets.QGraphicsScene()
self.pixmap = QtWidgets.QGraphicsPixmapItem()
scene.addItem(self.pixmap)
self.graphicsView.setScene(scene)
self.im = QPixmap(self.imagesloc + self.files[self.iter])
self.pixmap.setPixmap(self.im)
self.graphicsView.fitInView(self.graphicsView.sceneRect(), QtCore.Qt.KeepAspectRatio)
self.show()
def resizeEvent(self, event):
QMainWindow.resizeEvent(self, event)
self.graphicsView.fitInView(self.graphicsView.sceneRect(), QtCore.Qt.KeepAspectRatio)
self.show()
def deletebutton(self):
buttonReply = QMessageBox.question(self, 'PyQt5 message', "Delete all metadata and start test again?",
QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
if buttonReply == QMessageBox.Yes:
if os.path.exists(self.imagesloc + 'progressfile.dat'):
os.remove(self.imagesloc + 'progressfile.dat')
print('All metadata deleted, restarting')
self.close()
self.__init__()
else:
print('Not clicked')
def score(self, score):
self.scores.append([self.files[self.iter], score])
self.progressBar.setMaximum(self.total)
print(score)
print(self.iter, self.total)
if self.iter <= self.total - 2:
self.iter += 1
print(self.files[self.iter])
pixmap = QPixmap(self.imagesloc + self.files[self.iter])
self.pixmap.setPixmap(pixmap)
self.statusbar.showMessage(f'Select a diagnosis {self.iter + 1} of {self.total}')
print(self.iter)
self.progressBar.setValue(self.iter)
# saving progress
with open(self.imagesloc + 'progressfile.dat', 'wb') as f:
pickle.dump([self.iter, self.scores], f, protocol=2)
else:
while True:
try:
self.progressBar.setValue(self.iter + 1)
self.statusbar.showMessage(f'Save File')
saveloc, _ = QFileDialog.getSaveFileName(self, "Save results to excel", ".", "*.csv")
with open(saveloc, 'w') as out:
csv_out = csv.writer(out)
csv_out.writerow(['Image_name', 'Diagnosis'])
for row in self.scores:
csv_out.writerow(row)
except FileNotFoundError:
print("Sorry, I didn't understand that.")
continue
else:
self.statusbar.showMessage(f'Results saved - please return results to study coordinator')
self.btn1.setEnabled(False)
self.btn2.setEnabled(False)
self.progressBar.setEnabled(False)
self.graphicsView.setEnabled(False)
self.listWidget.setEnabled(False)
break
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = AdversarialApp()
# style sheet - https://github.com/mstuttgart/qdarkgraystyle
app.setStyleSheet(qdarkgraystyle.load_stylesheet())
# execute
ex.show()
app.exec_()