diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..26d3352
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/.idea/convert_pyside.iml b/.idea/convert_pyside.iml
new file mode 100644
index 0000000..b04c19f
--- /dev/null
+++ b/.idea/convert_pyside.iml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
new file mode 100644
index 0000000..edc52fd
--- /dev/null
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -0,0 +1,66 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml
new file mode 100644
index 0000000..105ce2d
--- /dev/null
+++ b/.idea/inspectionProfiles/profiles_settings.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..b90a867
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..afc1b90
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..94a25f7
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/logo.ico b/logo.ico
new file mode 100644
index 0000000..da0d3d5
Binary files /dev/null and b/logo.ico differ
diff --git a/requirements.txt b/requirements.txt
index 50f7a13..fdbc086 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,7 +1,10 @@
-PyQt5 >= 5.13
+PySide6~=6.3.0
python-vlc
-PyQtGraph
-pyechart
-influxdb
-opencv-python
-pandas
\ No newline at end of file
+opencv-contrib-python
+pandas~=1.3.4
+scipy~=1.7.2
+psutil~=5.9.0
+pyinstaller
+opencv-python~=4.6.0.66
+numpy~=1.21.3
+cryptography~=37.0.2
\ No newline at end of file
diff --git a/run.py b/run.py
index b1a3bda..0387554 100644
--- a/run.py
+++ b/run.py
@@ -6,6 +6,44 @@
# cotjdals5450@gmail.com (Seong Min Chae)
# 5jx2oh@gmail.com (Jongjin Oh)
-from src.__main__ import main
+import os
+import sys
+import time
+import multiprocessing as mp
+from multiprocessing import Queue, Process
-main()
+from PySide6.QtWidgets import QApplication, QMessageBox
+from PySide6.QtGui import QGuiApplication
+
+from src.video_thread_mp import producer
+from src.clock import clockclock
+from src.js08 import JS08MainWindow
+from src.model import JS08Settings
+
+
+if __name__ == '__main__':
+ print(f'Start time: {time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}')
+
+ mp.freeze_support()
+ q = Queue()
+ _q = Queue()
+
+ _producer = producer
+
+ p = Process(name='clock', target=clockclock, args=(q,), daemon=True)
+ _p = Process(name='producer', target=_producer, args=(_q,), daemon=True)
+
+ p.start()
+ _p.start()
+
+ os.makedirs(f'{JS08Settings.get("data_csv_path")}', exist_ok=True)
+ os.makedirs(f'{JS08Settings.get("target_csv_path")}', exist_ok=True)
+ os.makedirs(f'{JS08Settings.get("image_save_path")}', exist_ok=True)
+
+ app = QApplication(sys.argv)
+ screen_size = QGuiApplication.screens()[0].geometry()
+ width, height = screen_size.width(), screen_size.height()
+ if width > 1920 or height > 1080:
+ QMessageBox.warning(None, 'Warning', 'JS08 is based on FHD screen.')
+ window = JS08MainWindow(q, _q)
+ sys.exit(app.exec())
diff --git a/src/JS08_Logo.ico b/src/JS08_Logo.ico
new file mode 100644
index 0000000..977ce5b
Binary files /dev/null and b/src/JS08_Logo.ico differ
diff --git a/src/__main__.py b/src/__main__.py
deleted file mode 100644
index 31a8202..0000000
--- a/src/__main__.py
+++ /dev/null
@@ -1,9 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 2021-2022 Sijung Co., Ltd.
-#
-# Authors:
-# cotjdals5450@gmail.com (Seong Min Chae)
-# 5jx2oh@gmail.com (Jongjin Oh)
-
-import nd01
diff --git a/src/auto_file_delete.py b/src/auto_file_delete.py
new file mode 100644
index 0000000..62a770e
--- /dev/null
+++ b/src/auto_file_delete.py
@@ -0,0 +1,76 @@
+#!/usr/bin/env python3
+#
+# Copyright 2021-2022 9th grade 5th class.
+#
+# Authors:
+# 5jx2oh@gmail.com
+
+import os
+import psutil
+import shutil
+
+from PySide6.QtWidgets import (QDialog, QApplication, QMessageBox)
+
+from model import JS08Settings
+from resources.auto_file_delete import Ui_Form
+
+
+def byte_transform(bytes, to, bsize=1024):
+ """
+ Unit conversion of byte received from shutil
+
+ :return: Capacity of the selected unit (int)
+ """
+ unit = {'KB': 1, 'MB': 2, 'GB': 3, 'TB': 4}
+ r = float(bytes)
+ for i in range(unit[to]):
+ r = r / bsize
+ return int(r)
+
+
+def delete_select_date(path: str, folder: list):
+ """
+ Delete the list containing the folder name
+
+ :param path: Path to proceed with a auto-delete
+ :param folder: Data older than the date selected as the calendarWidget
+ """
+
+ # for i in range(len(folder)):
+ # a = os.path.join(path, str(folder[i]))
+ # shutil.rmtree(a)
+ # print(f'{a} delete complete.')
+ a = os.path.join(path, str(folder[0]))
+ print(f'{a} delete complete.')
+
+
+def check_file_date(path: str):
+ is_old = []
+
+ for f in os.listdir(path):
+ is_old.append(int(f))
+ delete_select_date(path, is_old)
+
+
+def FileAutoDelete():
+ save_disk = JS08Settings.get('image_save_path')[:2]
+
+ total, used, free = shutil.disk_usage(save_disk)
+ if JS08Settings.get('afd'):
+ if byte_transform(free, 'GB') <= 20:
+ check_disk()
+
+
+def check_disk():
+ check_file_date(os.path.join(JS08Settings.get('image_save_path'), 'vista',
+ JS08Settings.get('front_camera_name')))
+ print('-' * 10)
+ check_file_date(os.path.join(JS08Settings.get('image_save_path'), 'vista',
+ JS08Settings.get('rear_camera_name')))
+
+
+if __name__ == "__main__":
+ import sys
+
+ FileAutoDelete()
+ # sys.exit(app.exec())
diff --git a/src/cal_ext_coef.py b/src/cal_ext_coef.py
new file mode 100644
index 0000000..fe49e19
--- /dev/null
+++ b/src/cal_ext_coef.py
@@ -0,0 +1,99 @@
+#!/usr/bin/env python3
+#
+# Copyright 2021-2022 Sijung Co., Ltd.
+#
+# Authors:
+# cotjdals5450@gmail.com (Seong Min Chae)
+# 5jx2oh@gmail.com (Jongjin Oh)
+
+import itertools
+import os
+
+import time
+import numpy as np
+import pandas as pd
+import traceback
+
+from scipy.optimize import curve_fit
+from model import JS08Settings
+from save_log import log
+
+
+class Coef:
+
+ def __init__(self):
+ self.hanhwa_dist = []
+ self.hanhwa_x = []
+ self.hanhwa_r = []
+ self.hanhwa_g = []
+ self.hanhwa_b = []
+
+ def select_max_rgb(self, r, g, b):
+ c_list = [r, g, b]
+ c_index = c_list.index(max(c_list))
+
+ if c_index == 0:
+ select_color = 'red'
+ elif c_index == 1:
+ select_color = 'green'
+ else:
+ select_color = 'blue'
+
+ return select_color
+
+ def cal_curve(self, hanhwa: pd.DataFrame):
+ hanhwa = hanhwa.sort_values(by=['distance'])
+ self.hanhwa_dist = hanhwa[['distance']].squeeze().to_numpy()
+ self.hanhwa_x = np.linspace(self.hanhwa_dist[0], self.hanhwa_dist[-1], 100, endpoint=True)
+ self.hanhwa_x.sort()
+ self.hanhwa_r = hanhwa[['r']].squeeze().to_numpy()
+ self.hanhwa_g = hanhwa[['g']].squeeze().to_numpy()
+ self.hanhwa_b = hanhwa[['b']].squeeze().to_numpy()
+
+ r1_init = self.hanhwa_r[0] * 0.7
+ g1_init = self.hanhwa_g[0] * 0.7
+
+ b1_init = self.hanhwa_b[0] * 0.7
+ r2_init = self.hanhwa_r[-1] * 1.3
+ g2_init = self.hanhwa_g[-1] * 1.3
+ b2_init = self.hanhwa_b[-1] * 1.3
+
+ select_color = self.select_max_rgb(r2_init, g2_init, b2_init)
+
+ r_ext_init = [r1_init, r2_init, 1]
+ g_ext_init = [g1_init, g2_init, 1]
+ b_ext_init = [b1_init, b2_init, 1]
+
+ try:
+ hanhwa_opt_r, hanhwa_cov_r = curve_fit(self.func, self.hanhwa_dist, self.hanhwa_r, p0=r_ext_init, maxfev=5000)
+ hanhwa_opt_g, hanhwa_cov_g = curve_fit(self.func, self.hanhwa_dist, self.hanhwa_g, p0=g_ext_init, maxfev=5000)
+ hanhwa_opt_b, hanhwa_cov_b = curve_fit(self.func, self.hanhwa_dist, self.hanhwa_b, p0=b_ext_init, maxfev=5000)
+ JS08Settings.set('maxfev_flag', False)
+
+ except RuntimeError as e:
+ # print(f'[{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}] - {e}')
+ # JS08Settings.set('maxfev_flag', True)
+ # JS08Settings.set('maxfev_count', JS08Settings.get('maxfev_count') + 1)
+ log(JS08Settings.get('current_id'), 'maxfev Error')
+ return
+
+ list1 = []
+ list2 = []
+ list3 = []
+
+ list1.append(hanhwa_opt_r[0])
+ list1.append(hanhwa_opt_g[0])
+ list1.append(hanhwa_opt_b[0])
+
+ list2.append(hanhwa_opt_r[1])
+ list2.append(hanhwa_opt_g[1])
+ list2.append(hanhwa_opt_b[1])
+
+ list3.append(hanhwa_opt_r[2])
+ list3.append(hanhwa_opt_g[2])
+ list3.append(hanhwa_opt_b[2])
+
+ return list1, list2, list3, select_color
+
+ def func(self, x, c1, c2, a):
+ return c2 + (c1 - c2) * np.exp(-a * x)
diff --git a/src/calculation/curve_save.py b/src/calculation/curve_save.py
deleted file mode 100644
index 62bf6dd..0000000
--- a/src/calculation/curve_save.py
+++ /dev/null
@@ -1,124 +0,0 @@
-import itertools
-import os
-
-import numpy as np
-import pandas as pd
-
-import scipy
-from scipy.optimize import curve_fit
-from PyQt5 import QtWidgets, QtGui, QtCore
-
-curved_flag = True
-# cam_name = cam_name
-hanhwa_dist = []
-hanhwa_x = []
-hanhwa_r = []
-hanhwa_g = []
-hanhwa_b = []
-# epoch = epoch
-# rgbsavedir = os.path.join(f"rgb/{cam_name}")
-# extsavedir = os.path.join(f"extinction/{cam_name}")
-
-def select_max_rgb(r, g, b):
-
- select_color = ""
- c_list = [r, g, b]
-
- c_index = c_list.index(max(c_list))
-
- if c_index == 0:
- select_color = "red"
- elif c_index == 1:
- select_color = "green"
- else :
- select_color = "blue"
- return select_color
-
-def cal_curve(hanhwa: pd.DataFrame):
- # hanhwa = pd.read_csv(f"{rgbsavedir}/{epoch}.csv")
- print(hanhwa)
- hanhwa = hanhwa.sort_values(by=['distance'])
- hanhwa_dist = hanhwa[['distance']].squeeze().to_numpy()
- hanhwa_x = np.linspace(hanhwa_dist[0], hanhwa_dist[-1], 100, endpoint=True)
- hanhwa_x.sort()
- hanhwa_r = hanhwa[['r']].squeeze().to_numpy()
- hanhwa_g = hanhwa[['g']].squeeze().to_numpy()
- hanhwa_b = hanhwa[['b']].squeeze().to_numpy()
-
- r1_init = hanhwa_r[0] * 0.7
- g1_init = hanhwa_g[0] * 0.7
- b1_init = hanhwa_b[0] * 0.7
-
- r2_init = hanhwa_r[-1] * 1.3
- g2_init = hanhwa_g[-1] * 1.3
- b2_init = hanhwa_b[-1] * 1.3
-
- select_color = select_max_rgb(r2_init, g2_init, b2_init)
-
- r_ext_init = [r1_init, r2_init, 1]
- g_ext_init = [g1_init, g2_init, 1]
- b_ext_init = [b1_init, b2_init, 1]
-
- try:
-
- hanhwa_opt_r, hanhwa_cov_r = curve_fit(func, hanhwa_dist, hanhwa_r, p0=r_ext_init, maxfev=5000)
- hanhwa_opt_g, hanhwa_cov_g = curve_fit(func, hanhwa_dist, hanhwa_g, p0=g_ext_init, maxfev=5000)
- hanhwa_opt_b, hanhwa_cov_b = curve_fit(func, hanhwa_dist, hanhwa_b, p0=b_ext_init, maxfev=5000)
-
- except Exception as e:
- print("error msg: ", e)
- return
- list1 = []
- list2 = []
- list3 = []
-
- list1.append(hanhwa_opt_r[0])
- list1.append(hanhwa_opt_g[0])
- list1.append(hanhwa_opt_b[0])
-
- list2.append(hanhwa_opt_r[1])
- list2.append(hanhwa_opt_g[1])
- list2.append(hanhwa_opt_b[1])
-
- list3.append(hanhwa_opt_r[2])
- list3.append(hanhwa_opt_g[2])
- list3.append(hanhwa_opt_b[2])
-
- hanhwa_err_r = np.sqrt(np.diag(hanhwa_cov_r))
- hanhwa_err_g = np.sqrt(np.diag(hanhwa_cov_g))
- hanhwa_err_b = np.sqrt(np.diag(hanhwa_cov_b))
-
- print_result(hanhwa_opt_r, hanhwa_opt_g, hanhwa_opt_b, hanhwa_err_r, hanhwa_err_g, hanhwa_err_b)
-
- print(f"Red channel: {extcoeff_to_vis(hanhwa_opt_r[2], hanhwa_err_r[2], 3)} km")
- print(f"Green channel: {extcoeff_to_vis(hanhwa_opt_g[2], hanhwa_err_g[2], 3)} km")
- print(f"Blue channel: {extcoeff_to_vis(hanhwa_opt_b[2], hanhwa_err_b[2], 3)} km")
-
- return list1, list2, list3, select_color
- # update_extinc_signal.emit(list1, list2, list3, select_color)
-
- try:
- os.mkdir(extsavedir)
- except Exception as e:
- pass
-
-# @staticmethod
-def func(x, c1, c2, a):
- return c2 + (c1 - c2) * np.exp(-a * x)
-
-def print_result(opt_r, opt_g, opt_b, err_r, err_g, err_b):
- print(f"Red channel: (",
- f"C1: {opt_r[0]:.2f} ± {err_r[0]:.2f}, ",
- f"C2: {opt_r[1]:.2f} ± {err_r[1]:.2f}, ",
- f"alpha: {opt_r[2]:.2f} ± {err_r[2]:.2f})")
- print(f"Green channel: (",
- f"C1: {opt_g[0]:.2f} ± {err_g[0]:.2f}, ",
- f"C2: {opt_g[1]:.2f} ± {err_g[1]:.2f}, ",
- f"alpha: {opt_g[2]:.2f} ± {err_g[2]:.2f})")
- print(f"Blue channel: (",
- f"C1: {opt_b[0]:.2f} ± {err_b[0]:.2f}, ",
- f"C2: {opt_b[1]:.2f} ± {err_b[1]:.2f}, ",
- f"alpha: {opt_b[2]:.2f} ± {err_b[2]:.2f})")
-
-def extcoeff_to_vis(optimal, error, coeff=3.291):
- return coeff / (optimal + np.array((1, 0, -1)) * error)
diff --git a/src/calculation/gary_visibility.py b/src/calculation/gary_visibility.py
deleted file mode 100644
index 113eebf..0000000
--- a/src/calculation/gary_visibility.py
+++ /dev/null
@@ -1,106 +0,0 @@
-import itertools
-import os
-
-import numpy as np
-import pandas as pd
-
-import scipy
-from scipy.optimize import curve_fit
-import matplotlib
-import matplotlib.pyplot as plt
-
-
-def minprint(self):
- """지정한 구역들에서 소산계수 산출용 픽셀을 출력하는 함수"""
- result = ()
- cnt = 1
- min_x = []
- min_y = []
-
- for upper_left, lower_right in zip(left_range, right_range):
- result = minrgb(upper_left, lower_right)
- print(f"target{cnt}의 소산계수 검출용 픽셀위치 = ", result)
- min_x.append(result[0])
- min_y.append(result[1])
- cnt += 1
-
- get_rgb(epoch)
-
- curved_thread = CurvedThread(camera_name, epoch)
- curved_thread.update_extinc_signal.connect(extinc_print)
- curved_thread.run()
-
- list_test()
-
- graph_dir = os.path.join(f"extinction/{camera_name}")
-def minrgb(self, upper_left, lower_right):
- """드래그한 영역의 RGB 최솟값을 추출한다"""
-
- up_y = min(upper_left[1], lower_right[1])
- down_y = max(upper_left[1], lower_right[1])
-
- left_x = min(upper_left[0], lower_right[0])
- right_x = max(upper_left[0], lower_right[0])
-
- test = cp_image[up_y:down_y, left_x:right_x, :]
-
- # 드래그한 영역의 RGB 값을 각각 추출한다.
- # r = test[:, :]
- # g = test[:, :, 1]
- # b = test[:, :, 2]
-
- # RGB값을 각 위치별로 모두 더한다.
- # RGB 최댓값이 255로 정해져있어 값을 초과하면 0부터 시작된다. numpy의 clip 함수를 이용해 array의 최댓값을 수정한다.
- # r = np.clip(r, 0, 765)
- # sum_rgb = r + g + b
-
- # RGB 값을 합한 뒤 가장 최솟값의 index를 추출한다.
- t_idx = np.where(test == np.min(test))
-
- show_min_y = t_idx[0][0] + up_y
- show_min_x = t_idx[1][0] + left_x
-
- return (show_min_x, show_min_y)
-
-def get_rgb(self, epoch: str):
- r_list = []
- g_list = []
- b_list = []
-
- for x, y in zip(min_x, min_y):
-
- r_list.append(cp_image[y, x, 0])
- g_list.append(cp_image[y, x, 1])
- b_list.append(cp_image[y, x, 2])
-
- print("red : ", cp_image[y, x, 0])
- print("green : ", cp_image[y, x, 1])
- print("blue: ", cp_image[y, x, 2])
-
-
- save_rgb(r_list, g_list, b_list, epoch)
-
-def save_rgb(self, r_list, g_list, b_list, epoch):
- """Save the rgb information for each target."""
- try:
- save_path = os.path.join(f"rgb/{camera_name}")
- os.mkdir(save_path)
-
- except Exception as e:
- pass
-
- if r_list:
- r_list = list(map(int, r_list))
- g_list = list(map(int, g_list))
- b_list = list(map(int, b_list))
- print(b_list)
-
- col = ["target_name", "r", "g", "b", "distance"]
- result = pd.DataFrame(columns=col)
- result["target_name"] = target_name
- result["r"] = r_list
- result["g"] = g_list
- result["b"] = b_list
- result["distance"] = distance
- print(result.head(10))
- result.to_csv(f"{save_path}/{epoch}.csv", mode="w", index=False)
\ No newline at end of file
diff --git a/src/clock.py b/src/clock.py
new file mode 100644
index 0000000..1ff306a
--- /dev/null
+++ b/src/clock.py
@@ -0,0 +1,21 @@
+#!/usr/bin/env python3
+#
+# Copyright 2021-2022 Sijung Co., Ltd.
+#
+# Authors:
+# cotjdals5450@gmail.com (Seong Min Chae)
+# 5jx2oh@gmail.com (Jongjin Oh)
+
+import time
+
+
+def clock_clock(queue):
+ """Real-time clock
+ Current time to be expressed on JS-08
+
+ :param queue: MultiProcessing Queue
+ """
+ while True:
+ now = str(time.time())
+ queue.put(now)
+ time.sleep(1)
diff --git a/src/consumer.py b/src/consumer.py
new file mode 100644
index 0000000..a90b7a0
--- /dev/null
+++ b/src/consumer.py
@@ -0,0 +1,33 @@
+#!/usr/bin/env python3
+#
+# Copyright 2021-2022 Sijung Co., Ltd.
+#
+# Authors:
+# cotjdals5450@gmail.com (Seong Min Chae)
+# 5jx2oh@gmail.com (Jongjin Oh)
+
+from PySide6.QtCore import QThread, Signal
+
+
+class Consumer(QThread):
+ poped = Signal(str)
+
+ def __init__(self, q):
+ super().__init__()
+ self.q = q
+ self.running = True
+
+ def run(self):
+ while self.running:
+ if not self.q.empty():
+ data = self.q.get()
+ self.poped.emit(data)
+
+ def pause(self):
+ self.running = False
+
+ def resume(self):
+ self.running = True
+
+ def stop(self):
+ self.terminate()
\ No newline at end of file
diff --git a/src/controller.py b/src/controller.py
deleted file mode 100644
index 2372a69..0000000
--- a/src/controller.py
+++ /dev/null
@@ -1,525 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 2020-2021 Sijung Co., Ltd.
-#
-# Authors:
-# ruddyscent@gmail.com (Kyungwon Chun)
-# 5jx2oh@gmail.com (Jongjin Oh)
-
-import json
-import os
-import sys
-from typing import List
-
-import cv2
-import numpy as np
-# import onnxruntime as ort
-
-from PyQt5.QtCore import (QDateTime, QDir, QObject, QRect, QThread,
- QThreadPool, QTime, QTimer, pyqtSignal, pyqtSlot)
-from PyQt5.QtGui import QImage
-from PyQt5.QtMultimedia import QVideoFrame
-
-# from .model import (Js08AttrModel, Js08CameraTableModel, Js08IoRunner,
-# Js08Settings, Js08SimpleTarget, Js08Wedge)
-
-
-class MainCtrl(QObject):
- abnormal_shutdown = pyqtSignal()
- front_camera_changed = pyqtSignal(str) # uri
- rear_camera_changed = pyqtSignal(str) # uri
- front_target_decomposed = pyqtSignal()
- rear_target_decomposed = pyqtSignal()
- target_assorted = pyqtSignal(list, list) # positives, negatives
- wedge_vis_ready = pyqtSignal(int, dict) # epoch, wedge visibility
-
- # def __init__(self, model: Js08AttrModel):
- def __init__(self):
- super().__init__()
-
- self.writer_pool = QThreadPool.globalInstance()
- self.writer_pool.setMaxThreadCount(1)
-
- self._model = model
-
- self.num_working_cam = 0
-
- self.front_simple_targets = []
- self.rear_simple_targets = []
-
- self.front_target_prepared = False
- self.rear_target_prepared = False
-
- self.init_db()
-
- self.observation_timer = QTimer(self)
- # self.front_camera_changed.connect(self.decompose_front_targets)
- # self.rear_camera_changed.connect(self.decompose_rear_targets)
-
- self.worker_running = False
- self.start_observation_timer()
-
- def init_db(self):
- db_host = Js08Settings.get('db_host')
- db_port = Js08Settings.get('db_port')
- db_name = Js08Settings.get('db_name')
- self._model.connect_to_db(db_host, db_port, db_name)
-
- if getattr(sys, 'frozen', False):
- directory = sys._MEIPASS
- else:
- directory = os.path.dirname(__file__)
- attr_path = os.path.join(directory, 'resources', 'attr.json')
- with open(attr_path, 'r') as f:
- attr_json = json.load(f)
- camera_path = os.path.join(directory, 'resources', 'camera.json')
- with open(camera_path, 'r') as f:
- camera_json = json.load(f)
-
- self._model.setup_db(attr_json, camera_json)
-
- @pyqtSlot(str)
- def decompose_front_targets(self, _: str) -> None:
- """Make list of SimpleTarget by decoposing compound targets.
-
- Parameters:
- """
- self.front_target_prepared = False
- # self.decompose_targets('front')
- self.front_target_prepared = True
-
- @pyqtSlot(str)
- def decompose_rear_targets(self, _: str) -> None:
- """Make list of SimpleTarget by decoposing compound targets.
-
- Parameters:
- """
- self.rear_target_prepared = False
- # self.decompose_targets('rear')
- self.rear_target_prepared = True
-
- def decompose_targets(self, direction: str) -> None:
- """Make list of SimpleTarget by decoposing compound targets.
-
- Parameters:
- direction: 'front' or 'rear', default is 'front'
- """
- decomposed_targets = []
- attr = self._model.read_attr()
- if direction == 'front':
- targets = attr['front_camera']['targets']
- id = str(attr['front_camera']['camera_id'])
- elif direction == 'rear':
- targets = attr['rear_camera']['targets']
- id = str(attr['rear_camera']['camera_id'])
-
- base_path = Js08Settings.get('image_base_path')
-
- # Prepare model.
- # TODO(Kyungwon): Put the model file into Qt Resource Collection.
- if getattr(sys, 'frozen', False):
- directory = sys._MEIPASS
- else:
- directory = os.path.dirname(__file__)
- model_path = os.path.join(directory, 'resources', 'js08_1636343249.onnx')
- providers = ['CPUExecutionProvider']
- sess = ort.InferenceSession(model_path, providers=providers)
- input_shape = sess.get_inputs()[0].shape
- input_height = input_shape[1]
- input_width = input_shape[2]
-
- for tg in targets:
- wedge = tg['wedge']
- azimuth = tg['azimuth']
- point = tg['roi']['point']
- size = tg['roi']['size']
- roi = QRect(*point, *size)
-
- for i in range(len(tg['mask'])):
- label = f"{tg['label']}-{i}"
- distance = tg['distance'][i]
- mask_path = os.path.join(base_path, 'mask', id, tg['mask'][i])
- mask = self.read_mask(mask_path)
- st = Js08SimpleTarget(label, wedge, azimuth, distance, roi, mask, input_width, input_height)
- decomposed_targets.append(st)
-
- if direction == 'front':
- self.front_simple_targets = decomposed_targets
- elif direction == 'rear':
- self.rear_simple_targets = decomposed_targets
-
- def read_mask(self, path: str) -> np.ndarray:
- """Read mask image and return
-
- Parameters:
- path: path to mask file
- """
- attr = self._model.read_attr()
- front_id = str(attr['front_camera']['camera_id'])
- rear_id = str(attr['rear_camera']['camera_id'])
-
- basepath = Js08Settings.get('image_base_path')
- front_dir = os.path.join(basepath, 'mask', front_id)
- rear_dir = os.path.join(basepath, 'mask', rear_id)
- os.makedirs(front_dir, exist_ok=True)
- os.makedirs(rear_dir, exist_ok=True)
-
- with open(path, 'rb') as f:
- content = f.read()
- image = QImage()
- image.loadFromData(content)
- return image
-
- def start_observation_timer(self) -> None:
- print('DEBUG(start_observation_timer):', QTime.currentTime().toString())
- self.observation_timer.setInterval(1000) # every one second
- self.observation_timer.timeout.connect(self.start_worker)
- self.observation_timer.start()
-
- @pyqtSlot()
- def start_worker(self) -> None:
- # if decomposed targets are not ready, quit.
- if self.front_target_prepared is False or self.rear_target_prepared is False:
- return
-
- # If broker is already running, quit.
- if self.worker_running:
- return
- else:
- self.worker_running = True
-
- self.epoch = QDateTime.currentSecsSinceEpoch()
- front_uri = self.get_front_camera_uri()
- rear_uri = self.get_rear_camera_uri()
- self.worker = Js08InferenceWorker(
- self.epoch,
- front_uri,
- rear_uri,
- self.front_simple_targets,
- self.rear_simple_targets
- )
- self.worker_thread = QThread()
- self.worker.moveToThread(self.worker_thread)
- self.worker_thread.started.connect(self.worker.run)
- self.worker.finished.connect(self.worker_thread.quit)
- self.worker.finished.connect(self.postproduction)
- self.worker.finished.connect(self.finalize_broker)
- self.worker_thread.start()
-
- @pyqtSlot()
- def finalize_broker(self):
- self.worker_running = False
-
- @pyqtSlot()
- def postproduction(self):
- """
- epoch: seconds since epoch
- """
- epoch = self.epoch
-
- pos, neg = self.assort_discernment()
- self.target_assorted.emit(pos, neg)
- wedge_vis = self.wedge_visibility()
- self.wedge_vis_ready.emit(epoch, wedge_vis)
- self.write_visibilitiy(epoch, wedge_vis)
- self._model.write_discernment(epoch, self.front_simple_targets, self.rear_simple_targets)
-
- @pyqtSlot()
- def stop_timer(self) -> None:
- self.observation_timer.stop()
-
- def assort_discernment(self) -> tuple:
- """Assort targets in positive or negative according to the discernment result
- """
- pos, neg = [], []
-
- for t in self.front_simple_targets:
- point = (t.azimuth, t.distance)
- if t.discernment:
- pos.append(point)
- else:
- neg.append(point)
-
- for t in self.rear_simple_targets:
- point = (t.azimuth, t.distance)
- if t.discernment:
- pos.append(point)
- else:
- neg.append(point)
-
- return pos, neg
-
- def write_visibilitiy(self, epoch: int, wedge_visibility: dict) -> None:
- wedge_visibility = wedge_visibility.copy()
- vis_list = list(wedge_visibility.values())
- prevailing = self.prevailing_visibility(vis_list)
- wedge_visibility['epoch'] = epoch
- wedge_visibility['prevailing'] = prevailing
- print('DEBUG:', wedge_visibility)
- self._model.write_visibility(wedge_visibility)
-
- def wedge_visibility(self) -> dict:
- wedge_vis = {w: None for w in Js08Wedge}
- for t in self.front_simple_targets:
- if t.discernment:
- if wedge_vis[t.wedge] == None:
- wedge_vis[t.wedge] = t.distance
- elif wedge_vis[t.wedge] < t.distance:
- wedge_vis[t.wedge] = t.distance
- for t in self.rear_simple_targets:
- if t.discernment:
- if wedge_vis[t.wedge] == None:
- wedge_vis[t.wedge] = t.distance
- elif wedge_vis[t.wedge] < t.distance:
- wedge_vis[t.wedge] = t.distance
- return wedge_vis
-
- def prevailing_visibility(self, wedge_vis: list) -> float:
- if None in wedge_vis:
- return None
- sorted_vis = sorted(wedge_vis, reverse=True)
- prevailing = sorted_vis[(len(sorted_vis) - 1) // 2]
- return prevailing
-
- def save_image(self, dir: str, filename: str, image: QImage) -> None:
- os.makedirs(dir, exist_ok=True)
- path = QDir.cleanPath(os.path.join(dir, filename))
- runner = Js08IoRunner(path, image)
- self.writer_pool.start(runner)
-
- def grab_image(self, direction: str) -> QImage:
- """
- Parameters:
- direction: 'front' or 'rear'
- """
- if direction == 'front':
- uri = self.get_front_camera_uri()
- elif direction == 'rear':
- uri = self.get_rear_camera_uri()
- cap = cv2.VideoCapture(uri)
- ret, frame = cap.read()
- image = None
- if ret:
- frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
- image = QImage(frame, frame.shape[1], frame.shape[0], QImage.Format_RGB888)
- return image
-
- @pyqtSlot()
- def get_front_camera_uri(self) -> str:
- attr = self._model.read_attr()
- return attr['front_camera']['uri']
-
- @pyqtSlot()
- def get_rear_camera_uri(self) -> str:
- attr = self._model.read_attr()
- return attr['rear_camera']['uri']
-
- def get_target(self, direction: str) -> list:
- attr = self._model.read_attr()
- return attr[f'{direction}_camera']['targets']
-
- def get_camera_table_model(self) -> dict:
- cameras = self.get_cameras()
- table_model = Js08CameraTableModel(cameras)
- return table_model
-
- def check_exit_status(self) -> bool:
- normal_exit = Js08Settings.get('normal_shutdown')
- Js08Settings.set('normal_shutdown', False)
- return normal_exit
-
- def update_cameras(self, cameras: list, update_target: bool = False) -> None:
- # Remove deleted cameras
- cam_id_in_db = [cam["_id"] for cam in self._model.read_cameras()]
- cam_id_in_arg = [cam["_id"] for cam in cameras]
- for cam_id in cam_id_in_db:
- if cam_id not in cam_id_in_arg:
- self._model.delete_camera(cam_id)
-
- # if `cameras` does not have 'targets' field, add an empty list for it.
- for cam in cameras:
- if 'targets' not in cam:
- cam['targets'] = []
-
- # Copy targets if `update_target` is False.
- if update_target == False:
- cam_in_db = self._model.read_cameras()
- for c_db in cam_in_db:
- for c_arg in cameras:
- if c_arg['_id'] == c_db['_id']:
- c_arg['targets'] = c_db['targets']
- continue
-
- # if '_id' is empty, delete the field
- for cam in cameras:
- if not cam['_id']:
- del cam['_id']
-
- # Update existing camera or Insert new cameras
- for cam in cameras:
- self._model.upsert_camera(cam)
-
- @pyqtSlot()
- def close_process(self) -> None:
- Js08Settings.set('normal_shutdown', True)
-
- def get_attr(self) -> dict:
- attr_doc = self._model.read_attr()
- # attr_doc = None
- # if self._attr.count_documents({}):
- # attr_doc = list(self._attr.find().sort("_id", -1).limit(1))[0]
- return attr_doc
-
- def insert_attr(self, model: dict) -> None:
- self._model.insert_attr(model)
-
- @pyqtSlot()
- def restore_defaults(self) -> None:
- Js08Settings.restore_defaults()
-
- @pyqtSlot(bool)
- def set_normal_shutdown(self) -> None:
- Js08Settings.set('normal_shutdown', True)
-
- def get_cameras(self) -> list:
- return self._model.read_cameras()
-
-
-class Js08InferenceWorker(QObject):
- finished = pyqtSignal()
-
- def __init__(self, epoch: int, front_uri: str, rear_uri: str, front_decomposed_targets: list, rear_decomposed_targets: list) -> None:
- """
- Parameters:
- ctrl:
- """
- super().__init__()
-
- # TODO(Kyungwon): Put the model file into Qt Resource Collection.
- if getattr(sys, 'frozen', False):
- directory = sys._MEIPASS
- else:
- directory = os.path.dirname(__file__)
-
- self.epoch = epoch
- self.front_uri = front_uri
- self.rear_uri = rear_uri
- self.front_targets = front_decomposed_targets
- self.rear_targets = rear_decomposed_targets
-
- self.batch_size = Js08Settings.get('inference_batch_size')
-
- # Prepare model.
- model_path = os.path.join(directory, 'resources', 'js08_1636343249.onnx')
- providers = ['CPUExecutionProvider']
- self.session = ort.InferenceSession(model_path, providers=providers)
-
- # Prepare mask array.
- input_shape = self.session.get_inputs()[0].shape
- self.input_height = input_shape[1]
- self.input_width = input_shape[2]
-
- def grab_image(self, uri: str) -> QImage:
- """
- Parameters:
- uri: URI of a video stream
- """
- cap = cv2.VideoCapture(uri)
- ret, frame = cap.read()
- image = None
- if ret:
- frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
- image = QImage(frame, frame.shape[1], frame.shape[0], QImage.Format_RGB888)
- return image
-
- def save_image(self, dir: str, filename: str, image: QImage) -> None:
- os.makedirs(dir, exist_ok=True)
- path = QDir.cleanPath(os.path.join(dir, filename))
- image.save(path)
-
- def classify_image(self, image: np.ndarray) -> np.ndarray:
- """Discriminate the image.
-
- Return 1 if the model can discriminate the image, 0 otherwise.
- """
- input_data = image
- input_name = self.session.get_inputs()[0].name
- output_data = self.session.run(None, {input_name: input_data})
- tops = np.argmax(output_data, axis=-1)
- return np.squeeze(tops)
-
- def run(self):
- front_image = self.grab_image(self.front_uri)
- rear_image = self.grab_image(self.rear_uri)
-
- if front_image is None:
- print('DEBUG: Failed to capture the front video stream')
- self.finished.emit()
- return
-
- if rear_image is None:
- print('DEBUG: Failed to capture the rear video stream')
- self.finished.emit()
- return
-
- if Js08Settings.get('save_vista'):
- basepath = Js08Settings.get('image_base_path')
- now = QDateTime.fromSecsSinceEpoch(self.epoch)
- dir = os.path.join(basepath, 'vista', now.toString("yyyy-MM-dd"))
- filename = f'vista-front-{now.toString("yyyy-MM-dd-hh-mm")}.png'
- self.save_image(dir, filename, front_image)
- filename = f'vista-rear-{now.toString("yyyy-MM-dd-hh-mm")}.png'
- self.save_image(dir, filename, rear_image)
-
- # Discriminate the targets of front camera
- self.classify_batch(self.front_targets, front_image)
-
- # Discriminate the targets of rear camera
- self.classify_batch(self.rear_targets, rear_image)
-
- self.finished.emit()
-
- def classify_batch(self, targets: List[Js08SimpleTarget], vista: QImage):
- """Discriminate image batch
-
- Parameters:
- targets: List of Js08SimpleTarget
- vista: QImage
- """
- save_target_clip = Js08Settings.get('save_target_clip')
- if save_target_clip:
- basepath = Js08Settings.get('image_base_path')
- dir = os.path.join(basepath, 'target', str(self.epoch))
- os.makedirs(dir, exist_ok=True)
- masked_img_list = []
-
- padding_size = -len(targets) % self.batch_size
- result = np.zeros(len(targets) + padding_size)
- for i, target in enumerate(targets):
- if i % self.batch_size == 0:
- data = np.zeros(
- (self.batch_size, self.input_height, self.input_width, 3),
- dtype=np.float32
- )
-
- roi_image = target.clip_roi(vista)
- arr = target.img_to_arr(roi_image, self.input_width, self.input_height)
- masked_arr = arr * target.mask
- data[i % self.batch_size] = masked_arr
-
- if save_target_clip:
- masked_img = target.arr_to_img(masked_arr)
- masked_img_list.append(masked_img)
-
- if i % self.batch_size == self.batch_size - 1:
- result[i - self.batch_size + 1: i + 1] = self.classify_image(data)
- elif i == len(targets) - 1:
- chunk_size = len(targets) % self.batch_size
- result[i - chunk_size + 1:] = self.classify_image(data)
-
- for i, target in enumerate(targets):
- target.discernment = bool(result[i] == 1)
- if save_target_clip:
- postfix = 'pos' if target.discernment else 'neg'
- filename = f'{target.label}_{postfix}.png'
- self.save_image(dir, filename, masked_img_list[i])
\ No newline at end of file
diff --git a/src/curve_save.py b/src/curve_save.py
deleted file mode 100644
index 62bf6dd..0000000
--- a/src/curve_save.py
+++ /dev/null
@@ -1,124 +0,0 @@
-import itertools
-import os
-
-import numpy as np
-import pandas as pd
-
-import scipy
-from scipy.optimize import curve_fit
-from PyQt5 import QtWidgets, QtGui, QtCore
-
-curved_flag = True
-# cam_name = cam_name
-hanhwa_dist = []
-hanhwa_x = []
-hanhwa_r = []
-hanhwa_g = []
-hanhwa_b = []
-# epoch = epoch
-# rgbsavedir = os.path.join(f"rgb/{cam_name}")
-# extsavedir = os.path.join(f"extinction/{cam_name}")
-
-def select_max_rgb(r, g, b):
-
- select_color = ""
- c_list = [r, g, b]
-
- c_index = c_list.index(max(c_list))
-
- if c_index == 0:
- select_color = "red"
- elif c_index == 1:
- select_color = "green"
- else :
- select_color = "blue"
- return select_color
-
-def cal_curve(hanhwa: pd.DataFrame):
- # hanhwa = pd.read_csv(f"{rgbsavedir}/{epoch}.csv")
- print(hanhwa)
- hanhwa = hanhwa.sort_values(by=['distance'])
- hanhwa_dist = hanhwa[['distance']].squeeze().to_numpy()
- hanhwa_x = np.linspace(hanhwa_dist[0], hanhwa_dist[-1], 100, endpoint=True)
- hanhwa_x.sort()
- hanhwa_r = hanhwa[['r']].squeeze().to_numpy()
- hanhwa_g = hanhwa[['g']].squeeze().to_numpy()
- hanhwa_b = hanhwa[['b']].squeeze().to_numpy()
-
- r1_init = hanhwa_r[0] * 0.7
- g1_init = hanhwa_g[0] * 0.7
- b1_init = hanhwa_b[0] * 0.7
-
- r2_init = hanhwa_r[-1] * 1.3
- g2_init = hanhwa_g[-1] * 1.3
- b2_init = hanhwa_b[-1] * 1.3
-
- select_color = select_max_rgb(r2_init, g2_init, b2_init)
-
- r_ext_init = [r1_init, r2_init, 1]
- g_ext_init = [g1_init, g2_init, 1]
- b_ext_init = [b1_init, b2_init, 1]
-
- try:
-
- hanhwa_opt_r, hanhwa_cov_r = curve_fit(func, hanhwa_dist, hanhwa_r, p0=r_ext_init, maxfev=5000)
- hanhwa_opt_g, hanhwa_cov_g = curve_fit(func, hanhwa_dist, hanhwa_g, p0=g_ext_init, maxfev=5000)
- hanhwa_opt_b, hanhwa_cov_b = curve_fit(func, hanhwa_dist, hanhwa_b, p0=b_ext_init, maxfev=5000)
-
- except Exception as e:
- print("error msg: ", e)
- return
- list1 = []
- list2 = []
- list3 = []
-
- list1.append(hanhwa_opt_r[0])
- list1.append(hanhwa_opt_g[0])
- list1.append(hanhwa_opt_b[0])
-
- list2.append(hanhwa_opt_r[1])
- list2.append(hanhwa_opt_g[1])
- list2.append(hanhwa_opt_b[1])
-
- list3.append(hanhwa_opt_r[2])
- list3.append(hanhwa_opt_g[2])
- list3.append(hanhwa_opt_b[2])
-
- hanhwa_err_r = np.sqrt(np.diag(hanhwa_cov_r))
- hanhwa_err_g = np.sqrt(np.diag(hanhwa_cov_g))
- hanhwa_err_b = np.sqrt(np.diag(hanhwa_cov_b))
-
- print_result(hanhwa_opt_r, hanhwa_opt_g, hanhwa_opt_b, hanhwa_err_r, hanhwa_err_g, hanhwa_err_b)
-
- print(f"Red channel: {extcoeff_to_vis(hanhwa_opt_r[2], hanhwa_err_r[2], 3)} km")
- print(f"Green channel: {extcoeff_to_vis(hanhwa_opt_g[2], hanhwa_err_g[2], 3)} km")
- print(f"Blue channel: {extcoeff_to_vis(hanhwa_opt_b[2], hanhwa_err_b[2], 3)} km")
-
- return list1, list2, list3, select_color
- # update_extinc_signal.emit(list1, list2, list3, select_color)
-
- try:
- os.mkdir(extsavedir)
- except Exception as e:
- pass
-
-# @staticmethod
-def func(x, c1, c2, a):
- return c2 + (c1 - c2) * np.exp(-a * x)
-
-def print_result(opt_r, opt_g, opt_b, err_r, err_g, err_b):
- print(f"Red channel: (",
- f"C1: {opt_r[0]:.2f} ± {err_r[0]:.2f}, ",
- f"C2: {opt_r[1]:.2f} ± {err_r[1]:.2f}, ",
- f"alpha: {opt_r[2]:.2f} ± {err_r[2]:.2f})")
- print(f"Green channel: (",
- f"C1: {opt_g[0]:.2f} ± {err_g[0]:.2f}, ",
- f"C2: {opt_g[1]:.2f} ± {err_g[1]:.2f}, ",
- f"alpha: {opt_g[2]:.2f} ± {err_g[2]:.2f})")
- print(f"Blue channel: (",
- f"C1: {opt_b[0]:.2f} ± {err_b[0]:.2f}, ",
- f"C2: {opt_b[1]:.2f} ± {err_b[1]:.2f}, ",
- f"alpha: {opt_b[2]:.2f} ± {err_b[2]:.2f})")
-
-def extcoeff_to_vis(optimal, error, coeff=3.291):
- return coeff / (optimal + np.array((1, 0, -1)) * error)
diff --git a/src/curve_thread.py b/src/curve_thread.py
new file mode 100644
index 0000000..63f7216
--- /dev/null
+++ b/src/curve_thread.py
@@ -0,0 +1,29 @@
+#!/usr/bin/env python3
+#
+# Copyright 2021-2022 Sijung Co., Ltd.
+#
+# Authors:
+# cotjdals5450@gmail.com (Seong Min Chae)
+# 5jx2oh@gmail.com (Jongjin Oh)
+
+from multiprocessing import Queue
+
+from PySide6.QtCore import QThread, Signal
+
+
+class CurveThread(QThread):
+ poped = Signal(dict)
+
+ def __init__(self, _q: Queue = None):
+ super().__init__()
+ self.q = _q
+
+ def run(self):
+ while True:
+ if not self.q.empty():
+ visibility = self.q.get()
+ self.poped.emit(visibility)
+
+ def stop(self):
+ """Sets run flag to False and waits for thread to finish"""
+ self.terminate()
diff --git a/src/discernment_view.py b/src/discernment_view.py
new file mode 100644
index 0000000..505bfe8
--- /dev/null
+++ b/src/discernment_view.py
@@ -0,0 +1,175 @@
+#!/usr/bin/env python3
+#
+# Copyright 2021-2022 Sijung Co., Ltd.
+#
+# Authors:
+# cotjdals5450@gmail.com (Seong Min Chae)
+# 5jx2oh@gmail.com (Jongjin Oh)
+
+import time
+import numpy as np
+import random
+
+from PySide6.QtGui import QPainter, QColor, QBrush, QPen, QFont
+from PySide6.QtWidgets import QWidget
+from PySide6.QtCore import Qt, QPointF
+from PySide6.QtCharts import (QChartView, QLegend, QLineSeries,
+ QPolarChart, QValueAxis, QChart,
+ QAreaSeries, QCategoryAxis)
+from model import JS08Settings
+
+
+class DiscernmentView(QChartView):
+
+ def __init__(self, parent: QWidget):
+
+ super().__init__(parent)
+ self.setRenderHint(QPainter.Antialiasing)
+ self.setMinimumSize(200, 200)
+ self.setMaximumSize(600, 400)
+
+ # chart = QPolarChart(title='Discernment Visibility')
+ chart = QPolarChart()
+ # chart.legend().setAlignment(Qt.AlignRight)
+ chart.legend().setVisible(False)
+ # chart.legend().setMarkerShape(QLegend.MarkerShapeCircle)
+ self.setChart(chart)
+ self.chart().setTheme(QChart.ChartThemeDark)
+ self.chart().setBackgroundBrush(QBrush(QColor('#16202a')))
+
+ self.past_dataDist = None
+
+ self.axis_x = QValueAxis()
+ self.axis_x.setTickCount(9)
+ self.axis_x.setRange(0, 360)
+ self.axis_x.setLabelFormat('%d \xc2\xb0')
+
+ self.axis_distance = QCategoryAxis()
+ self.axis_distance.setLabelsPosition(QCategoryAxis.AxisLabelsPositionOnValue)
+ self.axis_distance.setRange(0, 360)
+ self.axis_distance.setLabelsFont(QFont('Noto Sans', 15))
+
+ data = np.arange(22.5, 360, 45)
+ self.dataName = ['NE', 'EN', 'ES', 'SE', 'SW', 'WS', 'WN', 'NW']
+ self.dataDist = [0, 0, 0, 0, 0, 0, 0, 0]
+
+ for name, dist, dt in zip(self.dataName, self.dataDist, data):
+ self.axis_distance.append(f'{name} ({dist})', dt)
+ self.axis_distance.setGridLineVisible(False)
+ self.axis_distance.setLineVisible(False)
+
+ self.axis_y = QValueAxis()
+ self.axis_y.setRange(0, 20)
+ self.axis_y.setMax(20)
+ self.axis_y.setLabelFormat('%d km')
+ # axis_y.setTitleText('Distance (km)')
+ # axis_y.setTitleVisible(False)
+ # chart.setAxisY(self.axis_y, self.series)
+
+ self.lowerLine = QLineSeries()
+ self.upperLine = QLineSeries()
+ # self.upperLine.attachAxis(self.axis_x)
+ # self.upperLine.attachAxis(self.axis_y)
+
+ for i in range(0, 46):
+ self.upperLine.append(i, 0)
+ for i in range(45, 91):
+ self.upperLine.append(i, 0)
+ for i in range(90, 136):
+ self.upperLine.append(i, 0)
+ for i in range(135, 181):
+ self.upperLine.append(i, 0)
+ for i in range(180, 226):
+ self.upperLine.append(i, 0)
+ for i in range(226, 271):
+ self.upperLine.append(i, 0)
+ for i in range(270, 316):
+ self.upperLine.append(i, 0)
+ for i in range(315, 361):
+ self.upperLine.append(i, 0)
+
+ self.area = QAreaSeries()
+ self.area.setLowerSeries(self.lowerLine)
+ self.area.setUpperSeries(self.upperLine)
+ self.area.setOpacity(0.7)
+
+ chart.addSeries(self.area)
+ # chart.addAxis(self.axis_x, QPolarChart.PolarOrientationAngular)
+ chart.addAxis(self.axis_distance, QPolarChart.PolarOrientationAngular)
+ # chart.addAxis(self.axis_y, QPolarChart.PolarOrientationRadial)
+ chart.setAxisX(self.axis_x, self.area)
+ chart.setAxisY(self.axis_y, self.area)
+
+ def refresh_stats(self, data: dict):
+
+ self.upperLine.clear()
+ del data['visibility_front']
+ del data['visibility_rear']
+
+ dataDist = list(data.values())
+
+ for i in range(0, 46):
+ self.upperLine.append(i, data.get('NE'))
+ for i in range(45, 91):
+ self.upperLine.append(i, data.get('EN'))
+ for i in range(90, 136):
+ self.upperLine.append(i, data.get('ES'))
+ for i in range(135, 181):
+ self.upperLine.append(i, data.get('SE'))
+ for i in range(180, 226):
+ self.upperLine.append(i, data.get('SW'))
+ for i in range(226, 271):
+ self.upperLine.append(i, data.get('WS'))
+ for i in range(270, 316):
+ self.upperLine.append(i, data.get('WN'))
+ for i in range(315, 361):
+ self.upperLine.append(i, data.get('NW'))
+
+ if self.past_dataDist is None:
+ for name, dist, dt in zip(self.dataName, dataDist, data):
+ self.axis_distance.replaceLabel(f'{name} ({self.dataDist[self.dataName.index(name)]})',
+ f'{name} ({dist})')
+ else:
+ for name, dist, dt in zip(self.dataName, dataDist, data):
+ self.axis_distance.replaceLabel(f'{name} ({self.past_dataDist[self.dataName.index(name)]})',
+ f'{name} ({dist})')
+ self.past_dataDist = dataDist
+
+ def mousePressEvent(self, event):
+
+ # JS08Settings.set('maxfev_count', JS08Settings.get('maxfev_count') + 1)
+ # self.maxfev_time.append(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
+ # JS08Settings.set('maxfev_time', self.maxfev_time)
+ # print(self.maxfev_time)
+
+ print(f'flag: {JS08Settings.get("maxfev_flag")}, count: {JS08Settings.get("maxfev_count")}')
+ # JS08Settings.add_maxfev_time(self.maxfev_time)
+ # print()
+ # print(f'time: {JS08Settings.get("maxfev_time")}')
+
+ # data = {'NE': round(random.uniform(10, 20), 3), 'EN': round(random.uniform(10, 20), 3),
+ # 'ES': round(random.uniform(10, 20), 3), 'SE': round(random.uniform(10, 20), 3),
+ # 'SW': round(random.uniform(10, 20), 3), 'WS': round(random.uniform(10, 20), 3),
+ # 'WN': round(random.uniform(10, 20), 3), 'NW': round(random.uniform(10, 20), 3)}
+ # self.refresh_stats(data)
+
+
+if __name__ == '__main__':
+
+ import sys
+ from PySide6.QtWidgets import QApplication, QMainWindow
+
+ visibility = {'visibility_front': 18.829, 'visibility_rear': 5.192,
+ 'NE': 20.000, 'EN': 7.208,
+ 'ES': 20.000, 'SE': 5.015,
+ 'SW': 2.613, 'WS': 20.000,
+ 'WN': 20.000, 'NW': 20.000}
+
+ app = QApplication(sys.argv)
+ window = QMainWindow()
+ window.resize(600, 400)
+ discernment_view = DiscernmentView(window)
+ discernment_view.refresh_stats(visibility)
+ window.setCentralWidget(discernment_view)
+ window.show()
+ sys.exit(app.exec())
diff --git a/src/image.png b/src/image.png
new file mode 100644
index 0000000..6d957e4
Binary files /dev/null and b/src/image.png differ
diff --git a/src/input_target.py b/src/input_target.py
new file mode 100644
index 0000000..9855d9f
--- /dev/null
+++ b/src/input_target.py
@@ -0,0 +1,44 @@
+#!/usr/bin/env python3
+#
+# Copyright 2021-2022 Sijung Co., Ltd.
+#
+# Authors:
+# cotjdals5450@gmail.com (Seong Min Chae)
+# 5jx2oh@gmail.com (Jongjin Oh)
+
+
+import sys
+
+from PySide6.QtWidgets import QDialog, QLineEdit, QDialogButtonBox, QFormLayout, QApplication
+from PySide6.QtGui import QIcon
+
+
+class InputTarget(QDialog):
+ def __init__(self, azimuth=''):
+ super().__init__()
+ self.setWindowTitle('거리 입력')
+ self.setWindowIcon(QIcon('resources/asset/logo.png'))
+
+ self.distance = QLineEdit(self)
+ self.azimuth = QLineEdit(self)
+ self.azimuth.setText(azimuth)
+ buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel, self)
+
+ layout = QFormLayout(self)
+ layout.addRow("거리(km)", self.distance)
+ layout.addRow("방위", self.azimuth)
+ layout.addWidget(buttonBox)
+
+ buttonBox.accepted.connect(self.accept)
+ buttonBox.rejected.connect(self.reject)
+
+ def getInputs(self):
+ return self.distance.text(), self.azimuth.text()
+
+
+if __name__ == '__main__':
+
+ app = QApplication(sys.argv)
+ dialog = InputTarget()
+ dialog.show()
+ sys.exit(app.exec())
diff --git a/src/js08.py b/src/js08.py
new file mode 100644
index 0000000..36132d4
--- /dev/null
+++ b/src/js08.py
@@ -0,0 +1,791 @@
+#!/usr/bin/env python3
+#
+# Copyright 2021-2023 Sijung Co., Ltd.
+#
+# Authors:
+# cotjdals5450@gmail.com (Seong Min Chae)
+# 5jx2oh@gmail.com (Jongjin Oh)
+
+
+import os
+import sys
+
+import vlc
+import time
+
+import numpy as np
+import pandas as pd
+import multiprocessing as mp
+from multiprocessing import Process, Queue
+
+from PySide6.QtGui import QPixmap, QIcon, QPainter, QPen
+from PySide6.QtWidgets import (QMainWindow, QWidget, QFrame, QMessageBox)
+from PySide6.QtCore import (Qt, Slot, QRect, QTimer, QObject, QDateTime)
+
+from login_view import LoginWindow
+from video_thread_mp import producer
+from log_view import LogView
+from js08_settings_admin import JS08AdminSettingWidget
+from js08_settings_user import JS08UserSettingWidget
+from curve_thread import CurveThread
+from clock import clock_clock
+from consumer import Consumer
+from thumbnail_view import ThumbnailView
+from auto_file_delete import FileAutoDelete
+
+from visibility_view import VisibilityView
+from discernment_view import DiscernmentView
+
+# UI
+from resources.main_window import Ui_MainWindow
+
+from save_log import log
+
+
+class JS08MainWindow(QMainWindow, Ui_MainWindow):
+
+ def __init__(self, q, _q):
+ super(JS08MainWindow, self).__init__()
+ self.setupUi(self)
+ self.setWindowIcon(QIcon('resources/asset/logo.png'))
+
+ login_window = LoginWindow()
+ login_window.exec()
+
+ if JS08Settings.get('right') != 'administrator':
+ self.log_view.setEnabled(False)
+ self.log_view.setVisible(False)
+ self.blank_label_3.setVisible(False)
+
+ p = Process(name='clock', target=clock_clock, args=(q,), daemon=True)
+ p.start()
+
+ self.consumer = Consumer(q)
+ self.consumer.poped.connect(self.clock)
+ self.consumer.start()
+
+ _producer = producer
+ _p = Process(name='producer', target=_producer, args=(_q,), daemon=True)
+ self.video_thread = CurveThread(_q)
+ self.video_thread.poped.connect(self.print_data)
+
+ if JS08Settings.get('first_step') is False:
+ _p.start()
+ self.video_thread.start()
+ log(JS08Settings.get('current_id'), 'Visibility Measurement start')
+
+ self.get_date = []
+ self.get_epoch = []
+ self.q_list = []
+ self.q_list_scale = 1440 # 60 * 24 = 1 day graph
+ self.result = pd.DataFrame
+
+ self._plot = VisibilityView(self, self.q_list_scale)
+ self._polar = DiscernmentView(self)
+
+ self.view = None
+ self.km_mile_convert = False
+
+ self.visibility = None
+ self.visibility_front = 0
+ self.prevailing_visibility = None
+ self.graph_visibility_value = []
+
+ self.year_date = None
+ self.data_date = []
+ self.data_time = []
+
+ self.front_video_widget = VideoWidget(self)
+ self.front_video_widget.on_camera_change(JS08Settings.get('front_main'))
+
+ self.rear_video_widget = VideoWidget(self)
+ self.rear_video_widget.on_camera_change(JS08Settings.get('rear_main'))
+
+ self.video_horizontalLayout.addWidget(self.front_video_widget.video_frame)
+ self.video_horizontalLayout.addWidget(self.rear_video_widget.video_frame)
+
+ self.graph_horizontalLayout.addWidget(self._plot)
+ self.polar_horizontalLayout.addWidget(self._polar)
+
+ self.setting_button.setIcon(QIcon('resources/asset/settings.png'))
+ self.setting_button.enterEvent = self.btn_on
+ self.setting_button.leaveEvent = self.btn_off
+
+ self.log_view.setIcon(QIcon('resources/asset/log.png'))
+ self.log_view.enterEvent = self.log_on
+ self.log_view.leaveEvent = self.log_off
+
+ # Azimuth paint event
+ self.front_label.paintEvent = self.front_label_paintEvent
+ self.rear_label.paintEvent = self.rear_label_paintEvent
+
+ self.setWindowIcon(QIcon('logo.ico'))
+ self.logo.setIcon(QIcon('resources/asset/f_logo.png'))
+ self.time_button.setIcon(QIcon('resources/asset/clock.png'))
+ self.timeseries_button_2.setIcon(QIcon('resources/asset/graph.png'))
+ self.timeseries_button.setIcon(QIcon('resources/asset/polar.png'))
+ self.prevailing_vis_button.setIcon(QIcon('resources/asset/vis.png'))
+ self.button.setIcon(QIcon('resources/asset/pre_vis_1.png'))
+ self.maxfev_alert.setIcon(QIcon('resources/asset/alert.png'))
+ self.maxfev_alert.setToolTip('Optimal parameters not found: Number of calls to function has reached max fev = 5000.')
+ self.maxfev_alert.setVisible(JS08Settings.get('maxfev_flag'))
+
+ self.click_style = 'border: 1px solid red;'
+
+ self.alert.clicked.connect(self.alert_test)
+
+ self.c_vis_label.mousePressEvent = self.unit_convert
+ self.p_vis_label.mousePressEvent = self.unit_convert
+
+ self.label_1hour.mouseDoubleClickEvent = self.thumbnail_click1
+ self.label_2hour.mouseDoubleClickEvent = self.thumbnail_click2
+ self.label_3hour.mouseDoubleClickEvent = self.thumbnail_click3
+ self.label_4hour.mouseDoubleClickEvent = self.thumbnail_click4
+ self.label_5hour.mouseDoubleClickEvent = self.thumbnail_click5
+ self.label_6hour.mouseDoubleClickEvent = self.thumbnail_click6
+
+ self.log_view.clicked.connect(self.log_btn_click)
+ self.setting_button.clicked.connect(self.setting_btn_click)
+
+ self.show()
+
+ def alert_test(self):
+ self.alert.setIcon(QIcon('resources/asset/red.png'))
+ try:
+ strFormat = '%-20s%-10s\n'
+ strOut = strFormat % ('Azimuth', 'Visibility (m)')
+ for k, v in self.visibility.items():
+ v = str(float(v))
+ strOut += strFormat % (k, v)
+ except AttributeError:
+ strOut = 'It has not measured yet.'
+ pass
+ vis = QMessageBox.about(None, '8-Way Visibility', f'{strOut}')
+ # vis.setStyleSheet('color:rgb(0,0,0);')
+ # vis.about(self, '8-Way Visibility', f'{strOut}')
+
+ def reset_StyleSheet(self):
+ self.label_1hour.setStyleSheet('')
+ self.label_2hour.setStyleSheet('')
+ self.label_3hour.setStyleSheet('')
+ self.label_4hour.setStyleSheet('')
+ self.label_5hour.setStyleSheet('')
+ self.label_6hour.setStyleSheet('')
+
+ def thumbnail_view(self, file_name: str):
+ self.view = ThumbnailView(file_name, int(file_name[2:8]))
+ self.view.setGeometry(QRect(self.video_horizontalLayout.geometry().x(),
+ self.video_horizontalLayout.geometry().y(),
+ self.video_horizontalLayout.geometry().width(),
+ self.video_horizontalLayout.geometry().height()))
+ self.view.setWindowFlags(Qt.WindowStaysOnTopHint | Qt.FramelessWindowHint)
+ self.view.setWindowModality(Qt.ApplicationModal)
+ self.view.show()
+ self.view.raise_()
+
+ def thumbnail_show(self):
+ self.reset_StyleSheet()
+ self.view.close()
+
+ def log_btn_click(self):
+ dlg = LogView()
+ dlg.show()
+ dlg.setWindowModality(Qt.ApplicationModal)
+ dlg.exec()
+
+ @Slot()
+ def setting_btn_click(self):
+ if JS08Settings.get('right') == 'administrator':
+ self.front_video_widget.media_player.stop()
+ self.rear_video_widget.media_player.stop()
+ self.consumer.pause()
+
+ dlg = JS08AdminSettingWidget()
+ dlg.show()
+ dlg.setWindowModality(Qt.ApplicationModal)
+ dlg.exec()
+
+ self.front_video_widget.media_player.play()
+ self.rear_video_widget.media_player.play()
+ self.consumer.resume()
+ self.consumer.start()
+
+ elif JS08Settings.get('right') == 'user':
+ # self.front_video_widget.media_player.stop()
+ # self.rear_video_widget.media_player.stop()
+ # self.consumer.pause()
+
+ dlg = JS08UserSettingWidget()
+ dlg.show()
+ dlg.setWindowModality(Qt.ApplicationModal)
+ dlg.exec()
+
+ # self.front_video_widget.media_player.play()
+ # self.rear_video_widget.media_player.play()
+ # self.consumer.resume()
+ # self.consumer.start()
+
+ def get_data(self, year, month_day):
+
+ save_path = os.path.join(f'{JS08Settings.get("data_csv_path")}/Prevailing_Visibility/{year}')
+
+ if os.path.isfile(f'{save_path}/{month_day}.csv'):
+ self.result = pd.read_csv(f'{save_path}/{month_day}.csv')
+ data_visibility = self.result['prev'].tolist()
+
+ return data_visibility
+
+ else:
+ return []
+
+ @Slot(str)
+ def print_data(self, visibility: dict):
+ """
+ A function that runs every minute, updating data such as visibility values
+
+ :param visibility: 8-degree Visibility value
+ """
+ FileAutoDelete()
+
+ self.convert_visibility(visibility)
+ visibility_front = visibility.get('visibility_front')
+ visibility_rear = visibility.get('visibility_rear')
+
+ # Graph Visibility value
+ self.graph_visibility_value.append(self.prevailing_visibility / 1000)
+ if len(self.graph_visibility_value) >= 10:
+ del self.graph_visibility_value[0]
+ plot_value = round(float(np.mean(self.graph_visibility_value)), 3)
+
+ epoch = QDateTime.currentSecsSinceEpoch()
+ current_time = time.strftime('%Y-%m-%d %H:%M:00', time.localtime(epoch))
+ _time = time.strftime('%Y%m%d%H%M%S', time.localtime(epoch))
+ year = current_time[:4]
+ md = current_time[5:7] + current_time[8:10]
+
+ # if _time[-4:] == '0000':
+ # self.front_video_widget.get_status()
+ # self.rear_video_widget.get_status()
+
+ self.q_list = self.get_data(year, md)
+
+ if len(self.q_list) == 0 or self.q_list_scale != len(self.q_list):
+ self.q_list = []
+ for i in range(self.q_list_scale):
+ # self.q_list.append(visibility_front)
+ # self.q_list.append(self.prevailing_visibility / 1000)
+ self.q_list.append(plot_value)
+ result_vis = np.mean(self.q_list)
+ else:
+ self.q_list.pop(0)
+ # self.q_list.append(visibility_front)
+ # self.q_list.append(self.prevailing_visibility / 1000)
+ self.q_list.append(plot_value)
+ result_vis = np.mean(self.q_list)
+
+ if len(self.data_date) >= self.q_list_scale:
+ self.data_date.pop(0)
+ self.data_time.pop(0)
+
+ self.data_date.append(current_time)
+ self.data_time.append(epoch * 1000.0)
+
+ save_path_front = os.path.join(
+ f'{JS08Settings.get("data_csv_path")}/{JS08Settings.get("front_camera_name")}/{year}')
+ save_path_rear = os.path.join(
+ f'{JS08Settings.get("data_csv_path")}/{JS08Settings.get("rear_camera_name")}/{year}')
+ save_path_prevailing = os.path.join(f'{JS08Settings.get("data_csv_path")}/Prevailing_Visibility/{year}')
+
+ file_front = f'{save_path_front}/{md}.csv'
+ file_rear = f'{save_path_rear}/{md}.csv'
+ file_prevailing = f'{save_path_prevailing}/{md}.csv'
+
+ result_front = pd.DataFrame(columns=['date', 'epoch', 'visibility', 'SW', 'WS', 'WN', 'NW'])
+ result_rear = pd.DataFrame(columns=['date', 'epoch', 'visibility', 'NE', 'EN', 'ES', 'SE'])
+ result_prevailing = pd.DataFrame(columns=['date', 'epoch', 'prev'])
+
+ if os.path.isfile(f'{file_front}') is False or os.path.isfile(f'{file_rear}') is False \
+ or os.path.isfile(f'{file_prevailing}') is False:
+ os.makedirs(f'{save_path_front}', exist_ok=True)
+ os.makedirs(f'{save_path_rear}', exist_ok=True)
+ os.makedirs(f'{save_path_prevailing}', exist_ok=True)
+ result_front.to_csv(f'{file_front}', mode='w', index=False)
+ result_rear.to_csv(f'{file_rear}', mode='w', index=False)
+ result_prevailing.to_csv(f'{file_prevailing}', mode='w', index=False)
+
+ try:
+ result_front['date'] = [self.data_date[-1]]
+ result_front['epoch'] = [self.data_time[-1]]
+ result_front['visibility'] = visibility_front
+ # result_front['visibility'] = plot_value
+ result_front['NE'] = visibility.get('NE')
+ result_front['EN'] = visibility.get('EN')
+ result_front['ES'] = visibility.get('ES')
+ result_front['SE'] = visibility.get('SE')
+
+ result_rear['date'] = [self.data_date[-1]]
+ result_rear['epoch'] = [self.data_time[-1]]
+ result_rear['visibility'] = visibility_rear
+ # result_rear['visibility'] = plot_value
+ result_rear['SW'] = visibility.get('SW')
+ result_rear['WS'] = visibility.get('WS')
+ result_rear['WN'] = visibility.get('WN')
+ result_rear['NW'] = visibility.get('NW')
+
+ result_prevailing['date'] = [self.data_date[-1]]
+ result_prevailing['epoch'] = [self.data_time[-1]]
+ result_prevailing['prev'] = round(self.prevailing_visibility / 1000, 3)
+
+ except TypeError as e:
+ # print(f'Occurred error ({current_time}) -\n{e}')
+ log(JS08Settings.get('current_id'), str(e))
+
+ result_rear.to_csv(f'{file_rear}', mode='a', index=False, header=False)
+ result_front.to_csv(f'{file_front}', mode='a', index=False, header=False)
+ result_prevailing.to_csv(f'{file_prevailing}', mode='a', index=False, header=False)
+
+ self.visibility_front = round(float(result_vis), 3)
+
+ self._plot.refresh_stats(self.data_time[-1], self.q_list)
+ self._polar.refresh_stats(visibility)
+
+ self.maxfev_alert.setVisible(JS08Settings.get('maxfev_flag'))
+
+ @Slot()
+ def clock(self, data):
+
+ current_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(float(data)))
+ self.year_date = current_time[2:4] + current_time[5:7] + current_time[8:10]
+ self.real_time_label.setText(current_time)
+
+ try:
+ if self.km_mile_convert:
+ self.c_vis_label.setText(f'{format(round(self.prevailing_visibility / 1609, 2), ",")} mile')
+
+ elif self.km_mile_convert is False:
+ if self.visibility is not None:
+ self.c_vis_label.setText(
+ f'{format(int(self.prevailing_visibility), ",")} m')
+ except TypeError as e:
+ log(JS08Settings.get('current_id'), str(e))
+
+ if current_time[-2:] == '00':
+ self.thumbnail_refresh()
+
+ if int(self.visibility_front * 1000) <= JS08Settings.get('visibility_alert_limit'):
+ self.alert.setIcon(QIcon('resources/asset/red.png'))
+ else:
+ self.alert.setIcon(QIcon('resources/asset/green.png'))
+
+ def convert_visibility(self, data: dict):
+ """
+ Function with airstrip visibility unit conversion algorithm applied.
+ Currently, 'JS-08' stores visibility values in dict format. It can be converted at once.
+
+ Notes
+ --------
+ - If visibility ranging from 0 m to less than 400 m, mark it in units of *25 m*.
+ - If visibility ranging from 400 m to less than 800 m, mark it in units of 50 m.
+ .. math:: q (10 ^ { size - 1 } ) + re
+
+ - If the visibility is more than 800 m, mark it in units of 100 m.
+ .. math:: q (10 ^{ 2 } ) + re
+
+ Examples
+ --------
+ >>> Visibility = {'A': 1263, 'B': 695, 'C': 341}
+ >>> convert_visibility(Visibility)
+ {'A': 1200, 'B': 650, 'C': 325}
+
+ :param data: Visibility data in form of dict
+ :return: Visibility data in Converted form of dict
+ """
+
+ keys = list(data.keys())
+ values = []
+
+ for i in keys:
+ if type(data.get(i)) is bool:
+ continue
+ value = int(float(data.get(i)) * 1000)
+
+ q, re = divmod(value, 100)
+ size = len(str(value))
+
+ if value < 400:
+ if 0 <= re < 25:
+ re = 0
+ elif 25 <= re < 50:
+ re = 25
+ elif 50 <= re < 75:
+ re = 50
+ elif 75 <= re < 100:
+ re = 75
+ data[i] = (q * (10 ** (size - 1)) + re) / 1000
+
+ elif 400 <= value < 800:
+ if 0 <= re < 50:
+ re = 0
+ elif 50 <= re < 100:
+ re = 50
+ data[i] = (q * (10 ** (size - 1)) + re) / 1000
+
+ elif 800 <= value:
+ data[i] = (q * (10 ** 2)) / 1000
+
+ self.visibility = data
+ disposable = self.visibility.copy()
+ del disposable['visibility_front']
+ del disposable['visibility_rear']
+ for i in disposable.keys():
+ values.append(int(disposable.get(i) * 1000))
+
+ values.sort(reverse=True)
+ self.prevailing_visibility = values[3]
+
+ def thumbnail_refresh(self):
+
+ try:
+ data_datetime = self.result['date'].tolist()
+ except TypeError:
+ data_datetime = []
+
+ one_hour_ago = time.strftime('%Y%m%d%H%M00', time.localtime(time.time() - 3600))
+ one_hour_visibility = time.strftime('%Y-%m-%d %H:%M:00', time.localtime(time.time() - 3600))
+ two_hour_ago = time.strftime('%Y%m%d%H%M00', time.localtime(time.time() - 3600 * 2))
+ two_hour_visibility = time.strftime('%Y-%m-%d %H:%M:00', time.localtime(time.time() - 3600 * 2))
+ three_hour_ago = time.strftime('%Y%m%d%H%M00', time.localtime(time.time() - 3600 * 3))
+ three_hour_visibility = time.strftime('%Y-%m-%d %H:%M:00', time.localtime(time.time() - 3600 * 3))
+ four_hour_ago = time.strftime('%Y%m%d%H%M00', time.localtime(time.time() - 3600 * 4))
+ four_hour_visibility = time.strftime('%Y-%m-%d %H:%M:00', time.localtime(time.time() - 3600 * 4))
+ five_hour_ago = time.strftime('%Y%m%d%H%M00', time.localtime(time.time() - 3600 * 5))
+ five_hour_visibility = time.strftime('%Y-%m-%d %H:%M:00', time.localtime(time.time() - 3600 * 5))
+ six_hour_ago = time.strftime('%Y%m%d%H%M00', time.localtime(time.time() - 3600 * 6))
+ six_hour_visibility = time.strftime('%Y-%m-%d %H:%M:00', time.localtime(time.time() - 3600 * 6))
+
+ if one_hour_visibility in data_datetime:
+ data = self.result.where(self.result['date'] == one_hour_visibility).dropna()
+ vis = int(data['prev'].tolist()[0] * 1000)
+ self.label_1hour_time.setText(f'{time.strftime("%H:%M", time.localtime(time.time() - 3600))}'
+ f' - {vis} m')
+ else:
+ self.label_1hour_time.setText(f'{time.strftime("%H:%M", time.localtime(time.time() - 3600))}')
+
+ if two_hour_visibility in data_datetime:
+ data = self.result.where(self.result['date'] == two_hour_visibility).dropna()
+ vis = int(data['prev'].tolist()[0] * 1000)
+ self.label_2hour_time.setText(f'{time.strftime("%H:%M", time.localtime(time.time() - 3600 * 2))}'
+ f' - {vis} m')
+ else:
+ self.label_2hour_time.setText(f'{time.strftime("%H:%M", time.localtime(time.time() - 3600 * 2))}')
+
+ if three_hour_visibility in data_datetime:
+ data = self.result.where(self.result['date'] == three_hour_visibility).dropna()
+ vis = int(data['prev'].tolist()[0] * 1000)
+ self.label_3hour_time.setText(f'{time.strftime("%H:%M", time.localtime(time.time() - 3600 * 3))}'
+ f' - {vis} m')
+ else:
+ self.label_3hour_time.setText(f'{time.strftime("%H:%M", time.localtime(time.time() - 3600 * 3))}')
+
+ if four_hour_visibility in data_datetime:
+ data = self.result.where(self.result['date'] == four_hour_visibility).dropna()
+ vis = int(data['prev'].tolist()[0] * 1000)
+ self.label_4hour_time.setText(f'{time.strftime("%H:%M", time.localtime(time.time() - 3600 * 4))}'
+ f' - {vis} m')
+ else:
+ self.label_4hour_time.setText(f'{time.strftime("%H:%M", time.localtime(time.time() - 3600 * 4))}')
+
+ if five_hour_visibility in data_datetime:
+ data = self.result.where(self.result['date'] == five_hour_visibility).dropna()
+ vis = int(data['prev'].tolist()[0] * 1000)
+ self.label_5hour_time.setText(f'{time.strftime("%H:%M", time.localtime(time.time() - 3600 * 5))}'
+ f' - {vis} m')
+ else:
+ self.label_5hour_time.setText(f'{time.strftime("%H:%M", time.localtime(time.time() - 3600 * 5))}')
+
+ if six_hour_visibility in data_datetime:
+ data = self.result.where(self.result['date'] == six_hour_visibility).dropna()
+ vis = int(data['prev'].tolist()[0] * 1000)
+ self.label_6hour_time.setText(f'{time.strftime("%H:%M", time.localtime(time.time() - 3600 * 6))}'
+ f' - {vis} m')
+ else:
+ self.label_6hour_time.setText(f'{time.strftime("%H:%M", time.localtime(time.time() - 3600 * 6))}')
+
+ if os.path.isfile(
+ f'{JS08Settings.get("image_save_path")}/thumbnail/'
+ f'{JS08Settings.get("front_camera_name")}/{self.year_date}/{one_hour_ago}.jpg'):
+ self.label_1hour.setPixmap(
+ QPixmap(f'{JS08Settings.get("image_save_path")}/thumbnail/'
+ f'{JS08Settings.get("front_camera_name")}/{self.year_date}/{one_hour_ago}.jpg')
+ .scaled(self.label_1hour.width(), self.label_1hour.height(), Qt.IgnoreAspectRatio))
+
+ if os.path.isfile(
+ f'{JS08Settings.get("image_save_path")}/thumbnail/'
+ f'{JS08Settings.get("front_camera_name")}/{self.year_date}/{two_hour_ago}.jpg'):
+ self.label_2hour.setPixmap(
+ QPixmap(f'{JS08Settings.get("image_save_path")}/thumbnail/'
+ f'{JS08Settings.get("front_camera_name")}/{self.year_date}/{two_hour_ago}.jpg')
+ .scaled(self.label_2hour.width(), self.label_2hour.height(), Qt.IgnoreAspectRatio))
+
+ if os.path.isfile(
+ f'{JS08Settings.get("image_save_path")}/thumbnail/'
+ f'{JS08Settings.get("front_camera_name")}/{self.year_date}/{three_hour_ago}.jpg'):
+ self.label_3hour.setPixmap(
+ QPixmap(f'{JS08Settings.get("image_save_path")}/thumbnail/'
+ f'{JS08Settings.get("front_camera_name")}/{self.year_date}/{three_hour_ago}.jpg')
+ .scaled(self.label_3hour.width(), self.label_3hour.height(), Qt.IgnoreAspectRatio))
+
+ if os.path.isfile(
+ f'{JS08Settings.get("image_save_path")}/thumbnail/'
+ f'{JS08Settings.get("front_camera_name")}/{self.year_date}/{four_hour_ago}.jpg'):
+ self.label_4hour.setPixmap(
+ QPixmap(f'{JS08Settings.get("image_save_path")}/thumbnail/'
+ f'{JS08Settings.get("front_camera_name")}/{self.year_date}/{four_hour_ago}.jpg')
+ .scaled(self.label_4hour.width(), self.label_4hour.height(), Qt.IgnoreAspectRatio))
+
+ if os.path.isfile(
+ f'{JS08Settings.get("image_save_path")}/thumbnail/'
+ f'{JS08Settings.get("front_camera_name")}/{self.year_date}/{five_hour_ago}.jpg'):
+ self.label_5hour.setPixmap(
+ QPixmap(f'{JS08Settings.get("image_save_path")}/thumbnail/'
+ f'{JS08Settings.get("front_camera_name")}/{self.year_date}/{five_hour_ago}.jpg')
+ .scaled(self.label_5hour.width(), self.label_5hour.height(), Qt.IgnoreAspectRatio))
+
+ if os.path.isfile(
+ f'{JS08Settings.get("image_save_path")}/thumbnail/'
+ f'{JS08Settings.get("front_camera_name")}/{self.year_date}/{six_hour_ago}.jpg'):
+ self.label_6hour.setPixmap(
+ QPixmap(f'{JS08Settings.get("image_save_path")}/thumbnail/'
+ f'{JS08Settings.get("front_camera_name")}/{self.year_date}/{six_hour_ago}.jpg')
+ .scaled(self.label_6hour.width(), self.label_6hour.height(), Qt.IgnoreAspectRatio))
+ self.update()
+
+ # Event
+ def thumbnail_click1(self, e):
+ name = self.label_1hour_time.text()[:2] + self.label_1hour_time.text()[3:5]
+ epoch = time.strftime('%Y%m%d', time.localtime(time.time()))
+ self.thumbnail_view(epoch + name + '00')
+
+ self.reset_StyleSheet()
+ self.label_1hour.setStyleSheet(self.click_style)
+ # self.logo.setStyleSheet('color: #ffffff; background-color: #1b3146')
+ # self.logo.setText(f' {self.label_1hour_time.text()} image')
+
+ QTimer.singleShot(2000, self.thumbnail_show)
+
+ def thumbnail_click2(self, e):
+ name = self.label_2hour_time.text()[:2] + self.label_2hour_time.text()[3:]
+ epoch = time.strftime('%Y%m%d', time.localtime(time.time()))
+ self.thumbnail_view(epoch + name + '00')
+
+ self.reset_StyleSheet()
+ self.label_2hour.setStyleSheet(self.click_style)
+ # self.logo.setStyleSheet('color: #ffffff; background-color: #1b3146')
+ # self.logo.setText(f' {self.label_2hour_time.text()} image')
+
+ QTimer.singleShot(2000, self.thumbnail_show)
+
+ def thumbnail_click3(self, e):
+ name = self.label_3hour_time.text()[:2] + self.label_3hour_time.text()[3:]
+ epoch = time.strftime('%Y%m%d', time.localtime(time.time()))
+ self.thumbnail_view(epoch + name + '00')
+
+ self.reset_StyleSheet()
+ self.label_3hour.setStyleSheet(self.click_style)
+ # self.logo.setStyleSheet('color: #ffffff; background-color: #1b3146')
+ # self.logo.setText(f' {self.label_3hour_time.text()} image')
+
+ QTimer.singleShot(2000, self.thumbnail_show)
+
+ def thumbnail_click4(self, e):
+ name = self.label_4hour_time.text()[:2] + self.label_4hour_time.text()[3:]
+ epoch = time.strftime('%Y%m%d', time.localtime(time.time()))
+ self.thumbnail_view(epoch + name + '00')
+
+ self.reset_StyleSheet()
+ self.label_4hour.setStyleSheet(self.click_style)
+ # self.logo.setStyleSheet('color: #ffffff; background-color: #1b3146')
+ # self.logo.setText(f' {self.label_4hour_time.text()} image')
+
+ QTimer.singleShot(2000, self.thumbnail_show)
+
+ def thumbnail_click5(self, e):
+ name = self.label_5hour_time.text()[:2] + self.label_5hour_time.text()[3:]
+ epoch = time.strftime('%Y%m%d', time.localtime(time.time()))
+ self.thumbnail_view(epoch + name + '00')
+
+ self.reset_StyleSheet()
+ self.label_5hour.setStyleSheet(self.click_style)
+ # self.logo.setStyleSheet('color: #ffffff; background-color: #1b3146')
+ # self.logo.setText(f' {self.label_5hour_time.text()} image')
+
+ QTimer.singleShot(2000, self.thumbnail_show)
+
+ def thumbnail_click6(self, e):
+ name = self.label_6hour_time.text()[:2] + self.label_6hour_time.text()[3:]
+ epoch = time.strftime('%Y%m%d', time.localtime(time.time()))
+ self.thumbnail_view(epoch + name + '00')
+
+ self.reset_StyleSheet()
+ self.label_6hour.setStyleSheet(self.click_style)
+ # self.logo.setStyleSheet('color: #ffffff; background-color: #1b3146')
+ # self.logo.setText(f' {self.label_6hour_time.text()} image')
+
+ QTimer.singleShot(2000, self.thumbnail_show)
+
+ def btn_on(self, event):
+ self.setting_button.setIcon(QIcon('resources/asset/settings_on.png'))
+
+ def btn_off(self, event):
+ self.setting_button.setIcon(QIcon('resources/asset/settings.png'))
+
+ def log_on(self, event):
+ self.log_view.setIcon(QIcon('resources/asset/log_on.png'))
+
+ def log_off(self, event):
+ self.log_view.setIcon(QIcon('resources/asset/log.png'))
+
+ def unit_convert(self, event):
+ if self.km_mile_convert:
+ self.km_mile_convert = False
+ elif self.km_mile_convert is False:
+ self.km_mile_convert = True
+
+ def keyPressEvent(self, e):
+ """Override function QMainwindow KeyPressEvent that works when key is pressed"""
+ if e.key() == Qt.Key_F:
+ self.showFullScreen()
+ self.thumbnail_refresh()
+ if e.key() == Qt.Key_D:
+ self.showNormal()
+ self.thumbnail_refresh()
+ if e.modifiers() & Qt.ControlModifier:
+ if e.key() == Qt.Key_W:
+ self.close()
+ sys.exit()
+
+ def front_label_paintEvent(self, event):
+ painter = QPainter(self.front_label)
+ painter.setPen(QPen(Qt.white, 1, Qt.DotLine))
+
+ painter.drawLine((self.front_label.width() * 0.25), 0,
+ (self.front_label.width() * 0.25), self.front_label.height())
+ painter.drawLine((self.front_label.width() * 0.5), 0,
+ (self.front_label.width() * 0.5), self.front_label.height())
+ painter.drawLine((self.front_label.width() * 0.75), 0,
+ (self.front_label.width() * 0.75), self.front_label.height())
+ painter.drawLine((self.front_label.width() - 1), 0,
+ (self.front_label.width() - 1), self.front_label.height())
+
+ painter.drawText(self.front_label.width() * 0.125, 14, 'SW')
+ painter.drawText(self.front_label.width() * 0.375, 14, 'WS')
+ painter.drawText(self.front_label.width() * 0.625, 14, 'WN')
+ painter.drawText(self.front_label.width() * 0.875, 14, 'NW')
+
+ painter.end()
+
+ def rear_label_paintEvent(self, event):
+ painter = QPainter(self.rear_label)
+ painter.setPen(QPen(Qt.white, 1, Qt.DotLine))
+
+ painter.drawLine((self.rear_label.width() * 0.25), 0,
+ (self.rear_label.width() * 0.25), self.rear_label.height())
+ painter.drawLine((self.rear_label.width() * 0.5), 0,
+ (self.rear_label.width() * 0.5), self.rear_label.height())
+ painter.drawLine((self.rear_label.width() * 0.75), 0,
+ (self.rear_label.width() * 0.75), self.rear_label.height())
+ painter.drawLine((self.rear_label.width() - 1), 0,
+ (self.rear_label.width() - 1), self.rear_label.height())
+
+ painter.drawText(self.rear_label.width() * 0.125, 14, 'NE')
+ painter.drawText(self.rear_label.width() * 0.375, 14, 'EN')
+ painter.drawText(self.rear_label.width() * 0.625, 14, 'ES')
+ painter.drawText(self.rear_label.width() * 0.875, 14, 'SE')
+
+ painter.end()
+
+ def closeEvent(self, e):
+ if self.consumer.isRunning():
+ self.consumer.stop()
+ if self.video_thread.isRunning():
+ self.video_thread.stop()
+ print(f'Close time: {time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}')
+ log(JS08Settings.get('current_id'), 'Logout')
+
+
+class VideoWidget(QWidget):
+ """Video stream player using QVideoWidget"""
+
+ def __init__(self, parent: QObject = None):
+ super().__init__(parent)
+
+ args = [
+ '--rtsp-frame-buffer-size=400000',
+ '--quiet',
+ '--sout-x264-keyint=25',
+ ]
+
+ self.instance = vlc.Instance(args)
+ self.instance.log_unset()
+
+ self.media_player = self.instance.media_player_new()
+ self.uri = None
+
+ # Current camera must be 'PNM-9031RV'
+ self.media_player.video_set_aspect_ratio('21:9')
+
+ self.video_frame = QFrame()
+
+ if sys.platform == 'win32':
+ self.media_player.set_hwnd(self.video_frame.winId())
+
+ def on_camera_change(self, uri: str):
+ if uri[:4] == 'rtsp':
+ self.uri = uri
+ self.media_player.set_media(self.instance.media_new(uri))
+ self.instance.vlm_set_loop(uri, True)
+ self.media_player.play()
+ else:
+ pass
+
+ def get_status(self):
+ # print(f'Video is playing?: {self.media_player.is_playing()}')
+ # if self.media_player.is_playing() == 0:
+ # print(f'Player is not playing!!!!!!!!!!! in '
+ # f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(QDateTime.currentSecsSinceEpoch()))}')
+ # print('replayed')
+ # self.media_player.set_media(self.instance.media_new(self.uri))
+ # self.media_player.play()
+
+ # print(f'is_seekable: {self.media_player.is_seekable()}') # return 0
+ # print(f'is_playing: {self.media_player.is_playing()}') # return 1
+
+ self.media_player.set_pause(1)
+ self.media_player.play()
+
+
+if __name__ == '__main__':
+ mp.freeze_support()
+
+ from PySide6.QtWidgets import QApplication
+ from PySide6.QtGui import QGuiApplication
+ from model import JS08Settings
+
+ print(f'Start time: {time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}')
+
+ q = Queue()
+ _q = Queue()
+
+ os.makedirs(f'{JS08Settings.get("data_csv_path")}', exist_ok=True)
+ os.makedirs(f'{JS08Settings.get("target_csv_path")}', exist_ok=True)
+ os.makedirs(f'{JS08Settings.get("rgb_csv_path")}', exist_ok=True)
+ os.makedirs(f'{JS08Settings.get("image_save_path")}', exist_ok=True)
+ os.makedirs(f'{JS08Settings.get("log_path")}/SET', exist_ok=True)
+
+ app = QApplication(sys.argv)
+ screen_size = QGuiApplication.screens()[0].geometry()
+ width, height = screen_size.width(), screen_size.height()
+ if width != 1920 or height != 1080:
+ QMessageBox.warning(None, 'Warning', 'JS08 is based on FHD screen.')
+ window = JS08MainWindow(q, _q)
+ sys.exit(app.exec())
diff --git a/src/js08_settings_admin.py b/src/js08_settings_admin.py
new file mode 100644
index 0000000..2a9a1b7
--- /dev/null
+++ b/src/js08_settings_admin.py
@@ -0,0 +1,663 @@
+#!/usr/bin/env python3
+#
+# Copyright 2021-2023 Sijung Co., Ltd.
+#
+# Authors:
+# cotjdals5450@gmail.com (Seong Min Chae)
+# 5jx2oh@gmail.com (Jongjin Oh)
+
+
+import os
+import cv2
+import numpy as np
+import pandas as pd
+from scipy.optimize import curve_fit
+
+from PySide6.QtCore import (QPoint, QRect, Qt)
+from PySide6.QtGui import (QPixmap, QPainter, QBrush,
+ QColor, QPen, QImage,
+ QIcon, QFont)
+from PySide6.QtWidgets import (QInputDialog, QDialog, QMessageBox,
+ QFileDialog, QHeaderView, QTableWidget,
+ QTableWidgetItem, QLineEdit)
+from PySide6.QtCharts import QChart, QChartView, QLineSeries, QValueAxis
+
+from target_info import TargetInfo
+from model import JS08Settings
+from user_edit import UserEdit
+from resources.admin_menu import Ui_Dialog
+from save_log import log
+
+import warnings
+warnings.filterwarnings('ignore')
+
+
+class JS08AdminSettingWidget(QDialog, Ui_Dialog):
+
+ def __init__(self):
+ super().__init__()
+ self.setupUi(self)
+
+ self.showFullScreen()
+ self.setWindowFlag(Qt.FramelessWindowHint)
+
+ self.begin = QPoint()
+ self.end = QPoint()
+
+ self.upper_left = ()
+ self.lower_right = ()
+
+ self.target_name = []
+ self.left_range = []
+ self.right_range = []
+ self.distance = []
+ self.azimuth = []
+ self.current_azi = ''
+
+ self.isDrawing = False
+
+ self.video_width = 0
+ self.video_height = 0
+
+ self.cp_image = None
+ self.end_drawing = True
+
+ self.chart_view = None
+ self.select_target = None
+ self.select_name = None
+ self.select_corner1 = None
+ self.select_corner2 = None
+
+ self.tableWidget.doubleClicked.connect(self.tableWidget_doubleClicked)
+
+ self.r_list = []
+ self.g_list = []
+ self.b_list = []
+ self.target_info = TargetInfo()
+
+ self.current_camera = JS08Settings.get('front_camera_name')
+ self.cam_flag = False
+
+ self.image_load()
+
+ if len(self.left_range) > 0:
+ self.tableWidget.setEditTriggers(QTableWidget.NoEditTriggers)
+ self.show_target_table()
+
+ self.red_checkBox.clicked.connect(self.chart_update)
+ self.green_checkBox.clicked.connect(self.chart_update)
+ self.blue_checkBox.clicked.connect(self.chart_update)
+
+ self.flip_button.clicked.connect(self.camera_flip)
+ self.flip_button.setIcon(QIcon('resources/asset/flip_off.png'))
+ self.flip_button.enterEvent = self.btn_on
+ self.flip_button.leaveEvent = self.btn_off
+
+ self.data_csv_path_button.clicked.connect(self.data_csv_path)
+ self.target_csv_path_button.clicked.connect(self.target_csv_path)
+ self.image_save_path_button.clicked.connect(self.image_save_path)
+ # self.afd_checkBox.stateChanged.connect(self.afd_btn_click)
+ self.user_list_button.clicked.connect(self.user_list_click)
+
+ self.data_csv_path_textBrowser.setPlainText(JS08Settings.get('data_csv_path'))
+ self.target_csv_path_textBrowser.setPlainText(JS08Settings.get('target_csv_path'))
+ self.image_save_path_textBrowser.setPlainText(JS08Settings.get('image_save_path'))
+
+ self.vis_limit_spinBox.setValue(JS08Settings.get('visibility_alert_limit'))
+ self.id_textBrowser.setText(JS08Settings.get('admin_id'))
+ self.current_pw.setEchoMode(QLineEdit.Password)
+ self.new_pw.setEchoMode(QLineEdit.Password)
+ self.new_pw_check.setEchoMode(QLineEdit.Password)
+ # self.current_pw.setText(JS08Settings.get('admin_pw'))
+
+ self.image_size_comboBox.setCurrentIndex(JS08Settings.get('image_size'))
+
+ self.image_label.paintEvent = self.lbl_paintEvent
+ self.image_label.mousePressEvent = self.lbl_mousePressEvent
+ self.image_label.mouseMoveEvent = self.lbl_mouseMoveEvent
+ self.image_label.mouseReleaseEvent = self.lbl_mouseReleaseEvent
+
+ self.buttonBox.accepted.connect(self.accept_click)
+ self.buttonBox.rejected.connect(self.reject_click)
+
+ def show_target_table(self):
+ min_x = []
+ min_y = []
+ self.r_list = []
+ self.g_list = []
+ self.b_list = []
+
+ copy_image = self.cp_image.copy()
+ row_count = len(self.distance)
+ self.tableWidget.setRowCount(row_count)
+ self.tableWidget.setColumnCount(3)
+ self.tableWidget.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
+ self.tableWidget.setHorizontalHeaderLabels(['Number', 'Distance', 'Azimuth'])
+
+ for upper_left, lower_right in zip(self.left_range, self.right_range):
+ result = self.target_info.minrgb(upper_left, lower_right, copy_image)
+ min_x.append(result[0])
+ min_y.append(result[1])
+
+ self.r_list.append(copy_image[result[1], result[0], 0])
+ self.g_list.append(copy_image[result[1], result[0], 1])
+ self.b_list.append(copy_image[result[1], result[0], 2])
+
+ for i in range(0, row_count):
+ item2 = QTableWidgetItem(f'{i + 1}')
+ item2.setTextAlignment(Qt.AlignVCenter | Qt.AlignHCenter)
+ item2.setForeground(QBrush(QColor(255, 255, 255)))
+ self.tableWidget.setItem(i, 0, item2)
+
+ item3 = QTableWidgetItem(f'{self.distance[i]} km')
+ item3.setTextAlignment(Qt.AlignVCenter | Qt.AlignHCenter)
+ item3.setForeground(QBrush(QColor(255, 255, 255)))
+ self.tableWidget.setItem(i, 1, item3)
+
+ item4 = QTableWidgetItem(f'{self.azimuth[i]}')
+ item4.setTextAlignment(Qt.AlignVCenter | Qt.AlignHCenter)
+ item4.setForeground(QBrush(QColor(255, 255, 255)))
+ self.tableWidget.setItem(i, 2, item4)
+
+ def func(self, x, c1, c2, a):
+ return c2 + (c1 - c2) * np.exp(-a * x)
+
+ def chart_update(self):
+ if self.chart_view is None:
+ self.chart_view = self.chart_draw()
+
+ if self.graph_verticalLayout.count() == 0:
+ self.chart_view = self.chart_draw()
+ self.graph_verticalLayout.addWidget(self.chart_view)
+ else:
+ new_chart_view = self.chart_draw()
+ self.graph_verticalLayout.removeWidget(self.chart_view)
+ self.graph_verticalLayout.addWidget(new_chart_view)
+ self.graph_verticalLayout.update()
+ self.chart_view = new_chart_view
+
+ def chart_draw(self):
+ """세팅창 그래프 칸에 소산계수 차트를 그리는 함수"""
+
+ try:
+ # self.distance.sort()
+ distance = self.distance.copy()
+ distance.sort()
+ self.x = np.linspace(distance[0], distance[-1], 100, endpoint=True)
+ # self.x.sort()
+
+ hanhwa_opt_r, hanhwa_cov_r = curve_fit(self.func, distance, self.r_list, maxfev=5000)
+ hanhwa_opt_g, hanhwa_cov_g = curve_fit(self.func, distance, self.g_list, maxfev=5000)
+ hanhwa_opt_b, hanhwa_cov_b = curve_fit(self.func, distance, self.b_list, maxfev=5000)
+
+ chart = QChart()
+ chart.setTheme(QChart.ChartThemeDark)
+ font = QFont('Noto Sans')
+ font.setPixelSize(20)
+ font.setBold(3)
+ chart.setTitleFont(font)
+ chart.setTitleBrush(QBrush(QColor('#ffffff')))
+ chart.setTitle('Extinction coefficient Graph')
+ chart.setAnimationOptions(QChart.SeriesAnimations)
+ chart.setBackgroundBrush(QBrush(QColor(255, 255, 255)))
+
+ axis_x = QValueAxis()
+ axis_x.setTickCount(7)
+ axis_x.setLabelFormat('%i')
+ axis_x.setTitleText('Distance(km)')
+ axis_x.setTitleBrush(QBrush(QColor('#ffffff')))
+ axis_x.setRange(0, 6)
+ chart.addAxis(axis_x, Qt.AlignBottom)
+
+ axis_y = QValueAxis()
+ axis_y.setTickCount(7)
+ axis_y.setLabelFormat('%i')
+ axis_y.setTitleText('Intensity')
+ axis_y.setTitleBrush(QBrush('#ffffff'))
+ axis_y.setRange(0, 255)
+ chart.addAxis(axis_y, Qt.AlignLeft)
+
+ # Red Graph
+ if self.red_checkBox.isChecked():
+ series1 = QLineSeries()
+ series1.setName('Red')
+ pen = QPen()
+ pen.setWidth(2)
+ series1.setPen(pen)
+ series1.setColor(QColor('Red'))
+
+ for dis in self.x:
+ series1.append(*(dis, self.func(dis, *hanhwa_opt_r)))
+ chart.addSeries(series1) # data feeding
+ series1.attachAxis(axis_x)
+ series1.attachAxis(axis_y)
+
+ # Green Graph
+ if self.green_checkBox.isChecked():
+ series2 = QLineSeries()
+ series2.setName('Green')
+ pen = QPen()
+ pen.setWidth(2)
+ series2.setPen(pen)
+ series2.setColor(QColor('Green'))
+
+ for dis in self.x:
+ series2.append(*(dis, self.func(dis, *hanhwa_opt_g)))
+ chart.addSeries(series2) # data feeding
+
+ series2.attachAxis(axis_x)
+ series2.attachAxis(axis_y)
+
+ # Blue Graph
+ if self.blue_checkBox.isChecked():
+ series3 = QLineSeries()
+ series3.setName('Blue')
+ pen = QPen()
+ pen.setWidth(2)
+ series3.setPen(pen)
+ series3.setColor(QColor('Blue'))
+
+ for dis in self.x:
+ series3.append(*(dis, self.func(dis, *hanhwa_opt_b)))
+ chart.addSeries(series3) # data feeding
+
+ series3.attachAxis(axis_x)
+ series3.attachAxis(axis_y)
+
+ chart.legend().setAlignment(Qt.AlignRight)
+
+ # displaying chart
+ chart.setBackgroundBrush(QBrush(QColor(22, 32, 42)))
+ chart_view = QChartView(chart)
+ chart_view.setRenderHint(QPainter.Antialiasing)
+ chart_view.setMaximumSize(800, 500)
+
+ return chart_view
+
+ except TypeError as e:
+ QMessageBox.about(self, 'Error', f'{e}')
+ log(JS08Settings.get('current_id'), str(e))
+ pass
+
+ except IndexError as e:
+ QMessageBox.about(self, 'Error', f'{e}')
+ log(JS08Settings.get('current_id'), str(e))
+ pass
+
+ def camera_flip(self):
+ if self.cam_flag:
+ self.cam_flag = False
+ else:
+ self.cam_flag = True
+ self.image_load()
+
+ def image_load(self):
+ self.left_range = None
+ self.right_range = None
+
+ if self.cam_flag: # cam_flag is True = PNM_9031RV_rear
+ src = JS08Settings.get('rear_camera_rtsp')
+ self.current_camera = JS08Settings.get('rear_camera_name')
+ self.target_setting_label.setText(f' Rear Target Setting ({self.current_camera})')
+ self.get_target(self.current_camera)
+
+ else: # cam_flag is False = PNM_9031RV_front
+ src = JS08Settings.get('front_camera_rtsp')
+ self.current_camera = JS08Settings.get('front_camera_name')
+ self.target_setting_label.setText(f' Front Target Setting ({self.current_camera})')
+ self.get_target(self.current_camera)
+
+ try:
+ cap = cv2.VideoCapture(src)
+ ret, cv_img = cap.read()
+ cp_image = cv_img.copy()
+ cap.release()
+
+ except Exception as e:
+ QMessageBox.about(self, 'Error', f'{e}')
+ log(JS08Settings.get('current_id'), str(e))
+
+ self.image_label.setPixmap(self.convert_cv_qt(cp_image))
+ self.show_target_table()
+ self.chart_update()
+ self.update()
+
+ def convert_cv_qt(self, cv_img):
+ """Convert CV image to QImage."""
+ cv_img = cv_img.copy()
+ cv_img = cv2.cvtColor(cv_img, cv2.COLOR_BGR2RGB)
+
+ self.cp_image = cv_img.copy()
+
+ self.video_height, self.video_width, ch = cv_img.shape
+
+ bytes_per_line = ch * self.video_width
+ convert_to_Qt_format = QImage(cv_img.data, self.video_width, self.video_height,
+ bytes_per_line, QImage.Format_RGB888)
+ p = convert_to_Qt_format.scaled(self.image_label.width(),
+ self.image_label.height(),
+ Qt.KeepAspectRatio, Qt.SmoothTransformation)
+
+ return QPixmap.fromImage(p)
+
+ def str_to_tuple(self, before_list):
+ """저장된 타겟들의 위치정보인 튜플 리스트가 문자열로 바뀌어 다시 튜플형태로 변환하는 함수"""
+ tuple_list = [i.split(',') for i in before_list]
+ tuple_list = [(int(i[0][1:]), int(i[1][:-1])) for i in tuple_list]
+ return tuple_list
+
+ # 타겟 조정 및 썸네일 관련 함수 시작
+ def thumbnail_pos(self, end_pos):
+ x = int((end_pos.x() / self.image_label.width()) * self.video_width)
+ y = int((end_pos.y() / self.image_label.height()) * self.video_height)
+ return x, y
+
+ def thumbnail(self, image):
+ height, width, channel = image.shape
+ bytesPerLine = channel * width
+ qImg = QImage(image.data.tobytes(), width, height, bytesPerLine, QImage.Format_RGB888)
+ return qImg
+
+ def data_csv_path(self):
+ fName = QFileDialog.getExistingDirectory(
+ self, 'Select path to save data csv file', JS08Settings.get('data_csv_path'))
+ if fName:
+ self.data_csv_path_textBrowser.setPlainText(fName)
+ else:
+ pass
+
+ def target_csv_path(self):
+ fName = QFileDialog.getExistingDirectory(
+ self, 'Select path to save target csv file', JS08Settings.get('target_csv_path'))
+ if fName:
+ self.target_csv_path_textBrowser.setPlainText(fName)
+ else:
+ pass
+
+ def image_save_path(self):
+ fName = QFileDialog.getExistingDirectory(
+ self, 'Select path to save image file', JS08Settings.get('image_save_path'))
+ if fName:
+ self.image_save_path_textBrowser.setPlainText(fName)
+ else:
+ pass
+
+ def afd_btn_click(self):
+ if self.afd_checkBox.isChecked():
+ QMessageBox.warning(self, 'Starting auto file delete', 'Image file will be automatically delete'
+ ' and cannot be restored.')
+ # dlg = FileAutoDelete()
+ # dlg.show()
+ # dlg.exec()
+
+ def user_list_click(self):
+ dlg = UserEdit()
+ dlg.show()
+ dlg.setWindowModality(Qt.ApplicationModal)
+ dlg.exec()
+
+ def save_target(self, camera: str):
+
+ file = f'{JS08Settings.get("target_csv_path")}/{camera}/{camera}.csv'
+ if self.left_range and os.path.isfile(file):
+ col = ['target_name', 'left_range', 'right_range', 'distance', 'azimuth']
+ result = pd.DataFrame(columns=col)
+ result['target_name'] = self.target_name
+ result['left_range'] = self.left_range
+ result['right_range'] = self.right_range
+ result['distance'] = self.distance
+ result['azimuth'] = self.azimuth
+ result.to_csv(file, mode='w', index=False)
+ print(f'[JS-08 Setting SAVED]')
+
+ def get_target(self, camera: str):
+
+ save_path = os.path.join(f'{JS08Settings.get("target_csv_path")}/{camera}')
+ file = f'{save_path}/{camera}.csv'
+
+ if os.path.isfile(f'{save_path}/{camera}.csv') is False:
+ os.makedirs(f'{save_path}', exist_ok=True)
+ if self.cam_flag is False:
+ result = pd.DataFrame(columns=['target_name', 'left_range', 'right_range', 'distance', 'azimuth'])
+ result['target_name'] = [1, 2, 3, 4]
+ result['left_range'] = [(95, 711), (367, 716), (293, 1749), (250, 124)]
+ result['right_range'] = [(31, 831), (279, 836), (236, 1841), (148, 211)]
+ result['distance'] = [0.1, 1.0, 2.0, 3.0]
+ result['azimuth'] = ['NE', 'NE', 'NE', 'NE']
+ result.to_csv(file, mode='w', index=False)
+ elif self.cam_flag:
+ result = pd.DataFrame(columns=['target_name', 'left_range', 'right_range', 'distance', 'azimuth'])
+ result['target_name'] = [1, 2, 3, 4]
+ result['left_range'] = [(95, 711), (367, 716), (293, 1749), (250, 124)]
+ result['right_range'] = [(31, 831), (279, 836), (236, 1841), (148, 211)]
+ result['distance'] = [0.1, 1.0, 2.0, 3.0]
+ result['azimuth'] = ['SW', 'SW', 'SW', 'SW']
+ result.to_csv(file, mode='w', index=False)
+
+ target_df = pd.read_csv(f'{save_path}/{camera}.csv')
+ self.target_name = target_df['target_name'].tolist()
+ self.left_range = self.str_to_tuple(target_df['left_range'].tolist())
+ self.right_range = self.str_to_tuple(target_df['right_range'].tolist())
+ self.distance = target_df['distance'].tolist()
+ self.azimuth = target_df['azimuth'].tolist()
+
+ def accept_click(self):
+ input_current_pw = self.current_pw.text()
+ input_new_pw = self.new_pw.text()
+ input_new_pw_check = self.new_pw_check.text()
+
+ if input_current_pw == JS08Settings.get('admin_pw') and \
+ input_new_pw == input_new_pw_check:
+
+ JS08Settings.set('data_csv_path', self.data_csv_path_textBrowser.toPlainText())
+ JS08Settings.set('target_csv_path', self.target_csv_path_textBrowser.toPlainText())
+ JS08Settings.set('image_save_path', self.image_save_path_textBrowser.toPlainText())
+ JS08Settings.set('image_size', self.image_size_comboBox.currentIndex())
+ JS08Settings.set('visibility_alert_limit', self.vis_limit_spinBox.value())
+ JS08Settings.set('admin_pw', input_new_pw)
+ if input_current_pw != input_new_pw:
+ log(f'{JS08Settings.get("admin_id")}', f'Change Password ({input_current_pw}) -> ({input_new_pw_check})')
+
+ self.save_target(self.current_camera)
+
+ if JS08Settings.get('first_step'):
+ QMessageBox.about(None, 'Restart JS-08',
+ 'When JS-08 program is restarted, Target Detection is started')
+ JS08Settings.set('first_step', False)
+ self.close()
+
+ def reject_click(self):
+ self.close()
+
+ # Event
+ def tableWidget_doubleClicked(self, event):
+ self.select_target = self.tableWidget.currentIndex().row()
+ self.update()
+
+ def btn_on(self, event):
+ self.flip_button.setIcon(QIcon('resources/asset/flip_on.png'))
+
+ def btn_off(self, event):
+ self.flip_button.setIcon(QIcon('resources/asset/flip_off.png'))
+
+ def lbl_paintEvent(self, event):
+ painter = QPainter(self.image_label)
+
+ back_ground_image = self.thumbnail(self.cp_image)
+ bk_image = QPixmap.fromImage(back_ground_image)
+ painter.drawPixmap(QRect(0, 0, self.image_label.width(),
+ self.image_label.height()), bk_image)
+
+ painter.setPen(QPen(Qt.white, 1, Qt.DotLine))
+
+ painter.drawLine((self.image_label.width() * 0.25), 0,
+ (self.image_label.width() * 0.25), self.image_label.height())
+ painter.drawLine((self.image_label.width() * 0.5), 0,
+ (self.image_label.width() * 0.5), self.image_label.height())
+ painter.drawLine((self.image_label.width() * 0.75), 0,
+ (self.image_label.width() * 0.75), self.image_label.height())
+
+ if self.cam_flag:
+ painter.setPen(QPen(Qt.black, 1, Qt.DotLine))
+ painter.drawText(self.image_label.width() * 0.125, 20, 'SW')
+ painter.drawText(self.image_label.width() * 0.375, 20, 'WS')
+ painter.drawText(self.image_label.width() * 0.625, 20, 'WN')
+ painter.drawText(self.image_label.width() * 0.875, 20, 'NW')
+ painter.setPen(QPen(Qt.white, 1, Qt.DotLine))
+ elif self.cam_flag is False:
+ painter.setPen(QPen(Qt.black, 1, Qt.DotLine))
+ painter.drawText(self.image_label.width() * 0.125, 20, 'NE')
+ painter.drawText(self.image_label.width() * 0.375, 20, 'EN')
+ painter.drawText(self.image_label.width() * 0.625, 20, 'ES')
+ painter.drawText(self.image_label.width() * 0.875, 20, 'SE')
+ painter.setPen(QPen(Qt.white, 1, Qt.DotLine))
+
+ if self.left_range and self.right_range:
+ for name, corner1, corner2 in zip(self.target_name, self.left_range, self.right_range):
+ br = QBrush(QColor(100, 10, 10, 40))
+ painter.setBrush(br)
+ painter.setPen(QPen(Qt.red, 2, Qt.SolidLine))
+ corner1_1 = int(corner1[0] / self.video_width * self.image_label.width())
+ corner1_2 = int(corner1[1] / self.video_height * self.image_label.height())
+ corner2_1 = int((corner2[0] - corner1[0]) / self.video_width * self.image_label.width())
+ corner2_2 = int((corner2[1] - corner1[1]) / self.video_height * self.image_label.height())
+ painter.drawRect(QRect(corner1_1, corner1_2, corner2_1, corner2_2))
+ painter.drawText(corner1_1 + corner2_1, corner1_2 - 5, f'{name}')
+
+ if self.isDrawing:
+ br = QBrush(QColor(100, 10, 10, 40))
+ painter.setBrush(br)
+ painter.setPen(QPen(Qt.red, 2, Qt.SolidLine))
+ painter.drawRect(QRect(self.begin, self.end))
+
+ # th_x, th_y = self.thumbnail_pos(self.end)
+ # th_qImage = self.thumbnail(self.cp_image[th_y - 50:th_y + 50, th_x - 50:th_x + 50, :])
+ # thumbnail_image = QPixmap.fromImage(th_qImage)
+ # painter.drawPixmap(QRect(self.end.x(), self.end.y(), 200, 200), thumbnail_image)
+
+ if self.end_drawing:
+ painter.eraseRect(QRect(self.begin, self.end))
+ self.end_drawing = False
+ self.isDrawing = False
+ painter.end()
+
+ def lbl_mousePressEvent(self, event):
+ """마우스 클릭시 발생하는 이벤트, QLabel method overriding"""
+
+ # 좌 클릭시 실행
+ if event.buttons() == Qt.LeftButton:
+ self.begin = event.pos()
+ self.end = event.pos()
+ self.upper_left = (int((self.begin.x() / self.image_label.width()) * self.video_width),
+ int((self.begin.y() / self.image_label.height()) * self.video_height))
+
+ self.isDrawing = True
+
+ # 우 클릭시 실행
+ elif event.buttons() == Qt.RightButton:
+ text, ok = QInputDialog.getText(self, 'Delete target', 'Input target number to delete')
+ if ok:
+ if text == '':
+ del self.target_name[-1]
+ del self.left_range[-1]
+ del self.right_range[-1]
+ del self.distance[-1]
+ del self.azimuth[-1]
+
+ else:
+ if len(self.target_name) > 0:
+ text = int(text)
+ del self.target_name[text - 1]
+ del self.left_range[text - 1]
+ del self.right_range[text - 1]
+ del self.distance[text - 1]
+ del self.azimuth[text - 1]
+
+ for i in range(len(self.target_name)):
+ self.target_name[i] = i + 1
+
+ self.show_target_table()
+
+ def lbl_mouseMoveEvent(self, event):
+ """마우스가 움직일 때 발생하는 이벤트, QLabel method overriding"""
+ if event.buttons() == Qt.LeftButton:
+ self.end = event.pos()
+ self.image_label.update()
+
+ def lbl_mouseReleaseEvent(self, event):
+ """마우스 클릭이 떼질 때 발생하는 이벤트, QLabel method overriding"""
+ if self.isDrawing:
+ if self.cam_flag:
+ if 0 < self.upper_left[0] <= self.video_width * 0.25:
+ self.azimuth.append('SW')
+ self.current_azi = 'SW'
+ elif self.video_width * 0.25 < self.upper_left[0] <= self.video_width * 0.5:
+ self.azimuth.append('WS')
+ self.current_azi = 'WS'
+ elif self.video_width * 0.5 < self.upper_left[0] <= self.video_width * 0.75:
+ self.azimuth.append('WN')
+ self.current_azi = 'WN'
+ elif self.video_width * 0.75 < self.upper_left[0] <= self.video_width:
+ self.azimuth.append('NW')
+ self.current_azi = 'NW'
+
+ elif self.cam_flag is False:
+ if 0 < self.upper_left[0] <= self.video_width * 0.25:
+ self.azimuth.append('NE')
+ self.current_azi = 'NE'
+ elif self.video_width * 0.25 < self.upper_left[0] <= self.video_width * 0.5:
+ self.azimuth.append('EN')
+ self.current_azi = 'EN'
+ elif self.video_width * 0.5 < self.upper_left[0] <= self.video_width * 0.75:
+ self.azimuth.append('ES')
+ self.current_azi = 'ES'
+ elif self.video_width * 0.75 < self.upper_left[0] <= self.video_width:
+ self.azimuth.append('SE')
+ self.current_azi = 'SE'
+
+ self.end = event.pos()
+ self.image_label.update()
+ self.lower_right = (int((self.end.x() / self.image_label.width()) * self.video_width),
+ int((self.end.y() / self.image_label.height()) * self.video_height))
+
+ # text, ok = QInputDialog.getText(self, '거리 입력', '거리(km)')
+
+ from input_target import InputTarget
+ getText = InputTarget(self.current_azi)
+ if getText.exec():
+ dist, azi = getText.getInputs()
+
+ self.left_range.append(self.upper_left)
+ self.right_range.append(self.lower_right)
+ self.distance.append(dist)
+ self.azimuth[-1] = azi
+ self.target_name.append(len(self.left_range))
+
+ self.end_drawing = True
+ log(JS08Settings.get('current_id'), 'Save Target ')
+ else:
+ del self.azimuth[-1]
+
+ # if state:
+ # self.left_range.append(self.upper_left)
+ # self.right_range.append(self.lower_right)
+ # self.distance.append(dist)
+ # self.target_name.append(len(self.left_range))
+ #
+ # self.end_drawing = True
+ #
+ # else:
+ # del self.azimuth[-1]
+
+ self.isDrawing = False
+ self.show_target_table()
+
+
+if __name__ == '__main__':
+ import sys
+ from PySide6.QtWidgets import QApplication
+
+ app = QApplication(sys.argv)
+ ui = JS08AdminSettingWidget()
+ ui.show()
+ sys.exit(app.exec())
diff --git a/src/js08_settings_user.py b/src/js08_settings_user.py
new file mode 100644
index 0000000..224eec6
--- /dev/null
+++ b/src/js08_settings_user.py
@@ -0,0 +1,122 @@
+#!/usr/bin/env python3
+#
+# Copyright 2021-2023 Sijung Co., Ltd.
+#
+# Authors:
+# cotjdals5450@gmail.com (Seong Min Chae)
+# 5jx2oh@gmail.com (Jongjin Oh)
+
+
+from PySide6.QtWidgets import QDialog, QFileDialog, QLineEdit, QMessageBox
+from PySide6.QtGui import QIcon
+
+from model import JS08Settings
+from resources.user_menu import Ui_Dialog
+from save_log import log
+
+import warnings
+
+warnings.filterwarnings('ignore')
+
+
+class JS08UserSettingWidget(QDialog, Ui_Dialog):
+
+ def __init__(self):
+ super().__init__()
+ self.setupUi(self)
+
+ # self.setWindowFlag(Qt.FramelessWindowHint)
+ self.setWindowIcon(QIcon('JS08_Logo.ico'))
+
+ self.data_csv_path_button.clicked.connect(self.data_csv_path)
+ self.target_csv_path_button.clicked.connect(self.target_csv_path)
+ self.image_save_path_button.clicked.connect(self.image_save_path)
+
+ self.data_csv_path_textBrowser.setPlainText(JS08Settings.get('data_csv_path'))
+ self.target_csv_path_textBrowser.setPlainText(JS08Settings.get('target_csv_path'))
+ self.image_save_path_textBrowser.setPlainText(JS08Settings.get('image_save_path'))
+
+ self.vis_limit_spinBox.setValue(JS08Settings.get('visibility_alert_limit'))
+ self.id_lineEdit.setText(JS08Settings.get('current_id'))
+ self.current_pw.setEchoMode(QLineEdit.Password)
+ self.new_pw.setEchoMode(QLineEdit.Password)
+ self.new_pw_check.setEchoMode(QLineEdit.Password)
+
+ self.image_size_comboBox.setCurrentIndex(JS08Settings.get('image_size'))
+
+ self.buttonBox.accepted.connect(self.accept_click)
+ self.buttonBox.rejected.connect(self.reject_click)
+ self.resize(417, 516)
+
+ def data_csv_path(self):
+ fName = QFileDialog.getExistingDirectory(
+ self, 'Select path to save data csv file', JS08Settings.get('data_csv_path'))
+ if fName:
+ self.data_csv_path_textBrowser.setPlainText(fName)
+ else:
+ pass
+
+ def target_csv_path(self):
+ fName = QFileDialog.getExistingDirectory(
+ self, 'Select path to save target csv file', JS08Settings.get('target_csv_path'))
+ if fName:
+ self.target_csv_path_textBrowser.setPlainText(fName)
+ else:
+ pass
+
+ def image_save_path(self):
+ fName = QFileDialog.getExistingDirectory(
+ self, 'Select path to save image file', JS08Settings.get('image_save_path'))
+ if fName:
+ self.image_save_path_textBrowser.setPlainText(fName)
+ else:
+ pass
+
+ def accept_click(self):
+ current_id = JS08Settings.get('current_id')
+
+ user = JS08Settings.get_user('user')
+ # user_id = list(JS08Settings.get_user('user').keys())
+ # user_pw = list(JS08Settings.get_user('user').values())
+
+ input_current_pw = self.current_pw.text()
+ input_new_pw = self.new_pw.text()
+ input_new_pw_check = self.new_pw_check.text()
+
+ if input_current_pw == JS08Settings.get('current_pw') and \
+ input_new_pw == input_new_pw_check:
+ user[current_id] = input_new_pw
+
+ JS08Settings.set('data_csv_path', self.data_csv_path_textBrowser.toPlainText())
+ JS08Settings.set('target_csv_path', self.target_csv_path_textBrowser.toPlainText())
+ JS08Settings.set('image_save_path', self.image_save_path_textBrowser.toPlainText())
+ JS08Settings.set('image_size', self.image_size_comboBox.currentIndex())
+ JS08Settings.set('visibility_alert_limit', self.vis_limit_spinBox.value())
+ JS08Settings.set('user', user)
+ JS08Settings.set('current_pw', input_new_pw)
+
+ if input_current_pw != input_new_pw:
+ log(JS08Settings.get('current_id'), f'Change Password ({input_current_pw}) -> ({input_new_pw})')
+
+ self.close()
+
+ elif input_current_pw != JS08Settings.get('current_pw'):
+ self.info.setText('현재 비밀번호가 올바르지 않습니다.')
+ # QMessageBox.warning(self, 'Warning', 'Password Error')
+
+ elif input_current_pw == JS08Settings.get('current_pw') and \
+ input_new_pw != input_new_pw_check:
+ self.info.setText('새 비밀번호가 동일하지 않습니다.')
+
+ def reject_click(self):
+ self.close()
+
+
+if __name__ == '__main__':
+ import sys
+ from PySide6.QtWidgets import QApplication
+
+ app = QApplication(sys.argv)
+ ui = JS08UserSettingWidget()
+ ui.show()
+ sys.exit(app.exec())
diff --git a/src/log_view.py b/src/log_view.py
new file mode 100644
index 0000000..8a69c0d
--- /dev/null
+++ b/src/log_view.py
@@ -0,0 +1,51 @@
+#!/usr/bin/env python3
+#
+# Copyright 2021-2023 Sijung Co., Ltd.
+#
+# Authors:
+# cotjdals5450@gmail.com (Seong Min Chae)
+# 5jx2oh@gmail.com (Jongjin Oh)
+
+
+from PySide6.QtCore import Qt
+from PySide6.QtGui import QIcon
+from PySide6.QtWidgets import QDialog, QFileDialog
+
+from model import JS08Settings
+from resources.log_decrypt import Ui_Dialog
+from save_log import decrypt_log
+
+
+class LogView(QDialog, Ui_Dialog):
+
+ def __init__(self):
+ super().__init__()
+ self.setupUi(self)
+ self.setWindowIcon(QIcon('JS08_Logo.ico'))
+
+ self.pushButton.clicked.connect(self.open_file)
+
+ def open_file(self):
+ self.textBrowser.clear()
+ fname = QFileDialog.getOpenFileName(self, 'Open file', JS08Settings.get('log_path'))
+ if fname[0]:
+ for v in decrypt_log(fname[0]):
+ self.textBrowser.append(v)
+
+ def keyPressEvent(self, e):
+ if e.modifiers() & Qt.ControlModifier:
+ if e.key() == Qt.Key_W:
+ self.close()
+
+ if e.key() & Qt.Key_Escape:
+ self.close()
+
+
+if __name__ == '__main__':
+ import sys
+ from PySide6.QtWidgets import QApplication
+
+ app = QApplication(sys.argv)
+ ui = LogView()
+ ui.show()
+ sys.exit(app.exec())
diff --git a/src/login_view.py b/src/login_view.py
new file mode 100644
index 0000000..3a14123
--- /dev/null
+++ b/src/login_view.py
@@ -0,0 +1,132 @@
+#!/usr/bin/env python3
+#
+# Copyright 2021-2023 Sijung Co., Ltd.
+#
+# Authors:
+# cotjdals5450@gmail.com (Seong Min Chae)
+# 5jx2oh@gmail.com (Jongjin Oh)
+
+
+import sys
+import random
+import string
+import time
+from datetime import datetime
+
+from PySide6.QtWidgets import QDialog, QLineEdit, QMessageBox
+from PySide6.QtCore import Qt
+from PySide6.QtGui import QIcon
+
+from model import JS08Settings
+from resources.login_window import Ui_Dialog
+from save_log import log
+
+
+class LoginWindow(QDialog, Ui_Dialog):
+
+ def __init__(self):
+ super(LoginWindow, self).__init__()
+
+ self.setupUi(self)
+ self.setWindowFlag(Qt.WindowCloseButtonHint, False)
+ self.setWindowFlag(Qt.WindowContextHelpButtonHint, False)
+ self.setWindowFlag(Qt.FramelessWindowHint)
+ self.setWindowIcon(QIcon('resources/asset/logo.png'))
+ self.show()
+
+ self.sijunglogo.setIcon(QIcon('resources/asset/f_logo.png'))
+ self.login_button.clicked.connect(self.login_click)
+ self.login_button.setShortcut('Return')
+
+ self.admin_id = JS08Settings.get('admin_id')
+ self.admin_pw = JS08Settings.get('admin_pw')
+ self.user_id = list(JS08Settings.get_user('user').keys())
+ self.user_pw = list(JS08Settings.get_user('user').values())
+ self.id = [self.admin_id]
+ self.id.extend(self.user_id)
+ self.pw = [self.admin_pw]
+ self.pw.extend(self.user_pw)
+ self.account = {}
+ for i in range(len(self.id)):
+ self.account[self.id[i]] = self.pw[i]
+ self.id = list(self.account.keys())
+ self.pw = list(self.account.values())
+
+ self.pw_lineEdit.setEchoMode(QLineEdit.Password)
+
+ self.flag = 0
+
+ def login_click(self):
+ input_id = self.id_lineEdit.text()
+ input_pw = self.pw_lineEdit.text()
+ if input_id in self.account.keys() and input_pw == self.account[f'{input_id}']:
+ if input_id == 'admin':
+ if JS08Settings.get('login_time') != '':
+ now = datetime.now()
+ agga = datetime.strptime(JS08Settings.get('login_time'), '%Y-%m-%d %H:%M:%S')
+ diff = now - agga
+ if diff.seconds >= 60:
+ JS08Settings.set('right', 'administrator')
+ JS08Settings.set('login_flag', 0)
+ JS08Settings.set('login_time', '')
+ else:
+ QMessageBox.warning(None, '계정 일시 차단', '잠시 후에 다시 로그인을 시도해 주세요.')
+ self.close()
+ sys.exit()
+ elif JS08Settings.get('login_time') == '':
+ JS08Settings.set('right', 'administrator')
+ JS08Settings.set('login_flag', 0)
+ JS08Settings.set('login_time', '')
+ else:
+ JS08Settings.set('right', 'user')
+ log(input_id, 'Login')
+ JS08Settings.set('current_id', input_id)
+ JS08Settings.set('current_pw', input_pw)
+ self.close()
+
+ elif not input_id in self.account.keys():
+ self.alert_label.setText('없는 아이디 입니다.')
+
+ else:
+ self.flag = self.flag + 1
+ self.alert_label.setText(f'비밀번호가 올바르지 않습니다. ({self.flag} / 5)')
+
+ if self.flag >= 5 and input_id != 'admin':
+ log(input_id, f'Account Blocking, Password initialized')
+ # log(input_id, f'User ({input_id}) Account Blocking')
+ QMessageBox.warning(None, '비밀번호 초기화', '비밀번호 5회 오류로 인해 비밀번호가 교체됩니다.'
+ ' 관리자에게 문의하세요.')
+
+ rand_str = ''
+ for i in range(10):
+ rand_str += str(random.choice(string.ascii_uppercase + string.digits))
+ user = JS08Settings.get_user('user')
+ user[input_id] = rand_str
+ JS08Settings.set('user', user)
+ self.close()
+ sys.exit()
+
+ elif self.flag >= 5 and input_id == 'admin':
+ if JS08Settings.get('login_flag') >= 2:
+ JS08Settings.restore_value('admin_pw')
+ QMessageBox.information(None, '비밀번호 초기화', '비밀번호가 초기화 됩니다.')
+ QMessageBox.warning(None, '비밀번호 5회 오류', '잠시 후에 다시 로그인을 시도해 주세요.')
+ JS08Settings.set('login_time', time.strftime('%Y-%m-%d %H:%M:00', time.localtime()))
+ JS08Settings.set('login_flag', JS08Settings.get('login_flag') + 1)
+ self.close()
+ sys.exit()
+
+ else:
+ pass
+
+ def keyPressEvent(self, event):
+ if event.key() == Qt.Key_Escape:
+ sys.exit()
+
+
+if __name__ == '__main__':
+ from PySide6.QtWidgets import QApplication
+
+ app = QApplication(sys.argv)
+ window = LoginWindow()
+ sys.exit(app.exec())
diff --git a/src/model.py b/src/model.py
index 4889d3c..bf23739 100644
--- a/src/model.py
+++ b/src/model.py
@@ -1,26 +1,47 @@
#!/usr/bin/env python3
#
-# Copyright 2021-2022 Sijung Co., Ltd.
+# Copyright 2021-2023 Sijung Co., Ltd.
#
# Authors:
# cotjdals5450@gmail.com (Seong Min Chae)
# 5jx2oh@gmail.com (Jongjin Oh)
+
import os
-from PyQt5.QtCore import QSettings, QStandardPaths
+from PySide6.QtCore import QSettings
-class JS06Settings:
- settings = QSettings('sijung', 'js06')
+class JS08Settings:
+ settings = QSettings('sijung', 'js08')
defaults = {
- 'data_csv_path': os.path.join('D:\\JS06', 'data'),
- 'target_csv_path': os.path.join('D:\\JS06', 'target'),
- 'image_save_path': os.path.join('D:\\JS06', 'image'),
+ 'front_camera_name': 'XNP-9300RW_front',
+ 'front_camera_rtsp': 'rtsp://admin:sijung5520@121.153.143.180/profile2/media.smp',
+ 'front_main': 'rtsp://admin:sijung5520@121.153.143.180/profile4/media.smp',
+ 'rear_camera_name': 'XNP-9300RW_rear',
+ 'rear_camera_rtsp': 'rtsp://admin:sijung5520@121.153.143.180/profile2/media.smp',
+ 'rear_main': 'rtsp://admin:sijung5520@121.153.143.180/profile4/media.smp',
+
+ 'data_csv_path': os.path.join('C:\\JS08', 'data'),
+ 'target_csv_path': os.path.join('C:\\JS08', 'target'),
+ 'rgb_csv_path': os.path.join('C:\\JS08', 'rgb'),
+ 'image_save_path': os.path.join('C:\\JS08', 'image'),
+ 'log_path': os.path.join('C:\\JS08', 'log'),
'image_size': 0,
'visibility_alert_limit': 1000,
- 'login_id': 'admin',
- 'login_pw': '1234'
+ 'right': 'administrator',
+ 'admin_id': 'admin',
+ 'admin_pw': 'admin',
+ 'user': {},
+ 'current_id': '',
+ 'current_pw': '',
+ 'login_time': '',
+ 'login_flag': 0,
+ 'first_step': True,
+ 'maxfev_flag': False,
+ 'maxfev_count': 0,
+ 'afd': False,
+ 'log_key': b'',
}
@classmethod
@@ -35,7 +56,36 @@ def get(cls, key):
type(cls.defaults[key])
)
+ @classmethod
+ def get_user(cls, key):
+ return cls.settings.value(
+ key, cls.defaults[key]
+ )
+
@classmethod
def restore_defaults(cls):
for key, value in cls.defaults.items():
cls.set(key, value)
+
+ @classmethod
+ def restore_value(cls, key):
+ if key in cls.defaults.keys():
+ cls.set(key, cls.defaults[key])
+
+ @classmethod
+ def add_maxfev_time(cls, data: list):
+ for i in data:
+ cls.settings.setValue('maxfev_time', i)
+
+
+if __name__ == '__main__':
+
+ JS08Settings.restore_defaults()
+ user = JS08Settings.get_user('user')
+ # time_ = JS08Settings.get('login_time')
+ # print(time_)
+ # print(time_[-4])
+ # print(type(time_))
+ # print(user)
+ # user['user1'] = '1111'
+ # print(user)
diff --git a/src/nd01.py b/src/nd01.py
deleted file mode 100644
index 5bd57c5..0000000
--- a/src/nd01.py
+++ /dev/null
@@ -1,512 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 2021-2022 Sijung Co., Ltd.
-#
-# Authors:
-# cotjdals5450@gmail.com (Seong Min Chae)
-# 5jx2oh@gmail.com (Jongjin Oh)
-
-
-import sys
-import os
-import time
-
-import vlc
-import numpy as np
-import pyqtgraph as pg
-import multiprocessing as mp
-from multiprocessing import Process, Queue
-
-from PyQt5.QtGui import (QPixmap, QIcon, QPainter, QColor)
-from PyQt5.QtWidgets import (QMainWindow, QWidget, QGraphicsScene,
- QFrame, QVBoxLayout)
-from PyQt5.QtCore import (Qt, pyqtSlot, pyqtSignal, QRect,
- QTimer, QObject, QThread)
-from PyQt5.QtChart import (QChartView, QLegend, QLineSeries,
- QPolarChart, QScatterSeries, QValueAxis)
-from PyQt5 import uic
-
-from video_thread_mp import producer, VideoThread
-from nd01_settings import ND01SettingWidget
-from model import JS06Settings
-from save_db import main
-
-
-def clock(queue):
- """Real-time clock
- Current time to be expressed on JS-06
-
- :param queue: MultiProcessing Queue
- """
- while True:
- now = str(time.time())
- queue.put(now)
- time.sleep(1)
-
-
-class Consumer(QThread):
- poped = pyqtSignal(str)
-
- def __init__(self, q):
- super().__init__()
- self.q = q
- self.running = True
-
- def run(self):
- while self.running:
- if not self.q.empty():
- data = q.get()
- self.poped.emit(data)
-
- def pause(self):
- self.running = False
-
- def resume(self):
- self.running = True
-
-
-class TimeAxisItem(pg.AxisItem):
-
- def __init__(self, *args, **kwargs):
- super().__init__(*args, **kwargs)
- self.setLabel(text='Time (sec)', units=None)
- self.enableAutoSIPrefix(False)
-
- def tickStrings(self, values, scale, spacing):
- """
- override 하여, tick 옆에 써지는 문자를 원하는대로 수정함.
- values --> x축 값들
- 숫자로 이루어진 Iterable data(하나씩 차례로 반환 가능한 object -> ex) List[int]) list, str, tuple 등등
- """
- return [time.strftime("%H:%M:%S", time.localtime(local_time)) for local_time in values]
-
-
-class PlotWidget(QWidget):
-
- def __init__(self, parent=None):
- QWidget.__init__(self, parent)
-
- self.pw = pg.PlotWidget(
- labels={'left': 'Visibility (km)'},
- axisItems={'bottom': TimeAxisItem(orientation='bottom')}
- )
-
- self.pw.showGrid(x=True, y=True)
- self.pdi = self.pw.plot(pen='w') # PlotDataItem obj 반환.
-
- self.p1 = self.pw.plotItem
-
- self.p2 = pg.ViewBox()
- self.p1.showAxis('right')
- self.p1.scene().addItem(self.p2)
- self.p1.getAxis('right').linkToView(self.p2)
- self.p2.setXLink(self.p1)
- self.p1.getAxis('right').setLabel('Axis 2', color='#ffff00')
-
- self.p2.setGeometry(self.p1.vb.sceneBoundingRect())
- # self.p2.addItem(pg.PlotCurveItem([10, 20, 40, 80, 400, 2000], pen='y'))
- # self.pdi.sigClicked.connect(self.onclick)
-
- self.plotData = {'x': [], 'y': []}
- self.pre_plotData = {'x': [], 'y': []}
-
- def update_plot(self, new_time_data: int):
- self.plotData['x'].append(new_time_data)
- self.plotData['y'].append(np.random.randint(10000, 15000))
-
- # 항상 x축 시간을 설정한 범위 ( -3 시간 전 ~ 10 분 후 )만 보여줌.
- # self.pw.setXRange(new_time_data - 3600 * 3, new_time_data + 600, padding=0)
- # self.pw.setYRange(-1, 21, padding=0)
-
- data = []
- for i in self.plotData['y']:
- i = i / 1000
- data.append(i)
- self.pdi.setData(self.plotData['x'], data)
-
- # self.pdi.setData([1643873584, 1643873585, 1643873586, 1643873587, 1643873588],
- # [12, 11, 10, 14, 13])
-
- def onclick(self, plot, points):
- for point in points:
- print(point.pos())
-
-
-class PolarWidget(QWidget):
-
- def __init__(self, parent=None):
- QWidget.__init__(self, parent)
-
- self.pw = pg.plot(
- labels={'left': 'Visibility (km)'},
- axisItems={'bottom': TimeAxisItem(orientation='bottom')}
- )
-
- self.pw.showGrid(x=True, y=True)
- self.pdi = self.pw.plot(pen='w')
-
- self.pw.addLine(x=0, pen=0.2)
- self.pw.addLine(y=0, pen=0.2)
- for r in range(2, 20, 2):
- circle = pg.QtGui.QGraphicsEllipseItem(-r, -r, r * 2, r * 2)
- circle.setPen(pg.mkPen(0.2))
- self.pw.addItem(circle)
-
- theta = np.linspace(0, 2 * np.pi, 8)
- radius = np.random.normal(loc=10, size=8)
-
- x = radius * np.cos(theta)
- y = radius * np.sin(theta)
- self.pw.plot(x, y)
-
-
-class ThumbnailView(QMainWindow):
-
- def __init__(self, image_file_name: str, date: int):
- super().__init__()
-
- ui_path = os.path.join(os.path.dirname(os.path.realpath(__file__)),
- "ui/thumbnail_view.ui")
- uic.loadUi(ui_path, self)
-
- self.front_image.setPixmap(QPixmap(f'D:/ND-01/vista/{date}/{image_file_name}.png')
- .scaled(self.front_image.width(), self.front_image.height()))
- self.rear_image.setPixmap(QPixmap(f'D:/ND-01/vista/{date}/{image_file_name}.png')
- .scaled(self.rear_image.width(), self.rear_image.height()))
-
-
-class ND01MainWindow(QMainWindow):
-
- def __init__(self, q):
- super().__init__()
-
- ui_path = os.path.join(os.path.dirname(os.path.realpath(__file__)),
- "resources/main_window.ui")
- uic.loadUi(ui_path, self)
- self.showFullScreen()
- self._plot = PlotWidget()
- self._polar = PolarWidget()
- self.view = None
- self.km_mile_convert = False
- self.date = None
-
- self.front_video_widget = VideoWidget(self)
- self.front_video_widget.on_camera_change("rtsp://admin:sijung5520@192.168.100.101/profile2/media.smp")
-
- self.rear_video_widget = VideoWidget(self)
- self.rear_video_widget.on_camera_change("rtsp://admin:sijung5520@192.168.100.100/profile2/media.smp")
-
- self.video_horizontalLayout.addWidget(self.front_video_widget)
- self.video_horizontalLayout.addWidget(self.rear_video_widget)
-
- self.scene = QGraphicsScene()
- self.vis_plot.setScene(self.scene)
- self.plotWidget = self._plot.pw
- self.plotWidget.resize(600, 400)
- self.scene.addWidget(self.plotWidget)
-
- self.scene_polar = QGraphicsScene()
- self.polar_plot.setScene(self.scene_polar)
- self.polarWidget = self._polar.pw
- self.polarWidget.resize(600, 400)
- self.scene_polar.addWidget(self.polarWidget)
-
- self.setting_button.enterEvent = self.btn_on
- self.setting_button.leaveEvent = self.btn_off
-
- self.consumer = Consumer(q)
- self.consumer.poped.connect(self.clock)
- self.consumer.start()
-
- self.click_style = 'border: 1px solid red;'
-
- self.alert.clicked.connect(self.alert_test)
-
- self.c_vis_label.mousePressEvent = self.unit_convert
- self.p_vis_label.mousePressEvent = self.unit_convert
-
- self.label_1hour.mouseDoubleClickEvent = self.thumbnail_click1
- self.label_2hour.mouseDoubleClickEvent = self.thumbnail_click2
- self.label_3hour.mouseDoubleClickEvent = self.thumbnail_click3
- self.label_4hour.mouseDoubleClickEvent = self.thumbnail_click4
- self.label_5hour.mouseDoubleClickEvent = self.thumbnail_click5
- self.label_6hour.mouseDoubleClickEvent = self.thumbnail_click6
-
- self.setting_button.clicked.connect(self.setting_btn_click)
-
- self.show()
-
- def alert_test(self):
- self.alert.setIcon(QIcon('resources/asset/red.png'))
-
- def reset_StyleSheet(self):
- self.label_1hour.setStyleSheet('')
- self.label_2hour.setStyleSheet('')
- self.label_3hour.setStyleSheet('')
- self.label_4hour.setStyleSheet('')
- self.label_5hour.setStyleSheet('')
- self.label_6hour.setStyleSheet('')
-
- def thumbnail_view(self, file_name: str):
- self.view = ThumbnailView(file_name, self.date)
- self.view.setGeometry(QRect(self.video_horizontalLayout.geometry().x(),
- self.video_horizontalLayout.geometry().y() + 21,
- self.video_horizontalLayout.geometry().width(),
- self.video_horizontalLayout.geometry().height()))
- self.view.setWindowFlags(Qt.WindowStaysOnTopHint | Qt.FramelessWindowHint)
- self.view.setWindowModality(Qt.ApplicationModal)
- self.view.show()
-
- def thumbnail_click1(self, e):
- name = self.label_1hour_time.text()[:2] + self.label_1hour_time.text()[3:]
- epoch = time.strftime("%Y%m%d", time.localtime(time.time()))
- self.thumbnail_view(epoch + name + "00")
-
- self.reset_StyleSheet()
- self.label_1hour.setStyleSheet(self.click_style)
- self.monitoring_label.setText(f' {self.label_1hour_time.text()} image')
-
- QTimer.singleShot(5000, self.thumbnail_show)
-
- def thumbnail_click2(self, e):
- name = self.label_2hour_time.text()[:2] + self.label_2hour_time.text()[3:]
- epoch = time.strftime("%Y%m%d", time.localtime(time.time()))
- self.thumbnail_view(epoch + name + "00")
-
- self.reset_StyleSheet()
- self.label_2hour.setStyleSheet(self.click_style)
- self.monitoring_label.setText(f' {self.label_2hour_time.text()} image')
-
- QTimer.singleShot(5000, self.thumbnail_show)
-
- def thumbnail_click3(self, e):
- name = self.label_3hour_time.text()[:2] + self.label_3hour_time.text()[3:]
- epoch = time.strftime("%Y%m%d", time.localtime(time.time()))
- self.thumbnail_view(epoch + name + "00")
-
- self.reset_StyleSheet()
- self.label_3hour.setStyleSheet(self.click_style)
- self.monitoring_label.setText(f' {self.label_3hour_time.text()} image')
-
- QTimer.singleShot(5000, self.thumbnail_show)
-
- def thumbnail_click4(self, e):
- name = self.label_4hour_time.text()[:2] + self.label_4hour_time.text()[3:]
- epoch = time.strftime("%Y%m%d", time.localtime(time.time()))
- self.thumbnail_view(epoch + name + "00")
-
- self.reset_StyleSheet()
- self.label_4hour.setStyleSheet(self.click_style)
- self.monitoring_label.setText(f' {self.label_4hour_time.text()} image')
-
- QTimer.singleShot(5000, self.thumbnail_show)
-
- def thumbnail_click5(self, e):
- name = self.label_5hour_time.text()[:2] + self.label_5hour_time.text()[3:]
- epoch = time.strftime("%Y%m%d", time.localtime(time.time()))
- self.thumbnail_view(epoch + name + "00")
-
- self.reset_StyleSheet()
- self.label_5hour.setStyleSheet(self.click_style)
- self.monitoring_label.setText(f' {self.label_5hour_time.text()} image')
-
- QTimer.singleShot(5000, self.thumbnail_show)
-
- def thumbnail_click6(self, e):
- name = self.label_6hour_time.text()[:2] + self.label_6hour_time.text()[3:]
- epoch = time.strftime("%Y%m%d", time.localtime(time.time()))
- self.thumbnail_view(epoch + name + "00")
-
- self.reset_StyleSheet()
- self.label_6hour.setStyleSheet(self.click_style)
- self.monitoring_label.setText(f' {self.label_6hour_time.text()} image')
-
- QTimer.singleShot(5000, self.thumbnail_show)
-
- def thumbnail_show(self):
- self.monitoring_label.setText(' Monitoring')
- self.reset_StyleSheet()
- self.view.close()
-
- @pyqtSlot()
- def setting_btn_click(self):
- self.front_video_widget.media_player.stop()
- self.rear_video_widget.media_player.stop()
- self.consumer.pause()
-
- dlg = ND01SettingWidget()
- dlg.show()
- dlg.setWindowModality(Qt.ApplicationModal)
- dlg.exec_()
-
- self.front_video_widget.media_player.play()
- self.rear_video_widget.media_player.play()
- self.consumer.resume()
- self.consumer.start()
-
- def btn_on(self, event):
- self.setting_button.setIcon(QIcon('resources/asset/settings_on.png'))
-
- def btn_off(self, event):
- self.setting_button.setIcon(QIcon('resources/asset/settings.png'))
-
- def unit_convert(self, event):
- if self.km_mile_convert:
- self.km_mile_convert = False
- elif self.km_mile_convert is False:
- self.km_mile_convert = True
-
- @pyqtSlot(str)
- def clock(self, data):
- current_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(float(data)))
- self.date = current_time[2:4] + current_time[5:7]
- self.real_time_label.setText(current_time)
- self._plot.update_plot(int(float(data)))
-
- result = 0
- for i in self._plot.plotData['y']:
- result += i
- p_vis_km = f'{format(round(int(result / len(self._plot.plotData["y"])), 2), ",")}'
- p_vis_nm = f'{format(round(int(result / len(self._plot.plotData["y"])) / 1609, 2), ",")}'
-
- if self.km_mile_convert:
- self.c_vis_label.setText(f'{format(round(self._plot.plotData["y"][-1] / 1609, 2), ",")} mile')
- self.p_vis_label.setText(f'{p_vis_nm} mile')
-
- elif self.km_mile_convert is False:
- self.c_vis_label.setText(f'{format(self._plot.plotData["y"][-1], ",")} m')
- self.p_vis_label.setText(f'{p_vis_km} m')
-
- data_time = self._plot.plotData['x']
- if int(float(data)) - 3600 * 3 in self._plot.plotData['x']:
- index = data_time.index(int(float(data)) - 3600 * 3)
- self._plot.plotData['x'].pop(index)
- self._plot.plotData['y'].pop(index)
-
- self.thumbnail_refresh()
- if current_time[-2:] == "00":
- self.thumbnail_refresh()
-
- if int(p_vis_km.replace(',', '')) <= JS06Settings.get('visibility_alert_limit'):
- self.alert.setIcon(QIcon('resources/asset/red.png'))
-
- def thumbnail_refresh(self):
- one_hour_ago = time.strftime('%Y%m%d%H%M00', time.localtime(time.time() - 3600))
- two_hour_ago = time.strftime('%Y%m%d%H%M00', time.localtime(time.time() - 3600 * 2))
- three_hour_ago = time.strftime('%Y%m%d%H%M00', time.localtime(time.time() - 3600 * 3))
- four_hour_ago = time.strftime('%Y%m%d%H%M00', time.localtime(time.time() - 3600 * 4))
- five_hour_ago = time.strftime('%Y%m%d%H%M00', time.localtime(time.time() - 3600 * 5))
- six_hour_ago = time.strftime('%Y%m%d%H%M00', time.localtime(time.time() - 3600 * 6))
-
- self.label_1hour_time.setText(time.strftime('%H:%M', time.localtime(time.time() - 3600)))
- self.label_2hour_time.setText(time.strftime('%H:%M', time.localtime(time.time() - 3600 * 2)))
- self.label_3hour_time.setText(time.strftime('%H:%M', time.localtime(time.time() - 3600 * 3)))
- self.label_4hour_time.setText(time.strftime('%H:%M', time.localtime(time.time() - 3600 * 4)))
- self.label_5hour_time.setText(time.strftime('%H:%M', time.localtime(time.time() - 3600 * 5)))
- self.label_6hour_time.setText(time.strftime('%H:%M', time.localtime(time.time() - 3600 * 6)))
-
- self.label_1hour.setPixmap(
- QPixmap(f'{JS06Settings.get("image_save_path")}/resize/{self.date}/{one_hour_ago}.jpg'))
- self.label_2hour.setPixmap(
- QPixmap(f'{JS06Settings.get("image_save_path")}/resize/{self.date}/{two_hour_ago}.jpg'))
- self.label_3hour.setPixmap(
- QPixmap(f'{JS06Settings.get("image_save_path")}/resize/{self.date}/{three_hour_ago}.jpg'))
- self.label_4hour.setPixmap(
- QPixmap(f'{JS06Settings.get("image_save_path")}/resize/{self.date}/{four_hour_ago}.jpg'))
- self.label_5hour.setPixmap(
- QPixmap(f'{JS06Settings.get("image_save_path")}/resize/{self.date}/{five_hour_ago}.jpg'))
- self.label_6hour.setPixmap(
- QPixmap(f'{JS06Settings.get("image_save_path")}/resize/{self.date}/{six_hour_ago}.jpg'))
-
- def keyPressEvent(self, e):
- """Override function QMainwindow KeyPressEvent that works when key is pressed"""
- if e.key() == Qt.Key_F:
- self.showFullScreen()
- if e.key() == Qt.Key_D:
- self.showNormal()
-
-
-class VideoWidget(QWidget):
- """Video stream player using QVideoWidget"""
- video_frame = None
-
- def __init__(self, parent: QObject = None):
- super().__init__(parent)
-
- args = [
- "--rtsp-frame-buffer-size",
- "1000000"
- ]
-
- self.instance = vlc.Instance(args)
- self.instance.log_unset()
- self.media_player = self.instance.media_player_new()
-
- self.image_player = self.instance.media_list_player_new()
- self.image_media = self.instance.media_list_new('')
-
- self.video_frame = QFrame()
-
- if sys.platform == 'win32':
- self.media_player.set_hwnd(self.video_frame.winId())
-
- layout = QVBoxLayout(self)
- layout.addWidget(self.video_frame)
-
- @pyqtSlot(str)
- def on_camera_change(self, uri: str):
- # uri = "rtsp://admin:sijung5520@192.168.100.100/profile2/media.smp"
- if uri[:4] == "rtsp":
- self.media_player.set_media(self.instance.media_new(uri))
- self.media_player.play()
- else:
- pass
-
-
-class MainCtrl(QObject):
- front_camera_changed = pyqtSignal(str)
- rear_camera_changed = pyqtSignal(str)
-
- def __init__(self):
- super().__init__()
-
- self.front_target_prepared = False
- self.rear_target_prepared = False
-
- self.front_camera_changed.connect(self.decompose_front_targets)
- self.rear_camera_changed.connect(self.decompose_rear_targets)
-
- @pyqtSlot(str)
- def decompose_front_targets(self, _: str):
- self.front_target_prepared = False
- self.decompose_targets('front')
- self.front_target_prepared = True
-
-
-if __name__ == '__main__':
-
- from PyQt5.QtWidgets import QApplication
-
- mp.freeze_support()
- q = Queue()
- _q = Queue()
-
- _producer = producer
-
- p = Process(name='clock', target=clock, args=(q, ), daemon=True)
- _p = Process(name="producer", target=_producer, args=(_q, ), daemon=True)
-
- p.start()
- _p.start()
-
- os.makedirs('D:/ND-01/vista', exist_ok=True)
- os.makedirs('D:/ND-01/resize', exist_ok=True)
-
- app = QApplication(sys.argv)
- window = ND01MainWindow(q)
- sys.exit(app.exec_())
-
- # MainWindow = QMainWindow()
- # ui = ND01MainWindow()
- # ui.show()
- # sys.exit(app.exec_())
diff --git a/src/nd01_settings.py b/src/nd01_settings.py
deleted file mode 100644
index 9d8e2b7..0000000
--- a/src/nd01_settings.py
+++ /dev/null
@@ -1,350 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 2021-2022 Sijung Co., Ltd.
-#
-# Authors:
-# cotjdals5450@gmail.com (Seong Min Chae)
-# 5jx2oh@gmail.com (Jongjin Oh)
-
-
-import os
-
-import cv2
-import pandas as pd
-from PyQt5 import uic
-from PyQt5.QtCore import (QPoint, QRect, Qt)
-from PyQt5.QtGui import (QPixmap, QPainter, QBrush,
- QColor, QPen, QImage,
- QIcon)
-from PyQt5.QtWidgets import (QApplication, QLabel, QInputDialog,
- QDialog, QAbstractItemView, QVBoxLayout,
- QGridLayout, QPushButton, QMessageBox,
- QFileDialog)
-from model import JS06Settings
-
-
-class ND01SettingWidget(QDialog):
-
- def __init__(self, *args, **kwargs):
-
- super().__init__(*args, **kwargs)
- ui_path = os.path.join(os.path.dirname(os.path.realpath(__file__)),
- "resources/settings.ui")
- uic.loadUi(ui_path, self)
- # self.setWindowFlag(Qt.FramelessWindowHint)
-
- self.begin = QPoint()
- self.end = QPoint()
- self.upper_left = ()
- self.lower_right = ()
- self.left_range = []
- self.right_range = []
- self.distance = []
- self.target_name = []
- self.min_xy = ()
-
- self.isDrawing = False
- self.draw_flag = False
- self.cam_flag = False
-
- self.video_width = 0
- self.video_height = 0
-
- self.cp_image = None
- self.end_drawing = None
-
- self.current_camera = ""
-
- self.image_load()
-
- # 그림 그리는 삐뮤디 생성
- # self.blank_lbl = QLabel(self.image_label)
- # # self.blank_lbl.setGeometry(0, 0, 1200, 500)
- # self.blank_lbl.paintEvent = self.lbl_paintEvent
- #
- # self.blank_lbl.mousePressEvent = self.lbl_mousePressEvent
- # self.blank_lbl.mouseMoveEvent = self.lbl_mouseMoveEvent
- # self.blank_lbl.mouseReleaseEvent = self.lbl_mouseReleaseEvent
-
- self.flip_button.clicked.connect(self.camera_flip)
- self.flip_button.enterEvent = self.btn_on
- self.flip_button.leaveEvent = self.btn_off
-
- self.data_csv_path_button.clicked.connect(self.data_csv_path)
- self.target_csv_path_button.clicked.connect(self.target_csv_path)
- self.image_save_path_button.clicked.connect(self.image_save_path)
-
- self.data_csv_path_textBrowser.setPlainText(JS06Settings.get('data_csv_path'))
- self.target_csv_path_textBrowser.setPlainText(JS06Settings.get('target_csv_path'))
- self.image_save_path_textBrowser.setPlainText(JS06Settings.get('image_save_path'))
-
- self.vis_limit_spinBox.setValue(JS06Settings.get('visibility_alert_limit'))
- self.id_lineEdit.setText(JS06Settings.get('login_id'))
- self.pw_lineEdit.setText(JS06Settings.get('login_pw'))
-
- self.image_size_comboBox.setCurrentIndex(JS06Settings.get('image_size'))
- # self.image_size_comboBox.currentTextChanged.connect(self.image_size_changed)
-
- self.image_label.paintEvent = self.lbl_paintEvent
- self.image_label.mousePressEvent = self.lbl_mousePressEvent
- self.image_label.mouseMoveEvent = self.lbl_mouseMoveEvent
- self.image_label.mouseReleaseEvent = self.lbl_mouseReleaseEvent
-
- self.get_target()
-
- self.buttonBox.accepted.connect(self.accept_click)
- self.buttonBox.rejected.connect(self.reject)
-
- def camera_flip(self):
- if self.cam_flag:
- self.cam_flag = False
- else:
- self.cam_flag = True
- self.image_load()
-
- def btn_on(self, e):
- self.flip_button.setIcon(QIcon('resources/asset/flip_on.png'))
-
- def btn_off(self, e):
- self.flip_button.setIcon(QIcon('resources/asset/flip_off.png'))
-
- def image_load(self):
- # self.image_label.update()
-
- if self.cam_flag:
- src = "rtsp://admin:sijung5520@192.168.100.100/profile2/media.smp"
- self.target_setting_label.setText(' Rear Target Setting')
- self.current_camera = 'PNM_9030V'
- self.get_target()
-
- else:
- src = "rtsp://admin:sijung5520@192.168.100.101/profile2/media.smp"
- self.target_setting_label.setText(' Front Target Setting')
- self.current_camera = 'PNM_9022V'
- self.get_target()
-
- try:
- print(f'현재 카메라 {self.current_camera}')
-
- os.makedirs(f'{JS06Settings.get("target_csv_path")}/{self.current_camera}', exist_ok=True)
- cap = cv2.VideoCapture(src)
- ret, cv_img = cap.read()
- cp_image = cv_img.copy()
- cap.release()
- except Exception as e:
- QMessageBox.about(self, 'Error', f'{e}')
-
- self.image_label.setPixmap(self.convert_cv_qt(cp_image))
-
- def convert_cv_qt(self, cv_img):
- """Convert CV image to QImage."""
- cv_img = cv_img.copy()
- cv_img = cv2.cvtColor(cv_img, cv2.COLOR_BGR2RGB)
-
- self.cp_image = cv_img.copy()
-
- self.video_height, self.video_width, ch = cv_img.shape
-
- bytes_per_line = ch * self.video_width
- convert_to_Qt_format = QImage(cv_img.data, self.video_width, self.video_height,
- bytes_per_line, QImage.Format_RGB888)
- p = convert_to_Qt_format.scaled(self.image_label.width(),
- self.image_label.height(),
- Qt.KeepAspectRatio, Qt.SmoothTransformation)
-
- return QPixmap.fromImage(p)
-
- def lbl_paintEvent(self, event):
- painter = QPainter(self.image_label)
-
- back_ground_image = self.thumbnail(self.cp_image)
- bk_image = QPixmap.fromImage(back_ground_image)
- painter.drawPixmap(QRect(0, 0, self.image_label.width(),
- self.image_label.height()), bk_image)
-
- for corner1, corner2, in zip(self.left_range, self.right_range):
- br = QBrush(QColor(100, 10, 10, 40))
- painter.setBrush(br)
- painter.setPen(QPen(Qt.red, 2, Qt.SolidLine))
- corner1_1 = int(corner1[0] / self.video_width * self.image_label.width())
- corner1_2 = int(corner1[1] / self.video_height * self.image_label.height())
- corner2_1 = int((corner2[0] - corner1[0]) / self.video_width * self.image_label.width())
- corner2_2 = int((corner2[1] - corner1[1]) / self.video_height * self.image_label.height())
- painter.drawRect(QRect(corner1_1, corner1_2, corner2_1, corner2_2))
-
- if self.isDrawing:
- br = QBrush(QColor(100, 10, 10, 40))
- painter.setBrush(br)
- painter.setPen(QPen(Qt.red, 2, Qt.SolidLine))
- painter.drawRect(QRect(self.begin, self.end))
- th_x, th_y = self.thumbnail_pos(self.end)
- th_qImage = self.thumbnail(self.cp_image[th_y - 50:th_y + 50, th_x - 50:th_x + 50, :])
- thumbnail_image = QPixmap.fromImage(th_qImage)
- painter.drawPixmap(QRect(self.end.x(), self.end.y(), 200, 200), thumbnail_image)
-
- if self.end_drawing:
- painter.eraseRect(QRect(self.begin, self.end))
- painter.eraseRect(QRect(self.end.x(), self.end.y(), 200, 200))
- self.end_drawing = False
- self.isDrawing = False
- painter.end()
-
- def str_to_tuple(self, before_list):
- """저장된 타겟들의 위치정보인 튜플 리스트가 문자열로 바뀌어 다시 튜플형태로 변환하는 함수"""
- tuple_list = [i.split(',') for i in before_list]
- tuple_list = [(int(i[0][1:]), int(i[1][:-1])) for i in tuple_list]
- return tuple_list
-
- # 타겟 조정 및 썸네일 관련 함수 시작
- def thumbnail_pos(self, end_pos):
- x = int((end_pos.x() / self.image_label.width()) * self.video_width)
- y = int((end_pos.y() / self.image_label.height()) * self.video_height)
- return x, y
-
- def thumbnail(self, image):
- height, width, channel = image.shape
- bytesPerLine = channel * width
- qImg = QImage(image.data.tobytes(), width, height, bytesPerLine, QImage.Format_RGB888)
- return qImg
-
- def lbl_mousePressEvent(self, event):
- """마우스 클릭시 발생하는 이벤트, QLabel method overriding"""
-
- # 좌 클릭시 실행
- if event.buttons() == Qt.LeftButton:
- self.isDrawing = True
- self.begin = event.pos()
- self.end = event.pos()
- self.upper_left = (int((self.begin.x() / self.image_label.width()) * self.video_width),
- int((self.begin.y() / self.image_label.height()) * self.video_height))
- self.image_label.update()
-
- self.draw_flag = True
-
- # 우 클릭시 실행
- elif event.buttons() == Qt.RightButton:
- self.isDrawing = False
- if len(self.left_range) > 0:
- del self.distance[-1]
- del self.target_name[-1]
- del self.left_range[-1]
- del self.right_range[-1]
- self.save_target(self.current_camera)
- self.draw_flag = False
- self.image_label.update()
-
- def lbl_mouseMoveEvent(self, event):
- """마우스가 움직일 때 발생하는 이벤트, QLabel method overriding"""
- if event.buttons() == Qt.LeftButton:
- self.end = event.pos()
- self.image_label.update()
- self.isDrawing = True
-
- def lbl_mouseReleaseEvent(self, event):
- """마우스 클릭이 떼질 때 발생하는 이벤트, QLabel method overriding"""
- if self.draw_flag:
- self.end = event.pos()
- self.image_label.update()
- self.lower_right = (int((self.end.x() / self.image_label.width()) * self.video_width),
- int((self.end.y() / self.image_label.height()) * self.video_height))
- text, ok = QInputDialog.getText(self, '거리 입력', '거리(km)')
- if ok:
- self.left_range.append(self.upper_left)
- self.right_range.append(self.lower_right)
- self.distance.append(text)
- # self.min_xy = self.minrgb(self.upper_left, self.lower_right)
- self.target_name.append("target_" + str(len(self.left_range)))
- self.save_target(self.current_camera)
- self.isDrawing = False
- self.end_drawing = True
-
- print(f'{text} km')
- else:
- self.isDrawing = False
- self.image_label.update()
-
- def data_csv_path(self):
- fName = QFileDialog.getExistingDirectory(
- self, 'Select path to save data csv file', JS06Settings.get('data_csv_path'))
- if fName:
- self.data_csv_path_textBrowser.setPlainText(fName)
- else:
- pass
-
- def target_csv_path(self):
- fName = QFileDialog.getExistingDirectory(
- self, 'Select path to save target csv file', JS06Settings.get('target_csv_path'))
- if fName:
- self.target_csv_path_textBrowser.setPlainText(fName)
- else:
- pass
-
- def image_save_path(self):
- fName = QFileDialog.getExistingDirectory(
- self, 'Select path to save image file', JS06Settings.get('image_save_path'))
- if fName:
- self.image_save_path_textBrowser.setPlainText(fName)
- else:
- pass
-
- def save_vis(self):
-
- col = ['datetime', 'camera_direction',
- 'N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW',
- 'prevailing_visibility']
- result = pd.DataFrame(col)
- print(result)
- # result['datetime'] =
- # result['camera_direction'] =
- # result['N'] =
- # result['NE'] =
- # result['E'] =
- # result['SE'] =
- # result['S'] =
- # result['SW'] =
- # result['W'] =
- # result['NW'] =
- # result['prevailing_visibility'] =
- # result.to_csv(f'{JS06Settings.get("data_csv_path")}/{self.current_camera}/{self.current_camera}.csv',
- # index=False)
-
- def save_target(self, camera: str):
-
- print(f'타겟을 저장합니다 - {camera}')
- if self.left_range:
- col = ['target_name', 'left_range', 'right_range', 'distance']
- result = pd.DataFrame(columns=col)
- result['target_name'] = self.target_name
- result['left_range'] = self.left_range
- result['right_range'] = self.right_range
- result['distance'] = self.distance
- result.to_csv(f'{JS06Settings.get("target_csv_path")}/{camera}/{camera}.csv',
- mode='w', index=False)
- print(f'{JS06Settings.get("target_csv_path")}/{camera}/{camera}.csv - SAVED!!!!')
-
- def get_target(self):
- print("타겟을 불러옵니다.")
-
- save_path = os.path.join(f'{JS06Settings.get("target_csv_path")}/{self.current_camera}')
- if os.path.isfile(f'{save_path}/{self.current_camera}.csv'):
- target_df = pd.read_csv(f'{save_path}/{self.current_camera}.csv')
- self.target_name = target_df["target_name"].tolist()
- self.left_range = self.str_to_tuple(target_df["left_range"].tolist())
- self.right_range = self.str_to_tuple(target_df["right_range"].tolist())
- self.distance = target_df["distance"].tolist()
- else:
- QMessageBox.about(self, 'Error', 'no file...')
-
- def accept_click(self):
- print('accept? yes accept~')
-
- # JS06Settings.set('data_csv_path', self.)
-
-
-if __name__ == '__main__':
- import sys
-
- app = QApplication(sys.argv)
- ui = ND01SettingWidget()
- ui.show()
- sys.exit(app.exec_())
diff --git a/src/resource_path.py b/src/resource_path.py
new file mode 100644
index 0000000..b72327f
--- /dev/null
+++ b/src/resource_path.py
@@ -0,0 +1,25 @@
+#!/usr/bin/env python3
+#
+# Copyright 2021-2022 Sijung Co., Ltd.
+#
+# Authors:
+# cotjdals5450@gmail.com (Seong Min Chae)
+# 5jx2oh@gmail.com (Jongjin Oh)
+
+import os
+import sys
+
+
+def resource_path(relative_path: str):
+ """
+ Get absolute path to resource, works for dev and for PyInstaller
+
+ :param relative_path: Files to reference
+ :return: os.path.join
+ """
+ try:
+ base_path = sys._MEIPASS
+ except Exception:
+ base_path = os.path.abspath('.')
+
+ return os.path.join(base_path, relative_path)
diff --git a/src/resources/Frutiger-Neue-1450-W04-Regular.ttf b/src/resources/Frutiger-Neue-1450-W04-Regular.ttf
new file mode 100644
index 0000000..d945c40
Binary files /dev/null and b/src/resources/Frutiger-Neue-1450-W04-Regular.ttf differ
diff --git a/src/resources/admin_menu.py b/src/resources/admin_menu.py
new file mode 100644
index 0000000..c3aa98d
--- /dev/null
+++ b/src/resources/admin_menu.py
@@ -0,0 +1,605 @@
+# -*- coding: utf-8 -*-
+
+################################################################################
+## Form generated from reading UI file 'admin_menu.ui'
+##
+## Created by: Qt User Interface Compiler version 6.3.0
+##
+## 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 (QAbstractButton, QApplication, QCheckBox, QComboBox,
+ QDialog, QDialogButtonBox, QGridLayout, QHBoxLayout,
+ QHeaderView, QLabel, QLayout, QLineEdit,
+ QPushButton, QSizePolicy, QSpinBox, QTableWidget,
+ QTableWidgetItem, QTextBrowser, QTextEdit, QVBoxLayout,
+ QWidget)
+
+class Ui_Dialog(object):
+ def setupUi(self, Dialog):
+ if not Dialog.objectName():
+ Dialog.setObjectName(u"Dialog")
+ Dialog.resize(1920, 1080)
+ sizePolicy = QSizePolicy(QSizePolicy.Maximum, QSizePolicy.Preferred)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(Dialog.sizePolicy().hasHeightForWidth())
+ Dialog.setSizePolicy(sizePolicy)
+ self.gridLayout = QGridLayout(Dialog)
+ self.gridLayout.setSpacing(0)
+ self.gridLayout.setObjectName(u"gridLayout")
+ self.gridLayout.setContentsMargins(0, 0, 0, 0)
+ self.gridWidget = QWidget(Dialog)
+ self.gridWidget.setObjectName(u"gridWidget")
+ self.gridWidget.setStyleSheet(u"background-color:rgb(22,32,42);")
+ self.gridLayout_2 = QGridLayout(self.gridWidget)
+ self.gridLayout_2.setObjectName(u"gridLayout_2")
+ self.main_verticalLayout = QVBoxLayout()
+ self.main_verticalLayout.setObjectName(u"main_verticalLayout")
+ self.top_horizontalLayout = QHBoxLayout()
+ self.top_horizontalLayout.setObjectName(u"top_horizontalLayout")
+ self.setting_verticalLayout = QVBoxLayout()
+ self.setting_verticalLayout.setObjectName(u"setting_verticalLayout")
+ self.setting_horizontalLayout = QHBoxLayout()
+ self.setting_horizontalLayout.setSpacing(0)
+ self.setting_horizontalLayout.setObjectName(u"setting_horizontalLayout")
+ self.target_setting_label = QLabel(self.gridWidget)
+ self.target_setting_label.setObjectName(u"target_setting_label")
+ sizePolicy1 = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Maximum)
+ sizePolicy1.setHorizontalStretch(0)
+ sizePolicy1.setVerticalStretch(0)
+ sizePolicy1.setHeightForWidth(self.target_setting_label.sizePolicy().hasHeightForWidth())
+ self.target_setting_label.setSizePolicy(sizePolicy1)
+ font = QFont()
+ font.setFamilies([u"Noto Sans"])
+ font.setPointSize(23)
+ self.target_setting_label.setFont(font)
+ self.target_setting_label.setStyleSheet(u"background-color:rgb(27,49,70);\n"
+"color: #ffffff;")
+
+ self.setting_horizontalLayout.addWidget(self.target_setting_label)
+
+ self.flip_button = QPushButton(self.gridWidget)
+ self.flip_button.setObjectName(u"flip_button")
+ sizePolicy2 = QSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum)
+ sizePolicy2.setHorizontalStretch(0)
+ sizePolicy2.setVerticalStretch(0)
+ sizePolicy2.setHeightForWidth(self.flip_button.sizePolicy().hasHeightForWidth())
+ self.flip_button.setSizePolicy(sizePolicy2)
+ self.flip_button.setMinimumSize(QSize(0, 42))
+ font1 = QFont()
+ font1.setFamilies([u"Noto Sans"])
+ font1.setPointSize(15)
+ self.flip_button.setFont(font1)
+ self.flip_button.setCursor(QCursor(Qt.PointingHandCursor))
+ self.flip_button.setStyleSheet(u"border:0px;\n"
+"background-color: #1b3146;\n"
+"color: #ffffff;")
+ icon = QIcon()
+ icon.addFile(u"asset/flip_off.png", QSize(), QIcon.Normal, QIcon.Off)
+ self.flip_button.setIcon(icon)
+ self.flip_button.setIconSize(QSize(40, 40))
+ self.flip_button.setFlat(True)
+
+ self.setting_horizontalLayout.addWidget(self.flip_button)
+
+
+ self.setting_verticalLayout.addLayout(self.setting_horizontalLayout)
+
+ self.image_label = QLabel(self.gridWidget)
+ self.image_label.setObjectName(u"image_label")
+ sizePolicy3 = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)
+ sizePolicy3.setHorizontalStretch(0)
+ sizePolicy3.setVerticalStretch(0)
+ sizePolicy3.setHeightForWidth(self.image_label.sizePolicy().hasHeightForWidth())
+ self.image_label.setSizePolicy(sizePolicy3)
+ self.image_label.setMinimumSize(QSize(0, 0))
+ self.image_label.setMaximumSize(QSize(16777215, 16777215))
+
+ self.setting_verticalLayout.addWidget(self.image_label)
+
+
+ self.top_horizontalLayout.addLayout(self.setting_verticalLayout)
+
+
+ self.main_verticalLayout.addLayout(self.top_horizontalLayout)
+
+ self.bottom_horizontalLayout = QHBoxLayout()
+ self.bottom_horizontalLayout.setSpacing(12)
+ self.bottom_horizontalLayout.setObjectName(u"bottom_horizontalLayout")
+ self.target_list_verticalLayout = QVBoxLayout()
+ self.target_list_verticalLayout.setSpacing(0)
+ self.target_list_verticalLayout.setObjectName(u"target_list_verticalLayout")
+ self.target_list_verticalLayout.setContentsMargins(6, -1, -1, -1)
+ self.target_list_label = QLabel(self.gridWidget)
+ self.target_list_label.setObjectName(u"target_list_label")
+ sizePolicy1.setHeightForWidth(self.target_list_label.sizePolicy().hasHeightForWidth())
+ self.target_list_label.setSizePolicy(sizePolicy1)
+ self.target_list_label.setFont(font)
+ self.target_list_label.setStyleSheet(u"background-color:rgb(27,49,70);\n"
+"color: #ffffff;")
+
+ self.target_list_verticalLayout.addWidget(self.target_list_label)
+
+ self.tableWidget = QTableWidget(self.gridWidget)
+ self.tableWidget.setObjectName(u"tableWidget")
+ self.tableWidget.setMaximumSize(QSize(700, 500))
+
+ self.target_list_verticalLayout.addWidget(self.tableWidget)
+
+
+ self.bottom_horizontalLayout.addLayout(self.target_list_verticalLayout)
+
+ self.value_verticalLayout = QVBoxLayout()
+ self.value_verticalLayout.setSpacing(0)
+ self.value_verticalLayout.setObjectName(u"value_verticalLayout")
+ self.value_label = QLabel(self.gridWidget)
+ self.value_label.setObjectName(u"value_label")
+ sizePolicy1.setHeightForWidth(self.value_label.sizePolicy().hasHeightForWidth())
+ self.value_label.setSizePolicy(sizePolicy1)
+ self.value_label.setFont(font)
+ self.value_label.setStyleSheet(u"background-color:rgb(27,49,70);\n"
+"color: #ffffff;")
+
+ self.value_verticalLayout.addWidget(self.value_label)
+
+ self.horizontalLayout = QHBoxLayout()
+ self.horizontalLayout.setSpacing(0)
+ self.horizontalLayout.setObjectName(u"horizontalLayout")
+ self.graph_verticalLayout = QVBoxLayout()
+ self.graph_verticalLayout.setSpacing(0)
+ self.graph_verticalLayout.setObjectName(u"graph_verticalLayout")
+
+ self.horizontalLayout.addLayout(self.graph_verticalLayout)
+
+ self.verticalLayout = QVBoxLayout()
+ self.verticalLayout.setSpacing(0)
+ self.verticalLayout.setObjectName(u"verticalLayout")
+ self.verticalLayout.setSizeConstraint(QLayout.SetMaximumSize)
+ self.label = QLabel(self.gridWidget)
+ self.label.setObjectName(u"label")
+
+ self.verticalLayout.addWidget(self.label)
+
+ self.red_checkBox = QCheckBox(self.gridWidget)
+ self.red_checkBox.setObjectName(u"red_checkBox")
+ sizePolicy4 = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Maximum)
+ sizePolicy4.setHorizontalStretch(0)
+ sizePolicy4.setVerticalStretch(0)
+ sizePolicy4.setHeightForWidth(self.red_checkBox.sizePolicy().hasHeightForWidth())
+ self.red_checkBox.setSizePolicy(sizePolicy4)
+ font2 = QFont()
+ font2.setFamilies([u"Noto Sans"])
+ font2.setBold(False)
+ self.red_checkBox.setFont(font2)
+ self.red_checkBox.setStyleSheet(u"\n"
+"color: #ffffff;")
+ self.red_checkBox.setChecked(True)
+
+ self.verticalLayout.addWidget(self.red_checkBox)
+
+ self.green_checkBox = QCheckBox(self.gridWidget)
+ self.green_checkBox.setObjectName(u"green_checkBox")
+ sizePolicy4.setHeightForWidth(self.green_checkBox.sizePolicy().hasHeightForWidth())
+ self.green_checkBox.setSizePolicy(sizePolicy4)
+ self.green_checkBox.setFont(font2)
+ self.green_checkBox.setStyleSheet(u"\n"
+"color: #ffffff;")
+ self.green_checkBox.setChecked(True)
+
+ self.verticalLayout.addWidget(self.green_checkBox)
+
+ self.blue_checkBox = QCheckBox(self.gridWidget)
+ self.blue_checkBox.setObjectName(u"blue_checkBox")
+ sizePolicy4.setHeightForWidth(self.blue_checkBox.sizePolicy().hasHeightForWidth())
+ self.blue_checkBox.setSizePolicy(sizePolicy4)
+ self.blue_checkBox.setFont(font2)
+ self.blue_checkBox.setStyleSheet(u"\n"
+"color: #ffffff;")
+ self.blue_checkBox.setChecked(True)
+
+ self.verticalLayout.addWidget(self.blue_checkBox)
+
+ self.label_2 = QLabel(self.gridWidget)
+ self.label_2.setObjectName(u"label_2")
+
+ self.verticalLayout.addWidget(self.label_2)
+
+
+ self.horizontalLayout.addLayout(self.verticalLayout)
+
+
+ self.value_verticalLayout.addLayout(self.horizontalLayout)
+
+
+ self.bottom_horizontalLayout.addLayout(self.value_verticalLayout)
+
+ self.etc_verticalLayout = QVBoxLayout()
+ self.etc_verticalLayout.setSpacing(3)
+ self.etc_verticalLayout.setObjectName(u"etc_verticalLayout")
+ self.setting_label = QLabel(self.gridWidget)
+ self.setting_label.setObjectName(u"setting_label")
+ sizePolicy1.setHeightForWidth(self.setting_label.sizePolicy().hasHeightForWidth())
+ self.setting_label.setSizePolicy(sizePolicy1)
+ self.setting_label.setFont(font)
+ self.setting_label.setStyleSheet(u"background-color:rgb(27,49,70);\n"
+"color: #ffffff;")
+
+ self.etc_verticalLayout.addWidget(self.setting_label)
+
+ self.data_csv_horizontalLayout = QHBoxLayout()
+ self.data_csv_horizontalLayout.setSpacing(0)
+ self.data_csv_horizontalLayout.setObjectName(u"data_csv_horizontalLayout")
+ self.data_csv_path_label = QLabel(self.gridWidget)
+ self.data_csv_path_label.setObjectName(u"data_csv_path_label")
+ sizePolicy3.setHeightForWidth(self.data_csv_path_label.sizePolicy().hasHeightForWidth())
+ self.data_csv_path_label.setSizePolicy(sizePolicy3)
+ font3 = QFont()
+ font3.setFamilies([u"Noto Sans KR Medium"])
+ font3.setPointSize(10)
+ self.data_csv_path_label.setFont(font3)
+ self.data_csv_path_label.setStyleSheet(u"background-color:rgb(27,49,70);\n"
+"color: #ffffff;")
+
+ self.data_csv_horizontalLayout.addWidget(self.data_csv_path_label)
+
+ self.data_csv_path_textBrowser = QTextBrowser(self.gridWidget)
+ self.data_csv_path_textBrowser.setObjectName(u"data_csv_path_textBrowser")
+ sizePolicy1.setHeightForWidth(self.data_csv_path_textBrowser.sizePolicy().hasHeightForWidth())
+ self.data_csv_path_textBrowser.setSizePolicy(sizePolicy1)
+ self.data_csv_path_textBrowser.setMaximumSize(QSize(16777215, 50))
+ self.data_csv_path_textBrowser.setStyleSheet(u"background-color: rgb(255, 255, 255);")
+
+ self.data_csv_horizontalLayout.addWidget(self.data_csv_path_textBrowser)
+
+ self.data_csv_path_button = QPushButton(self.gridWidget)
+ self.data_csv_path_button.setObjectName(u"data_csv_path_button")
+ sizePolicy1.setHeightForWidth(self.data_csv_path_button.sizePolicy().hasHeightForWidth())
+ self.data_csv_path_button.setSizePolicy(sizePolicy1)
+ self.data_csv_path_button.setMaximumSize(QSize(50, 50))
+ font4 = QFont()
+ font4.setFamilies([u"Arial"])
+ font4.setPointSize(17)
+ self.data_csv_path_button.setFont(font4)
+ self.data_csv_path_button.setStyleSheet(u"background-color:rgb(27,49,70);\n"
+"color: #ffffff;")
+
+ self.data_csv_horizontalLayout.addWidget(self.data_csv_path_button)
+
+
+ self.etc_verticalLayout.addLayout(self.data_csv_horizontalLayout)
+
+ self.target_csv_horizontalLayout = QHBoxLayout()
+ self.target_csv_horizontalLayout.setSpacing(0)
+ self.target_csv_horizontalLayout.setObjectName(u"target_csv_horizontalLayout")
+ self.target_csv_path_label = QLabel(self.gridWidget)
+ self.target_csv_path_label.setObjectName(u"target_csv_path_label")
+ sizePolicy3.setHeightForWidth(self.target_csv_path_label.sizePolicy().hasHeightForWidth())
+ self.target_csv_path_label.setSizePolicy(sizePolicy3)
+ self.target_csv_path_label.setFont(font3)
+ self.target_csv_path_label.setStyleSheet(u"background-color:rgb(27,49,70);\n"
+"color: #ffffff;")
+
+ self.target_csv_horizontalLayout.addWidget(self.target_csv_path_label)
+
+ self.target_csv_path_textBrowser = QTextBrowser(self.gridWidget)
+ self.target_csv_path_textBrowser.setObjectName(u"target_csv_path_textBrowser")
+ sizePolicy1.setHeightForWidth(self.target_csv_path_textBrowser.sizePolicy().hasHeightForWidth())
+ self.target_csv_path_textBrowser.setSizePolicy(sizePolicy1)
+ self.target_csv_path_textBrowser.setMaximumSize(QSize(16777215, 50))
+ self.target_csv_path_textBrowser.setStyleSheet(u"background-color: rgb(255, 255, 255);")
+
+ self.target_csv_horizontalLayout.addWidget(self.target_csv_path_textBrowser)
+
+ self.target_csv_path_button = QPushButton(self.gridWidget)
+ self.target_csv_path_button.setObjectName(u"target_csv_path_button")
+ sizePolicy1.setHeightForWidth(self.target_csv_path_button.sizePolicy().hasHeightForWidth())
+ self.target_csv_path_button.setSizePolicy(sizePolicy1)
+ self.target_csv_path_button.setMaximumSize(QSize(50, 50))
+ self.target_csv_path_button.setFont(font4)
+ self.target_csv_path_button.setStyleSheet(u"background-color:rgb(27,49,70);\n"
+"color: #ffffff;")
+
+ self.target_csv_horizontalLayout.addWidget(self.target_csv_path_button)
+
+
+ self.etc_verticalLayout.addLayout(self.target_csv_horizontalLayout)
+
+ self.image_save_horizontalLayout = QHBoxLayout()
+ self.image_save_horizontalLayout.setSpacing(0)
+ self.image_save_horizontalLayout.setObjectName(u"image_save_horizontalLayout")
+ self.image_save_path_label = QLabel(self.gridWidget)
+ self.image_save_path_label.setObjectName(u"image_save_path_label")
+ sizePolicy3.setHeightForWidth(self.image_save_path_label.sizePolicy().hasHeightForWidth())
+ self.image_save_path_label.setSizePolicy(sizePolicy3)
+ self.image_save_path_label.setFont(font3)
+ self.image_save_path_label.setStyleSheet(u"background-color:rgb(27,49,70);\n"
+"color: #ffffff;")
+
+ self.image_save_horizontalLayout.addWidget(self.image_save_path_label)
+
+ self.image_save_path_textBrowser = QTextBrowser(self.gridWidget)
+ self.image_save_path_textBrowser.setObjectName(u"image_save_path_textBrowser")
+ sizePolicy1.setHeightForWidth(self.image_save_path_textBrowser.sizePolicy().hasHeightForWidth())
+ self.image_save_path_textBrowser.setSizePolicy(sizePolicy1)
+ self.image_save_path_textBrowser.setMaximumSize(QSize(16777215, 50))
+ self.image_save_path_textBrowser.setStyleSheet(u"background-color: rgb(255, 255, 255);")
+
+ self.image_save_horizontalLayout.addWidget(self.image_save_path_textBrowser)
+
+ self.image_save_path_button = QPushButton(self.gridWidget)
+ self.image_save_path_button.setObjectName(u"image_save_path_button")
+ sizePolicy1.setHeightForWidth(self.image_save_path_button.sizePolicy().hasHeightForWidth())
+ self.image_save_path_button.setSizePolicy(sizePolicy1)
+ self.image_save_path_button.setMaximumSize(QSize(50, 50))
+ self.image_save_path_button.setFont(font4)
+ self.image_save_path_button.setStyleSheet(u"background-color:rgb(27,49,70);\n"
+"color: #ffffff;")
+
+ self.image_save_horizontalLayout.addWidget(self.image_save_path_button)
+
+
+ self.etc_verticalLayout.addLayout(self.image_save_horizontalLayout)
+
+ self.vis_limit_horizontalLayout_2 = QHBoxLayout()
+ self.vis_limit_horizontalLayout_2.setSpacing(6)
+ self.vis_limit_horizontalLayout_2.setObjectName(u"vis_limit_horizontalLayout_2")
+ self.vis_limit_label_2 = QLabel(self.gridWidget)
+ self.vis_limit_label_2.setObjectName(u"vis_limit_label_2")
+ sizePolicy3.setHeightForWidth(self.vis_limit_label_2.sizePolicy().hasHeightForWidth())
+ self.vis_limit_label_2.setSizePolicy(sizePolicy3)
+ self.vis_limit_label_2.setFont(font3)
+ self.vis_limit_label_2.setStyleSheet(u"background-color:rgb(27,49,70);\n"
+"color: #ffffff;")
+
+ self.vis_limit_horizontalLayout_2.addWidget(self.vis_limit_label_2)
+
+ self.image_size_comboBox = QComboBox(self.gridWidget)
+ self.image_size_comboBox.addItem("")
+ self.image_size_comboBox.addItem("")
+ self.image_size_comboBox.addItem("")
+ self.image_size_comboBox.setObjectName(u"image_size_comboBox")
+ sizePolicy5 = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Minimum)
+ sizePolicy5.setHorizontalStretch(0)
+ sizePolicy5.setVerticalStretch(0)
+ sizePolicy5.setHeightForWidth(self.image_size_comboBox.sizePolicy().hasHeightForWidth())
+ self.image_size_comboBox.setSizePolicy(sizePolicy5)
+ self.image_size_comboBox.setStyleSheet(u"background-color: rgb(255, 255, 255);")
+
+ self.vis_limit_horizontalLayout_2.addWidget(self.image_size_comboBox)
+
+
+ self.etc_verticalLayout.addLayout(self.vis_limit_horizontalLayout_2)
+
+ self.vis_limit_horizontalLayout = QHBoxLayout()
+ self.vis_limit_horizontalLayout.setSpacing(6)
+ self.vis_limit_horizontalLayout.setObjectName(u"vis_limit_horizontalLayout")
+ self.vis_limit_label = QLabel(self.gridWidget)
+ self.vis_limit_label.setObjectName(u"vis_limit_label")
+ sizePolicy3.setHeightForWidth(self.vis_limit_label.sizePolicy().hasHeightForWidth())
+ self.vis_limit_label.setSizePolicy(sizePolicy3)
+ self.vis_limit_label.setFont(font3)
+ self.vis_limit_label.setStyleSheet(u"background-color:rgb(27,49,70);\n"
+"color: #ffffff;")
+
+ self.vis_limit_horizontalLayout.addWidget(self.vis_limit_label)
+
+ self.vis_limit_spinBox = QSpinBox(self.gridWidget)
+ self.vis_limit_spinBox.setObjectName(u"vis_limit_spinBox")
+ sizePolicy3.setHeightForWidth(self.vis_limit_spinBox.sizePolicy().hasHeightForWidth())
+ self.vis_limit_spinBox.setSizePolicy(sizePolicy3)
+ self.vis_limit_spinBox.setStyleSheet(u"background-color: rgb(255, 255, 255);")
+ self.vis_limit_spinBox.setMaximum(20000)
+ self.vis_limit_spinBox.setSingleStep(1)
+ self.vis_limit_spinBox.setDisplayIntegerBase(10)
+
+ self.vis_limit_horizontalLayout.addWidget(self.vis_limit_spinBox)
+
+
+ self.etc_verticalLayout.addLayout(self.vis_limit_horizontalLayout)
+
+ self.id_horizontalLayout = QHBoxLayout()
+ self.id_horizontalLayout.setSpacing(6)
+ self.id_horizontalLayout.setObjectName(u"id_horizontalLayout")
+ self.id_label = QLabel(self.gridWidget)
+ self.id_label.setObjectName(u"id_label")
+ sizePolicy3.setHeightForWidth(self.id_label.sizePolicy().hasHeightForWidth())
+ self.id_label.setSizePolicy(sizePolicy3)
+ self.id_label.setFont(font3)
+ self.id_label.setStyleSheet(u"background-color:rgb(27,49,70);\n"
+"color: #ffffff;")
+
+ self.id_horizontalLayout.addWidget(self.id_label)
+
+ self.id_textBrowser = QTextBrowser(self.gridWidget)
+ self.id_textBrowser.setObjectName(u"id_textBrowser")
+ sizePolicy3.setHeightForWidth(self.id_textBrowser.sizePolicy().hasHeightForWidth())
+ self.id_textBrowser.setSizePolicy(sizePolicy3)
+ self.id_textBrowser.setMaximumSize(QSize(195, 39))
+ self.id_textBrowser.setStyleSheet(u"background-color: rgb(255, 255, 255);")
+ self.id_textBrowser.setLineWrapMode(QTextEdit.NoWrap)
+
+ self.id_horizontalLayout.addWidget(self.id_textBrowser)
+
+
+ self.etc_verticalLayout.addLayout(self.id_horizontalLayout)
+
+ self.pw_horizontalLayout = QHBoxLayout()
+ self.pw_horizontalLayout.setSpacing(6)
+ self.pw_horizontalLayout.setObjectName(u"pw_horizontalLayout")
+ self.pw_label = QLabel(self.gridWidget)
+ self.pw_label.setObjectName(u"pw_label")
+ sizePolicy3.setHeightForWidth(self.pw_label.sizePolicy().hasHeightForWidth())
+ self.pw_label.setSizePolicy(sizePolicy3)
+ self.pw_label.setFont(font3)
+ self.pw_label.setStyleSheet(u"background-color:rgb(27,49,70);\n"
+"color: #ffffff;")
+
+ self.pw_horizontalLayout.addWidget(self.pw_label)
+
+ self.current_pw = QLineEdit(self.gridWidget)
+ self.current_pw.setObjectName(u"current_pw")
+ sizePolicy3.setHeightForWidth(self.current_pw.sizePolicy().hasHeightForWidth())
+ self.current_pw.setSizePolicy(sizePolicy3)
+ self.current_pw.setStyleSheet(u"background-color: rgb(255, 255, 255);")
+
+ self.pw_horizontalLayout.addWidget(self.current_pw)
+
+
+ self.etc_verticalLayout.addLayout(self.pw_horizontalLayout)
+
+ self.pw_horizontalLayout_3 = QHBoxLayout()
+ self.pw_horizontalLayout_3.setSpacing(6)
+ self.pw_horizontalLayout_3.setObjectName(u"pw_horizontalLayout_3")
+ self.pw_label_3 = QLabel(self.gridWidget)
+ self.pw_label_3.setObjectName(u"pw_label_3")
+ sizePolicy3.setHeightForWidth(self.pw_label_3.sizePolicy().hasHeightForWidth())
+ self.pw_label_3.setSizePolicy(sizePolicy3)
+ self.pw_label_3.setFont(font3)
+ self.pw_label_3.setStyleSheet(u"background-color:rgb(27,49,70);\n"
+"color: #ffffff;")
+
+ self.pw_horizontalLayout_3.addWidget(self.pw_label_3)
+
+ self.new_pw = QLineEdit(self.gridWidget)
+ self.new_pw.setObjectName(u"new_pw")
+ sizePolicy3.setHeightForWidth(self.new_pw.sizePolicy().hasHeightForWidth())
+ self.new_pw.setSizePolicy(sizePolicy3)
+ self.new_pw.setStyleSheet(u"background-color: rgb(255, 255, 255);")
+
+ self.pw_horizontalLayout_3.addWidget(self.new_pw)
+
+
+ self.etc_verticalLayout.addLayout(self.pw_horizontalLayout_3)
+
+ self.pw_horizontalLayout_4 = QHBoxLayout()
+ self.pw_horizontalLayout_4.setSpacing(6)
+ self.pw_horizontalLayout_4.setObjectName(u"pw_horizontalLayout_4")
+ self.pw_label_4 = QLabel(self.gridWidget)
+ self.pw_label_4.setObjectName(u"pw_label_4")
+ sizePolicy3.setHeightForWidth(self.pw_label_4.sizePolicy().hasHeightForWidth())
+ self.pw_label_4.setSizePolicy(sizePolicy3)
+ self.pw_label_4.setFont(font3)
+ self.pw_label_4.setStyleSheet(u"background-color:rgb(27,49,70);\n"
+"color: #ffffff;")
+
+ self.pw_horizontalLayout_4.addWidget(self.pw_label_4)
+
+ self.new_pw_check = QLineEdit(self.gridWidget)
+ self.new_pw_check.setObjectName(u"new_pw_check")
+ sizePolicy3.setHeightForWidth(self.new_pw_check.sizePolicy().hasHeightForWidth())
+ self.new_pw_check.setSizePolicy(sizePolicy3)
+ self.new_pw_check.setStyleSheet(u"background-color: rgb(255, 255, 255);")
+
+ self.pw_horizontalLayout_4.addWidget(self.new_pw_check)
+
+
+ self.etc_verticalLayout.addLayout(self.pw_horizontalLayout_4)
+
+ self.afd_horizontalLayout = QHBoxLayout()
+ self.afd_horizontalLayout.setSpacing(6)
+ self.afd_horizontalLayout.setObjectName(u"afd_horizontalLayout")
+ self.user_list_label = QLabel(self.gridWidget)
+ self.user_list_label.setObjectName(u"user_list_label")
+ sizePolicy3.setHeightForWidth(self.user_list_label.sizePolicy().hasHeightForWidth())
+ self.user_list_label.setSizePolicy(sizePolicy3)
+ self.user_list_label.setFont(font3)
+ self.user_list_label.setStyleSheet(u"background-color:rgb(27,49,70);\n"
+"color: #ffffff;")
+
+ self.afd_horizontalLayout.addWidget(self.user_list_label)
+
+ self.user_list_button = QPushButton(self.gridWidget)
+ self.user_list_button.setObjectName(u"user_list_button")
+ sizePolicy3.setHeightForWidth(self.user_list_button.sizePolicy().hasHeightForWidth())
+ self.user_list_button.setSizePolicy(sizePolicy3)
+ font5 = QFont()
+ font5.setFamilies([u"Noto Sans KR Medium"])
+ self.user_list_button.setFont(font5)
+ self.user_list_button.setStyleSheet(u"background-color:rgb(255, 255, 255);")
+
+ self.afd_horizontalLayout.addWidget(self.user_list_button)
+
+
+ self.etc_verticalLayout.addLayout(self.afd_horizontalLayout)
+
+ self.buttonBox = QDialogButtonBox(self.gridWidget)
+ self.buttonBox.setObjectName(u"buttonBox")
+ sizePolicy4.setHeightForWidth(self.buttonBox.sizePolicy().hasHeightForWidth())
+ self.buttonBox.setSizePolicy(sizePolicy4)
+ font6 = QFont()
+ font6.setFamilies([u"Noto Sans"])
+ font6.setPointSize(9)
+ self.buttonBox.setFont(font6)
+ self.buttonBox.setStyleSheet(u"background-color:rgb(27,49,70);\n"
+"color: #ffffff;")
+ self.buttonBox.setOrientation(Qt.Horizontal)
+ self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel|QDialogButtonBox.Ok)
+ self.buttonBox.setCenterButtons(False)
+
+ self.etc_verticalLayout.addWidget(self.buttonBox)
+
+
+ self.bottom_horizontalLayout.addLayout(self.etc_verticalLayout)
+
+
+ self.main_verticalLayout.addLayout(self.bottom_horizontalLayout)
+
+
+ self.gridLayout_2.addLayout(self.main_verticalLayout, 0, 0, 1, 1)
+
+
+ self.gridLayout.addWidget(self.gridWidget, 0, 0, 1, 1)
+
+
+ self.retranslateUi(Dialog)
+
+ self.flip_button.setDefault(True)
+ self.image_size_comboBox.setCurrentIndex(0)
+
+
+ QMetaObject.connectSlotsByName(Dialog)
+ # setupUi
+
+ def retranslateUi(self, Dialog):
+ Dialog.setWindowTitle(QCoreApplication.translate("Dialog", u"Setting", None))
+ self.target_setting_label.setText(QCoreApplication.translate("Dialog", u" Front Target Setting", None))
+ self.flip_button.setText("")
+ self.image_label.setText("")
+ self.target_list_label.setText(QCoreApplication.translate("Dialog", u" Target list", None))
+ self.value_label.setText(QCoreApplication.translate("Dialog", u" ext \u03b1 Value", None))
+ self.label.setText("")
+ self.red_checkBox.setText(QCoreApplication.translate("Dialog", u"Red", None))
+ self.green_checkBox.setText(QCoreApplication.translate("Dialog", u"Green", None))
+ self.blue_checkBox.setText(QCoreApplication.translate("Dialog", u"Blue", None))
+ self.label_2.setText("")
+ self.setting_label.setText(QCoreApplication.translate("Dialog", u" Settings", None))
+ self.data_csv_path_label.setText(QCoreApplication.translate("Dialog", u"\ub370\uc774\ud130 \ud30c\uc77c \uacbd\ub85c", None))
+ self.data_csv_path_button.setText(QCoreApplication.translate("Dialog", u"\u21a9", None))
+ self.target_csv_path_label.setText(QCoreApplication.translate("Dialog", u"\ud0c0\uac9f \ud30c\uc77c \uacbd\ub85c", None))
+ self.target_csv_path_button.setText(QCoreApplication.translate("Dialog", u"\u21a9", None))
+ self.image_save_path_label.setText(QCoreApplication.translate("Dialog", u"\uc774\ubbf8\uc9c0 \uc800\uc7a5 \uacbd\ub85c", None))
+ self.image_save_path_button.setText(QCoreApplication.translate("Dialog", u"\u21a9", None))
+ self.vis_limit_label_2.setText(QCoreApplication.translate("Dialog", u"\uc774\ubbf8\uc9c0 \ud06c\uae30 \uc9c0\uc815", None))
+ self.image_size_comboBox.setItemText(0, QCoreApplication.translate("Dialog", u"Original (PNG)", None))
+ self.image_size_comboBox.setItemText(1, QCoreApplication.translate("Dialog", u"Reduce (JPG)", None))
+ self.image_size_comboBox.setItemText(2, QCoreApplication.translate("Dialog", u"Resize to FHD (PNG)", None))
+
+ self.vis_limit_label.setText(QCoreApplication.translate("Dialog", u"\ucd5c\uc800 \uc2dc\uc815 \uc54c\ub9bc \uae30\uc900", None))
+ self.vis_limit_spinBox.setSuffix(QCoreApplication.translate("Dialog", u" m", None))
+ self.vis_limit_spinBox.setPrefix("")
+ self.id_label.setText(QCoreApplication.translate("Dialog", u" ID: ", None))
+ self.pw_label.setText(QCoreApplication.translate("Dialog", u"\ud604\uc7ac \ube44\ubc00\ubc88\ud638", None))
+ self.pw_label_3.setText(QCoreApplication.translate("Dialog", u"\uc0c8 \ube44\ubc00\ubc88\ud638", None))
+ self.pw_label_4.setText(QCoreApplication.translate("Dialog", u"\uc0c8 \ube44\ubc00\ubc88\ud638 \ud655\uc778", None))
+ self.user_list_label.setText(QCoreApplication.translate("Dialog", u"\uc720\uc800 \uacc4\uc815 \uad00\ub9ac", None))
+ self.user_list_button.setText(QCoreApplication.translate("Dialog", u"\uc5f4\uae30", None))
+ # retranslateUi
+
diff --git a/src/resources/admin_menu.ui b/src/resources/admin_menu.ui
new file mode 100644
index 0000000..add2c5f
--- /dev/null
+++ b/src/resources/admin_menu.ui
@@ -0,0 +1,1010 @@
+
+
+ Dialog
+
+
+
+ 0
+ 0
+ 1920
+ 1080
+
+
+
+
+ 0
+ 0
+
+
+
+ Setting
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+ -
+
+
+ background-color:rgb(22,32,42);
+
+
+
-
+
+
-
+
+
-
+
+
-
+
+
+ 0
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ Noto Sans
+ 23
+
+
+
+ background-color:rgb(27,49,70);
+color: #ffffff;
+
+
+ Front Target Setting
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 42
+
+
+
+
+ Noto Sans
+ 15
+
+
+
+ PointingHandCursor
+
+
+ border:0px;
+background-color: #1b3146;
+color: #ffffff;
+
+
+
+
+
+
+ asset/flip_off.pngasset/flip_off.png
+
+
+
+ 40
+ 40
+
+
+
+ true
+
+
+ true
+
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 0
+
+
+
+
+ 16777215
+ 16777215
+
+
+
+
+
+
+
+
+
+
+
+ -
+
+
+ 12
+
+
-
+
+
+ 0
+
+
+ 6
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ Noto Sans
+ 23
+
+
+
+ background-color:rgb(27,49,70);
+color: #ffffff;
+
+
+ Target list
+
+
+
+ -
+
+
+
+ 700
+ 500
+
+
+
+
+
+
+ -
+
+
+ 0
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ Noto Sans
+ 23
+
+
+
+ background-color:rgb(27,49,70);
+color: #ffffff;
+
+
+ ext α Value
+
+
+
+ -
+
+
+ 0
+
+
-
+
+
+ 0
+
+
+
+ -
+
+
+ 0
+
+
+ QLayout::SetMaximumSize
+
+
-
+
+
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ Noto Sans
+ 50
+ false
+
+
+
+
+color: #ffffff;
+
+
+ Red
+
+
+ true
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ Noto Sans
+ 50
+ false
+
+
+
+
+color: #ffffff;
+
+
+ Green
+
+
+ true
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ Noto Sans
+ 50
+ false
+
+
+
+
+color: #ffffff;
+
+
+ Blue
+
+
+ true
+
+
+
+ -
+
+
+
+
+
+
+
+
+
+
+
+
+ -
+
+
+ 3
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ Noto Sans
+ 23
+
+
+
+ background-color:rgb(27,49,70);
+color: #ffffff;
+
+
+ Settings
+
+
+
+ -
+
+
+ 0
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ Noto Sans KR Medium
+ 10
+
+
+
+ background-color:rgb(27,49,70);
+color: #ffffff;
+
+
+ 데이터 파일 경로
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 16777215
+ 50
+
+
+
+ background-color: rgb(255, 255, 255);
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 50
+ 50
+
+
+
+
+ Arial
+ 17
+
+
+
+ background-color:rgb(27,49,70);
+color: #ffffff;
+
+
+ ↩
+
+
+
+
+
+ -
+
+
+ 0
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ Noto Sans KR Medium
+ 10
+
+
+
+ background-color:rgb(27,49,70);
+color: #ffffff;
+
+
+ 타겟 파일 경로
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 16777215
+ 50
+
+
+
+ background-color: rgb(255, 255, 255);
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 50
+ 50
+
+
+
+
+ Arial
+ 17
+
+
+
+ background-color:rgb(27,49,70);
+color: #ffffff;
+
+
+ ↩
+
+
+
+
+
+ -
+
+
+ 0
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ Noto Sans KR Medium
+ 10
+
+
+
+ background-color:rgb(27,49,70);
+color: #ffffff;
+
+
+ 이미지 저장 경로
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 16777215
+ 50
+
+
+
+ background-color: rgb(255, 255, 255);
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 50
+ 50
+
+
+
+
+ Arial
+ 17
+
+
+
+ background-color:rgb(27,49,70);
+color: #ffffff;
+
+
+ ↩
+
+
+
+
+
+ -
+
+
+ 6
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ Noto Sans KR Medium
+ 10
+
+
+
+ background-color:rgb(27,49,70);
+color: #ffffff;
+
+
+ 이미지 크기 지정
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ background-color: rgb(255, 255, 255);
+
+
+ 0
+
+
-
+
+ Original (PNG)
+
+
+ -
+
+ Reduce (JPG)
+
+
+ -
+
+ Resize to FHD (PNG)
+
+
+
+
+
+
+ -
+
+
+ 6
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ Noto Sans KR Medium
+ 10
+
+
+
+ background-color:rgb(27,49,70);
+color: #ffffff;
+
+
+ 최저 시정 알림 기준
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ background-color: rgb(255, 255, 255);
+
+
+ m
+
+
+
+
+
+ 20000
+
+
+ 1
+
+
+ 10
+
+
+
+
+
+ -
+
+
+ 6
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ Noto Sans KR Medium
+ 10
+
+
+
+ background-color:rgb(27,49,70);
+color: #ffffff;
+
+
+ ID:
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 195
+ 39
+
+
+
+ background-color: rgb(255, 255, 255);
+
+
+ QTextEdit::NoWrap
+
+
+
+
+
+ -
+
+
+ 6
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ Noto Sans KR Medium
+ 10
+
+
+
+ background-color:rgb(27,49,70);
+color: #ffffff;
+
+
+ 현재 비밀번호
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ background-color: rgb(255, 255, 255);
+
+
+
+
+
+ -
+
+
+ 6
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ Noto Sans KR Medium
+ 10
+
+
+
+ background-color:rgb(27,49,70);
+color: #ffffff;
+
+
+ 새 비밀번호
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ background-color: rgb(255, 255, 255);
+
+
+
+
+
+ -
+
+
+ 6
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ Noto Sans KR Medium
+ 10
+
+
+
+ background-color:rgb(27,49,70);
+color: #ffffff;
+
+
+ 새 비밀번호 확인
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ background-color: rgb(255, 255, 255);
+
+
+
+
+
+ -
+
+
+ 6
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ Noto Sans KR Medium
+ 10
+
+
+
+ background-color:rgb(27,49,70);
+color: #ffffff;
+
+
+ 유저 계정 관리
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ Noto Sans KR Medium
+
+
+
+ background-color:rgb(255, 255, 255);
+
+
+ 열기
+
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ Noto Sans
+ 9
+
+
+
+ background-color:rgb(27,49,70);
+color: #ffffff;
+
+
+ Qt::Horizontal
+
+
+ QDialogButtonBox::Cancel|QDialogButtonBox::Ok
+
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/resources/asset/alert.png b/src/resources/asset/alert.png
new file mode 100644
index 0000000..bea8ca9
Binary files /dev/null and b/src/resources/asset/alert.png differ
diff --git a/src/resources/asset/azimuth_off.png b/src/resources/asset/azimuth_off.png
new file mode 100644
index 0000000..3088db3
Binary files /dev/null and b/src/resources/asset/azimuth_off.png differ
diff --git a/src/resources/asset/azimuth_on.png b/src/resources/asset/azimuth_on.png
new file mode 100644
index 0000000..05f3f91
Binary files /dev/null and b/src/resources/asset/azimuth_on.png differ
diff --git a/src/resources/asset/f_logo.png b/src/resources/asset/f_logo.png
new file mode 100644
index 0000000..f1a02d9
Binary files /dev/null and b/src/resources/asset/f_logo.png differ
diff --git a/src/resources/asset/f_logo_2.png b/src/resources/asset/f_logo_2.png
new file mode 100644
index 0000000..369a90e
Binary files /dev/null and b/src/resources/asset/f_logo_2.png differ
diff --git a/src/resources/asset/log.png b/src/resources/asset/log.png
new file mode 100644
index 0000000..31f95b6
Binary files /dev/null and b/src/resources/asset/log.png differ
diff --git a/src/resources/asset/log1.png b/src/resources/asset/log1.png
new file mode 100644
index 0000000..e3f8733
Binary files /dev/null and b/src/resources/asset/log1.png differ
diff --git a/src/resources/asset/log_on.png b/src/resources/asset/log_on.png
new file mode 100644
index 0000000..e2a8351
Binary files /dev/null and b/src/resources/asset/log_on.png differ
diff --git a/src/resources/asset/logo2.png b/src/resources/asset/logo2.png
new file mode 100644
index 0000000..53af9ac
Binary files /dev/null and b/src/resources/asset/logo2.png differ
diff --git a/src/resources/asset/polar.png b/src/resources/asset/polar.png
new file mode 100644
index 0000000..ef675fe
Binary files /dev/null and b/src/resources/asset/polar.png differ
diff --git a/src/resources/asset/pre_vis.png b/src/resources/asset/pre_vis.png
new file mode 100644
index 0000000..502e033
Binary files /dev/null and b/src/resources/asset/pre_vis.png differ
diff --git a/src/resources/asset/pre_vis_1.png b/src/resources/asset/pre_vis_1.png
new file mode 100644
index 0000000..c25686d
Binary files /dev/null and b/src/resources/asset/pre_vis_1.png differ
diff --git a/src/resources/asset/sijung_logo.png b/src/resources/asset/sijung_logo.png
new file mode 100644
index 0000000..eb9079f
Binary files /dev/null and b/src/resources/asset/sijung_logo.png differ
diff --git a/src/resources/auto_file_delete.py b/src/resources/auto_file_delete.py
new file mode 100644
index 0000000..bfd08e3
--- /dev/null
+++ b/src/resources/auto_file_delete.py
@@ -0,0 +1,97 @@
+# -*- coding: utf-8 -*-
+
+################################################################################
+## Form generated from reading UI file 'auto_file_delete.ui'
+##
+## Created by: Qt User Interface Compiler version 6.3.0
+##
+## 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, QCalendarWidget, QPushButton, QSizePolicy,
+ QVBoxLayout, QWidget)
+
+class Ui_Form(object):
+ def setupUi(self, Form):
+ if not Form.objectName():
+ Form.setObjectName(u"Form")
+ Form.setWindowModality(Qt.WindowModal)
+ Form.resize(298, 282)
+ font = QFont()
+ font.setFamilies([u"KoPubWorld\ub3cb\uc6c0\uccb4 Medium"])
+ font.setPointSize(10)
+ font.setBold(False)
+ font.setItalic(False)
+ Form.setFont(font)
+ Form.setCursor(QCursor(Qt.ArrowCursor))
+ Form.setStyleSheet(u"")
+ self.verticalLayout = QVBoxLayout(Form)
+ self.verticalLayout.setObjectName(u"verticalLayout")
+ self.verticalLayout_2 = QVBoxLayout()
+ self.verticalLayout_2.setObjectName(u"verticalLayout_2")
+ self.calendarWidget = QCalendarWidget(Form)
+ self.calendarWidget.setObjectName(u"calendarWidget")
+ sizePolicy = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.calendarWidget.sizePolicy().hasHeightForWidth())
+ self.calendarWidget.setSizePolicy(sizePolicy)
+ font1 = QFont()
+ font1.setFamilies([u"Noto Sans"])
+ self.calendarWidget.setFont(font1)
+ self.calendarWidget.setStyleSheet(u"background-color: rgb(255, 255, 255);\n"
+"color: rgb(0, 0, 0);")
+ self.calendarWidget.setLocale(QLocale(QLocale.Korean, QLocale.SouthKorea))
+ self.calendarWidget.setFirstDayOfWeek(Qt.Sunday)
+ self.calendarWidget.setGridVisible(True)
+
+ self.verticalLayout_2.addWidget(self.calendarWidget)
+
+ self.exit_pushButton = QPushButton(Form)
+ self.exit_pushButton.setObjectName(u"exit_pushButton")
+ sizePolicy.setHeightForWidth(self.exit_pushButton.sizePolicy().hasHeightForWidth())
+ self.exit_pushButton.setSizePolicy(sizePolicy)
+ font2 = QFont()
+ font2.setFamilies([u"Noto Sans"])
+ font2.setPointSize(10)
+ font2.setBold(False)
+ font2.setItalic(False)
+ self.exit_pushButton.setFont(font2)
+ self.exit_pushButton.setCursor(QCursor(Qt.PointingHandCursor))
+ self.exit_pushButton.setStyleSheet(u"")
+
+ self.verticalLayout_2.addWidget(self.exit_pushButton)
+
+
+ self.verticalLayout.addLayout(self.verticalLayout_2)
+
+
+ self.retranslateUi(Form)
+
+ QMetaObject.connectSlotsByName(Form)
+ # setupUi
+
+ def retranslateUi(self, Form):
+ Form.setWindowTitle(QCoreApplication.translate("Form", u"File delete", None))
+#if QT_CONFIG(whatsthis)
+ Form.setWhatsThis(QCoreApplication.translate("Form", u"This is this.", None))
+#endif // QT_CONFIG(whatsthis)
+#if QT_CONFIG(whatsthis)
+ self.calendarWidget.setWhatsThis(QCoreApplication.translate("Form", u"Select a date and erase the data before that date", None))
+#endif // QT_CONFIG(whatsthis)
+#if QT_CONFIG(whatsthis)
+ self.exit_pushButton.setWhatsThis(QCoreApplication.translate("Form", u"Exit this window", None))
+#endif // QT_CONFIG(whatsthis)
+ self.exit_pushButton.setText(QCoreApplication.translate("Form", u"Close", None))
+#if QT_CONFIG(shortcut)
+ self.exit_pushButton.setShortcut(QCoreApplication.translate("Form", u"Ctrl+W", None))
+#endif // QT_CONFIG(shortcut)
+ # retranslateUi
+
diff --git a/src/resources/auto_file_delete.ui b/src/resources/auto_file_delete.ui
new file mode 100644
index 0000000..268f40c
--- /dev/null
+++ b/src/resources/auto_file_delete.ui
@@ -0,0 +1,111 @@
+
+
+ Form
+
+
+ Qt::WindowModal
+
+
+
+ 0
+ 0
+ 298
+ 282
+
+
+
+
+ KoPubWorld돋움체 Medium
+ 10
+ 50
+ false
+ false
+
+
+
+ ArrowCursor
+
+
+ File delete
+
+
+ This is this.
+
+
+
+
+
+ -
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ Noto Sans
+
+
+
+ Select a date and erase the data before that date
+
+
+ background-color: rgb(255, 255, 255);
+color: rgb(0, 0, 0);
+
+
+
+
+
+ Qt::Sunday
+
+
+ true
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ Noto Sans
+ 10
+ 50
+ false
+ false
+
+
+
+ PointingHandCursor
+
+
+ Exit this window
+
+
+
+
+
+ Close
+
+
+ Ctrl+W
+
+
+
+
+
+
+
+
+
+
diff --git a/src/resources/graph_range_window.ui b/src/resources/graph_range_window.ui
new file mode 100644
index 0000000..060988d
--- /dev/null
+++ b/src/resources/graph_range_window.ui
@@ -0,0 +1,80 @@
+
+
+ Dialog
+
+
+
+ 0
+ 0
+ 260
+ 139
+
+
+
+ Dialog
+
+
+
+
+ 50
+ 100
+ 156
+ 23
+
+
+
+
+ Noto Sans
+
+
+
+ QDialogButtonBox::Cancel|QDialogButtonBox::Ok
+
+
+
+
+
+ 20
+ 20
+ 121
+ 16
+
+
+
+
+ 0
+ 0
+
+
+
+
+ Noto Sans
+ 8
+
+
+
+ Graph Time Range
+
+
+
+
+
+ 20
+ 40
+ 221
+ 31
+
+
+
+
+ Noto Sans
+
+
+
+ ex) 24 = Visibility values for 24 hours
+
+
+
+
+
+
diff --git a/src/resources/log_decrypt.py b/src/resources/log_decrypt.py
new file mode 100644
index 0000000..b3b8290
--- /dev/null
+++ b/src/resources/log_decrypt.py
@@ -0,0 +1,50 @@
+# -*- coding: utf-8 -*-
+
+################################################################################
+## Form generated from reading UI file 'log_decrypt.ui'
+##
+## Created by: Qt User Interface Compiler version 6.3.0
+##
+## 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, QDialog, QGridLayout, QPushButton,
+ QSizePolicy, QTextBrowser, QWidget)
+
+class Ui_Dialog(object):
+ def setupUi(self, Dialog):
+ if not Dialog.objectName():
+ Dialog.setObjectName(u"Dialog")
+ Dialog.setEnabled(True)
+ Dialog.resize(417, 634)
+ Dialog.setStyleSheet(u"")
+ self.gridLayout = QGridLayout(Dialog)
+ self.gridLayout.setObjectName(u"gridLayout")
+ self.pushButton = QPushButton(Dialog)
+ self.pushButton.setObjectName(u"pushButton")
+
+ self.gridLayout.addWidget(self.pushButton, 0, 0, 1, 1)
+
+ self.textBrowser = QTextBrowser(Dialog)
+ self.textBrowser.setObjectName(u"textBrowser")
+
+ self.gridLayout.addWidget(self.textBrowser, 1, 0, 1, 1)
+
+
+ self.retranslateUi(Dialog)
+
+ QMetaObject.connectSlotsByName(Dialog)
+ # setupUi
+
+ def retranslateUi(self, Dialog):
+ Dialog.setWindowTitle(QCoreApplication.translate("Dialog", u"Log Decrypt", None))
+ self.pushButton.setText(QCoreApplication.translate("Dialog", u"OPEN", None))
+ # retranslateUi
+
diff --git a/src/resources/log_decrypt.ui b/src/resources/log_decrypt.ui
new file mode 100644
index 0000000..c4470ce
--- /dev/null
+++ b/src/resources/log_decrypt.ui
@@ -0,0 +1,37 @@
+
+
+ Dialog
+
+
+ true
+
+
+
+ 0
+ 0
+ 417
+ 634
+
+
+
+ Log Decrypt
+
+
+
+
+
+ -
+
+
+ OPEN
+
+
+
+ -
+
+
+
+
+
+
+
diff --git a/src/resources/login_window.py b/src/resources/login_window.py
new file mode 100644
index 0000000..5740ad2
--- /dev/null
+++ b/src/resources/login_window.py
@@ -0,0 +1,119 @@
+# -*- coding: utf-8 -*-
+
+################################################################################
+## Form generated from reading UI file 'login_window.ui'
+##
+## Created by: Qt User Interface Compiler version 6.3.0
+##
+## 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, QDialog, QFrame, QGridLayout,
+ QLabel, QLineEdit, QPushButton, QSizePolicy,
+ QWidget)
+
+class Ui_Dialog(object):
+ def setupUi(self, Dialog):
+ if not Dialog.objectName():
+ Dialog.setObjectName(u"Dialog")
+ Dialog.resize(290, 300)
+ Dialog.setStyleSheet(u"background-color:rgb(22,32,42);")
+ self.gridLayout = QGridLayout(Dialog)
+ self.gridLayout.setObjectName(u"gridLayout")
+ self.gridWidget = QWidget(Dialog)
+ self.gridWidget.setObjectName(u"gridWidget")
+ font = QFont()
+ font.setFamilies([u"Noto Sans"])
+ self.gridWidget.setFont(font)
+ self.gridWidget.setStyleSheet(u"background-color:rgb(27,49,70);")
+ self.gridLayout_2 = QGridLayout(self.gridWidget)
+ self.gridLayout_2.setObjectName(u"gridLayout_2")
+ self.id_lineEdit = QLineEdit(self.gridWidget)
+ self.id_lineEdit.setObjectName(u"id_lineEdit")
+ self.id_lineEdit.setFont(font)
+ self.id_lineEdit.setStyleSheet(u"background-color: #ffffff;")
+
+ self.gridLayout_2.addWidget(self.id_lineEdit, 2, 0, 1, 1)
+
+ self.alert_label = QLabel(self.gridWidget)
+ self.alert_label.setObjectName(u"alert_label")
+ self.alert_label.setEnabled(True)
+ sizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Maximum)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.alert_label.sizePolicy().hasHeightForWidth())
+ self.alert_label.setSizePolicy(sizePolicy)
+ font1 = QFont()
+ font1.setFamilies([u"Noto Sans KR Medium"])
+ font1.setPointSize(10)
+ self.alert_label.setFont(font1)
+ self.alert_label.setStyleSheet(u"color:#ff0000;")
+ self.alert_label.setFrameShadow(QFrame.Plain)
+ self.alert_label.setTextFormat(Qt.AutoText)
+ self.alert_label.setAlignment(Qt.AlignCenter)
+
+ self.gridLayout_2.addWidget(self.alert_label, 5, 0, 1, 1)
+
+ self.pw_lineEdit = QLineEdit(self.gridWidget)
+ self.pw_lineEdit.setObjectName(u"pw_lineEdit")
+ self.pw_lineEdit.setFont(font)
+ self.pw_lineEdit.setStyleSheet(u"background-color: #ffffff;")
+ self.pw_lineEdit.setEchoMode(QLineEdit.Password)
+
+ self.gridLayout_2.addWidget(self.pw_lineEdit, 3, 0, 1, 1)
+
+ self.sijunglogo = QPushButton(self.gridWidget)
+ self.sijunglogo.setObjectName(u"sijunglogo")
+ sizePolicy1 = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
+ sizePolicy1.setHorizontalStretch(0)
+ sizePolicy1.setVerticalStretch(0)
+ sizePolicy1.setHeightForWidth(self.sijunglogo.sizePolicy().hasHeightForWidth())
+ self.sijunglogo.setSizePolicy(sizePolicy1)
+ icon = QIcon()
+ icon.addFile(u"asset/f_logo.png", QSize(), QIcon.Normal, QIcon.Off)
+ self.sijunglogo.setIcon(icon)
+ self.sijunglogo.setIconSize(QSize(170, 90))
+ self.sijunglogo.setCheckable(False)
+ self.sijunglogo.setAutoDefault(False)
+ self.sijunglogo.setFlat(True)
+
+ self.gridLayout_2.addWidget(self.sijunglogo, 0, 0, 1, 1)
+
+
+ self.gridLayout.addWidget(self.gridWidget, 0, 0, 1, 1)
+
+ self.login_button = QPushButton(Dialog)
+ self.login_button.setObjectName(u"login_button")
+ font2 = QFont()
+ font2.setFamilies([u"Noto Sans"])
+ font2.setBold(True)
+ self.login_button.setFont(font2)
+ self.login_button.setStyleSheet(u"background-color:rgb(27,49,70);color:#ffffff;")
+
+ self.gridLayout.addWidget(self.login_button, 1, 0, 1, 1)
+
+
+ self.retranslateUi(Dialog)
+
+ self.sijunglogo.setDefault(False)
+
+
+ QMetaObject.connectSlotsByName(Dialog)
+ # setupUi
+
+ def retranslateUi(self, Dialog):
+ Dialog.setWindowTitle(QCoreApplication.translate("Dialog", u"Login", None))
+ self.id_lineEdit.setPlaceholderText(QCoreApplication.translate("Dialog", u"ID", None))
+ self.alert_label.setText("")
+ self.pw_lineEdit.setPlaceholderText(QCoreApplication.translate("Dialog", u"Password", None))
+ self.sijunglogo.setText("")
+ self.login_button.setText(QCoreApplication.translate("Dialog", u"Login", None))
+ # retranslateUi
+
diff --git a/src/resources/login_window.ui b/src/resources/login_window.ui
new file mode 100644
index 0000000..7b91b00
--- /dev/null
+++ b/src/resources/login_window.ui
@@ -0,0 +1,157 @@
+
+
+ Dialog
+
+
+
+ 0
+ 0
+ 290
+ 300
+
+
+
+ Login
+
+
+ background-color:rgb(22,32,42);
+
+
+ -
+
+
+
+ Noto Sans
+
+
+
+ background-color:rgb(27,49,70);
+
+
+
-
+
+
+
+ Noto Sans
+
+
+
+ background-color: #ffffff;
+
+
+ ID
+
+
+
+ -
+
+
+ true
+
+
+
+ 0
+ 0
+
+
+
+
+ Noto Sans KR Medium
+ 10
+
+
+
+ color:#ff0000;
+
+
+ QFrame::Plain
+
+
+
+
+
+ Qt::AutoText
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ Noto Sans
+
+
+
+ background-color: #ffffff;
+
+
+ QLineEdit::Password
+
+
+ Password
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+
+
+
+ asset/f_logo.pngasset/f_logo.png
+
+
+
+ 170
+ 90
+
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ true
+
+
+
+
+
+
+ -
+
+
+
+ Noto Sans
+ 75
+ true
+
+
+
+ background-color:rgb(27,49,70);color:#ffffff;
+
+
+ Login
+
+
+
+
+
+
+
+
diff --git a/src/resources/main_window.py b/src/resources/main_window.py
new file mode 100644
index 0000000..73f91ae
--- /dev/null
+++ b/src/resources/main_window.py
@@ -0,0 +1,775 @@
+# -*- coding: utf-8 -*-
+
+################################################################################
+## Form generated from reading UI file 'main_window.ui'
+##
+## Created by: Qt User Interface Compiler version 6.3.0
+##
+## 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 (QAction, QBrush, QColor, QConicalGradient,
+ QCursor, QFont, QFontDatabase, QGradient,
+ QIcon, QImage, QKeySequence, QLinearGradient,
+ QPainter, QPalette, QPixmap, QRadialGradient,
+ QTransform)
+from PySide6.QtWidgets import (QApplication, QFrame, QGridLayout, QHBoxLayout,
+ QLabel, QLayout, QMainWindow, QPushButton,
+ QSizePolicy, QVBoxLayout, QWidget)
+
+class Ui_MainWindow(object):
+ def setupUi(self, MainWindow):
+ if not MainWindow.objectName():
+ MainWindow.setObjectName(u"MainWindow")
+ MainWindow.setEnabled(True)
+ MainWindow.resize(1087, 816)
+ sizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(MainWindow.sizePolicy().hasHeightForWidth())
+ MainWindow.setSizePolicy(sizePolicy)
+ MainWindow.setMinimumSize(QSize(400, 300))
+ font = QFont()
+ font.setPointSize(9)
+ font.setBold(False)
+ font.setItalic(False)
+ MainWindow.setFont(font)
+ MainWindow.setMouseTracking(False)
+ icon = QIcon()
+ icon.addFile(u"asset/logo.png", QSize(), QIcon.Normal, QIcon.Off)
+ MainWindow.setWindowIcon(icon)
+ MainWindow.setStyleSheet(u"background-color:rgb(22,32,42);\n"
+"color: rgb(255, 255, 255);")
+ self.actionExit = QAction(MainWindow)
+ self.actionExit.setObjectName(u"actionExit")
+ self.actionsd = QAction(MainWindow)
+ self.actionsd.setObjectName(u"actionsd")
+ self.actionkm = QAction(MainWindow)
+ self.actionkm.setObjectName(u"actionkm")
+ self.actionkm.setCheckable(True)
+ self.actionkm.setEnabled(True)
+ self.actionmi = QAction(MainWindow)
+ self.actionmi.setObjectName(u"actionmi")
+ self.actionmi.setCheckable(True)
+ self.actionmi.setEnabled(True)
+ self.actionInference = QAction(MainWindow)
+ self.actionInference.setObjectName(u"actionInference")
+ self.actionInference.setCheckable(True)
+ self.actionInference.setChecked(False)
+ self.actionEdit_Target = QAction(MainWindow)
+ self.actionEdit_Target.setObjectName(u"actionEdit_Target")
+ self.actionEdit_Target.setCheckable(False)
+ self.actionEdit_Camera = QAction(MainWindow)
+ self.actionEdit_Camera.setObjectName(u"actionEdit_Camera")
+ self.actionEdit_Camera.setEnabled(True)
+ self.actionAbout = QAction(MainWindow)
+ self.actionAbout.setObjectName(u"actionAbout")
+ self.actionConfiguration = QAction(MainWindow)
+ self.actionConfiguration.setObjectName(u"actionConfiguration")
+ self.centralwidget = QWidget(MainWindow)
+ self.centralwidget.setObjectName(u"centralwidget")
+ self.centralwidget.setMaximumSize(QSize(16777215, 16777215))
+ self.centralwidget.setMouseTracking(False)
+ self.centralwidget.setStyleSheet(u"")
+ self.gridLayout = QGridLayout(self.centralwidget)
+ self.gridLayout.setSpacing(0)
+ self.gridLayout.setObjectName(u"gridLayout")
+ self.gridLayout.setContentsMargins(0, 0, 0, 0)
+ self.verticalLayout = QVBoxLayout()
+ self.verticalLayout.setSpacing(0)
+ self.verticalLayout.setObjectName(u"verticalLayout")
+ self.verticalLayout.setContentsMargins(0, -1, 0, -1)
+ self.monitoring_horizontalLayout = QHBoxLayout()
+ self.monitoring_horizontalLayout.setSpacing(0)
+ self.monitoring_horizontalLayout.setObjectName(u"monitoring_horizontalLayout")
+ self.thumbnail_info_label_2 = QLabel(self.centralwidget)
+ self.thumbnail_info_label_2.setObjectName(u"thumbnail_info_label_2")
+ sizePolicy1 = QSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum)
+ sizePolicy1.setHorizontalStretch(0)
+ sizePolicy1.setVerticalStretch(0)
+ sizePolicy1.setHeightForWidth(self.thumbnail_info_label_2.sizePolicy().hasHeightForWidth())
+ self.thumbnail_info_label_2.setSizePolicy(sizePolicy1)
+ self.thumbnail_info_label_2.setMinimumSize(QSize(0, 50))
+ font1 = QFont()
+ font1.setFamilies([u"Noto Sans"])
+ font1.setPointSize(30)
+ self.thumbnail_info_label_2.setFont(font1)
+ self.thumbnail_info_label_2.setStyleSheet(u"background-color:rgb(27,49,70);\n"
+"color: rgb(255, 0, 0);")
+
+ self.monitoring_horizontalLayout.addWidget(self.thumbnail_info_label_2)
+
+ self.logo = QPushButton(self.centralwidget)
+ self.logo.setObjectName(u"logo")
+ sizePolicy1.setHeightForWidth(self.logo.sizePolicy().hasHeightForWidth())
+ self.logo.setSizePolicy(sizePolicy1)
+ self.logo.setMinimumSize(QSize(0, 50))
+ self.logo.setStyleSheet(u"border:0px;\n"
+"background-color: #1b3146;")
+ icon1 = QIcon()
+ icon1.addFile(u"asset/f_logo.png", QSize(), QIcon.Normal, QIcon.Off)
+ self.logo.setIcon(icon1)
+ self.logo.setIconSize(QSize(295, 50))
+ self.logo.setAutoRepeatDelay(300)
+ self.logo.setAutoDefault(True)
+ self.logo.setFlat(True)
+
+ self.monitoring_horizontalLayout.addWidget(self.logo)
+
+ self.thumbnail_info_label = QLabel(self.centralwidget)
+ self.thumbnail_info_label.setObjectName(u"thumbnail_info_label")
+ sizePolicy2 = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Maximum)
+ sizePolicy2.setHorizontalStretch(0)
+ sizePolicy2.setVerticalStretch(0)
+ sizePolicy2.setHeightForWidth(self.thumbnail_info_label.sizePolicy().hasHeightForWidth())
+ self.thumbnail_info_label.setSizePolicy(sizePolicy2)
+ self.thumbnail_info_label.setMinimumSize(QSize(0, 50))
+ self.thumbnail_info_label.setFont(font1)
+ self.thumbnail_info_label.setStyleSheet(u"background-color:rgb(27,49,70);\n"
+"color: rgb(255, 0, 0);")
+
+ self.monitoring_horizontalLayout.addWidget(self.thumbnail_info_label)
+
+ self.maxfev_alert = QPushButton(self.centralwidget)
+ self.maxfev_alert.setObjectName(u"maxfev_alert")
+ sizePolicy1.setHeightForWidth(self.maxfev_alert.sizePolicy().hasHeightForWidth())
+ self.maxfev_alert.setSizePolicy(sizePolicy1)
+ self.maxfev_alert.setMinimumSize(QSize(0, 50))
+ self.maxfev_alert.setStyleSheet(u"border:0px;\n"
+"background-color: #1b3146;")
+ icon2 = QIcon()
+ icon2.addFile(u"asset/alert.png", QSize(), QIcon.Normal, QIcon.Off)
+ self.maxfev_alert.setIcon(icon2)
+ self.maxfev_alert.setIconSize(QSize(30, 30))
+ self.maxfev_alert.setAutoDefault(True)
+ self.maxfev_alert.setFlat(True)
+
+ self.monitoring_horizontalLayout.addWidget(self.maxfev_alert)
+
+ self.blank_label_2 = QLabel(self.centralwidget)
+ self.blank_label_2.setObjectName(u"blank_label_2")
+ sizePolicy1.setHeightForWidth(self.blank_label_2.sizePolicy().hasHeightForWidth())
+ self.blank_label_2.setSizePolicy(sizePolicy1)
+ self.blank_label_2.setMinimumSize(QSize(16, 50))
+ self.blank_label_2.setStyleSheet(u"border:0px;\n"
+"background-color: #1b3146;")
+
+ self.monitoring_horizontalLayout.addWidget(self.blank_label_2)
+
+ self.alert = QPushButton(self.centralwidget)
+ self.alert.setObjectName(u"alert")
+ sizePolicy1.setHeightForWidth(self.alert.sizePolicy().hasHeightForWidth())
+ self.alert.setSizePolicy(sizePolicy1)
+ self.alert.setMinimumSize(QSize(0, 50))
+ self.alert.setStyleSheet(u"border:0px;\n"
+"background-color: #1b3146;")
+ icon3 = QIcon()
+ icon3.addFile(u"asset/green.png", QSize(), QIcon.Normal, QIcon.Off)
+ self.alert.setIcon(icon3)
+ self.alert.setIconSize(QSize(30, 30))
+ self.alert.setAutoDefault(True)
+ self.alert.setFlat(True)
+
+ self.monitoring_horizontalLayout.addWidget(self.alert)
+
+ self.blank_label_3 = QLabel(self.centralwidget)
+ self.blank_label_3.setObjectName(u"blank_label_3")
+ sizePolicy1.setHeightForWidth(self.blank_label_3.sizePolicy().hasHeightForWidth())
+ self.blank_label_3.setSizePolicy(sizePolicy1)
+ self.blank_label_3.setMinimumSize(QSize(16, 50))
+ self.blank_label_3.setStyleSheet(u"border:0px;\n"
+"background-color: #1b3146;")
+
+ self.monitoring_horizontalLayout.addWidget(self.blank_label_3)
+
+ self.log_view = QPushButton(self.centralwidget)
+ self.log_view.setObjectName(u"log_view")
+ sizePolicy1.setHeightForWidth(self.log_view.sizePolicy().hasHeightForWidth())
+ self.log_view.setSizePolicy(sizePolicy1)
+ self.log_view.setMinimumSize(QSize(0, 50))
+ self.log_view.setCursor(QCursor(Qt.OpenHandCursor))
+ self.log_view.setStyleSheet(u"border:0px;\n"
+"background-color: #1b3146;")
+ icon4 = QIcon()
+ icon4.addFile(u"asset/log.png", QSize(), QIcon.Normal, QIcon.Off)
+ self.log_view.setIcon(icon4)
+ self.log_view.setIconSize(QSize(40, 40))
+ self.log_view.setAutoDefault(True)
+ self.log_view.setFlat(True)
+
+ self.monitoring_horizontalLayout.addWidget(self.log_view)
+
+ self.blank_label = QLabel(self.centralwidget)
+ self.blank_label.setObjectName(u"blank_label")
+ sizePolicy1.setHeightForWidth(self.blank_label.sizePolicy().hasHeightForWidth())
+ self.blank_label.setSizePolicy(sizePolicy1)
+ self.blank_label.setMinimumSize(QSize(16, 50))
+ self.blank_label.setStyleSheet(u"border:0px;\n"
+"background-color: #1b3146;")
+
+ self.monitoring_horizontalLayout.addWidget(self.blank_label)
+
+ self.setting_button = QPushButton(self.centralwidget)
+ self.setting_button.setObjectName(u"setting_button")
+ self.setting_button.setEnabled(True)
+ sizePolicy1.setHeightForWidth(self.setting_button.sizePolicy().hasHeightForWidth())
+ self.setting_button.setSizePolicy(sizePolicy1)
+ self.setting_button.setMinimumSize(QSize(0, 50))
+ self.setting_button.setCursor(QCursor(Qt.OpenHandCursor))
+ self.setting_button.setStyleSheet(u"border:0px;\n"
+"background-color: #1b3146;")
+ icon5 = QIcon()
+ icon5.addFile(u"asset/settings.png", QSize(), QIcon.Normal, QIcon.Off)
+ self.setting_button.setIcon(icon5)
+ self.setting_button.setIconSize(QSize(40, 40))
+ self.setting_button.setAutoDefault(True)
+ self.setting_button.setFlat(True)
+
+ self.monitoring_horizontalLayout.addWidget(self.setting_button)
+
+
+ self.verticalLayout.addLayout(self.monitoring_horizontalLayout)
+
+ self.horizontalLayout_3 = QHBoxLayout()
+ self.horizontalLayout_3.setObjectName(u"horizontalLayout_3")
+ self.front_label = QLabel(self.centralwidget)
+ self.front_label.setObjectName(u"front_label")
+ sizePolicy3 = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Maximum)
+ sizePolicy3.setHorizontalStretch(0)
+ sizePolicy3.setVerticalStretch(0)
+ sizePolicy3.setHeightForWidth(self.front_label.sizePolicy().hasHeightForWidth())
+ self.front_label.setSizePolicy(sizePolicy3)
+
+ self.horizontalLayout_3.addWidget(self.front_label)
+
+ self.rear_label = QLabel(self.centralwidget)
+ self.rear_label.setObjectName(u"rear_label")
+ sizePolicy3.setHeightForWidth(self.rear_label.sizePolicy().hasHeightForWidth())
+ self.rear_label.setSizePolicy(sizePolicy3)
+
+ self.horizontalLayout_3.addWidget(self.rear_label)
+
+
+ self.verticalLayout.addLayout(self.horizontalLayout_3)
+
+ self.camera_verticalLayout = QVBoxLayout()
+ self.camera_verticalLayout.setSpacing(0)
+ self.camera_verticalLayout.setObjectName(u"camera_verticalLayout")
+ self.camera_verticalLayout.setSizeConstraint(QLayout.SetMaximumSize)
+ self.video_horizontalLayout = QHBoxLayout()
+ self.video_horizontalLayout.setSpacing(0)
+ self.video_horizontalLayout.setObjectName(u"video_horizontalLayout")
+ self.video_horizontalLayout.setContentsMargins(-1, 0, -1, 0)
+
+ self.camera_verticalLayout.addLayout(self.video_horizontalLayout)
+
+
+ self.verticalLayout.addLayout(self.camera_verticalLayout)
+
+ self.thumbnail_horizontalLayout = QHBoxLayout()
+ self.thumbnail_horizontalLayout.setSpacing(2)
+ self.thumbnail_horizontalLayout.setObjectName(u"thumbnail_horizontalLayout")
+ self.ago6hour_verticalLayout = QVBoxLayout()
+ self.ago6hour_verticalLayout.setSpacing(0)
+ self.ago6hour_verticalLayout.setObjectName(u"ago6hour_verticalLayout")
+ self.label_6hour = QLabel(self.centralwidget)
+ self.label_6hour.setObjectName(u"label_6hour")
+ sizePolicy4 = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Preferred)
+ sizePolicy4.setHorizontalStretch(0)
+ sizePolicy4.setVerticalStretch(0)
+ sizePolicy4.setHeightForWidth(self.label_6hour.sizePolicy().hasHeightForWidth())
+ self.label_6hour.setSizePolicy(sizePolicy4)
+ self.label_6hour.setMinimumSize(QSize(0, 0))
+ self.label_6hour.setMaximumSize(QSize(16777215, 131))
+ self.label_6hour.setStyleSheet(u"")
+
+ self.ago6hour_verticalLayout.addWidget(self.label_6hour)
+
+ self.label_6hour_time = QLabel(self.centralwidget)
+ self.label_6hour_time.setObjectName(u"label_6hour_time")
+ sizePolicy3.setHeightForWidth(self.label_6hour_time.sizePolicy().hasHeightForWidth())
+ self.label_6hour_time.setSizePolicy(sizePolicy3)
+ font2 = QFont()
+ font2.setFamilies([u"Noto Sans"])
+ font2.setPointSize(11)
+ font2.setBold(True)
+ self.label_6hour_time.setFont(font2)
+ self.label_6hour_time.setStyleSheet(u"background-color:rgb(27,49,70);\n"
+"color:#ffffff;")
+ self.label_6hour_time.setAlignment(Qt.AlignCenter)
+
+ self.ago6hour_verticalLayout.addWidget(self.label_6hour_time)
+
+
+ self.thumbnail_horizontalLayout.addLayout(self.ago6hour_verticalLayout)
+
+ self.ago5hour_verticalLayout = QVBoxLayout()
+ self.ago5hour_verticalLayout.setSpacing(0)
+ self.ago5hour_verticalLayout.setObjectName(u"ago5hour_verticalLayout")
+ self.label_5hour = QLabel(self.centralwidget)
+ self.label_5hour.setObjectName(u"label_5hour")
+ sizePolicy4.setHeightForWidth(self.label_5hour.sizePolicy().hasHeightForWidth())
+ self.label_5hour.setSizePolicy(sizePolicy4)
+ self.label_5hour.setMinimumSize(QSize(0, 0))
+ self.label_5hour.setMaximumSize(QSize(16777215, 131))
+ self.label_5hour.setStyleSheet(u"")
+
+ self.ago5hour_verticalLayout.addWidget(self.label_5hour)
+
+ self.label_5hour_time = QLabel(self.centralwidget)
+ self.label_5hour_time.setObjectName(u"label_5hour_time")
+ sizePolicy3.setHeightForWidth(self.label_5hour_time.sizePolicy().hasHeightForWidth())
+ self.label_5hour_time.setSizePolicy(sizePolicy3)
+ self.label_5hour_time.setFont(font2)
+ self.label_5hour_time.setStyleSheet(u"background-color:rgb(27,49,70);\n"
+"color:#ffffff;")
+ self.label_5hour_time.setAlignment(Qt.AlignCenter)
+
+ self.ago5hour_verticalLayout.addWidget(self.label_5hour_time)
+
+
+ self.thumbnail_horizontalLayout.addLayout(self.ago5hour_verticalLayout)
+
+ self.ago4hour_verticalLayout = QVBoxLayout()
+ self.ago4hour_verticalLayout.setSpacing(0)
+ self.ago4hour_verticalLayout.setObjectName(u"ago4hour_verticalLayout")
+ self.label_4hour = QLabel(self.centralwidget)
+ self.label_4hour.setObjectName(u"label_4hour")
+ sizePolicy4.setHeightForWidth(self.label_4hour.sizePolicy().hasHeightForWidth())
+ self.label_4hour.setSizePolicy(sizePolicy4)
+ self.label_4hour.setMinimumSize(QSize(0, 0))
+ self.label_4hour.setMaximumSize(QSize(16777215, 131))
+ self.label_4hour.setStyleSheet(u"")
+
+ self.ago4hour_verticalLayout.addWidget(self.label_4hour)
+
+ self.label_4hour_time = QLabel(self.centralwidget)
+ self.label_4hour_time.setObjectName(u"label_4hour_time")
+ sizePolicy3.setHeightForWidth(self.label_4hour_time.sizePolicy().hasHeightForWidth())
+ self.label_4hour_time.setSizePolicy(sizePolicy3)
+ self.label_4hour_time.setFont(font2)
+ self.label_4hour_time.setStyleSheet(u"background-color:rgb(27,49,70);\n"
+"color:#ffffff;")
+ self.label_4hour_time.setAlignment(Qt.AlignCenter)
+
+ self.ago4hour_verticalLayout.addWidget(self.label_4hour_time)
+
+
+ self.thumbnail_horizontalLayout.addLayout(self.ago4hour_verticalLayout)
+
+ self.ago3hour_verticalLayout = QVBoxLayout()
+ self.ago3hour_verticalLayout.setSpacing(0)
+ self.ago3hour_verticalLayout.setObjectName(u"ago3hour_verticalLayout")
+ self.label_3hour = QLabel(self.centralwidget)
+ self.label_3hour.setObjectName(u"label_3hour")
+ sizePolicy4.setHeightForWidth(self.label_3hour.sizePolicy().hasHeightForWidth())
+ self.label_3hour.setSizePolicy(sizePolicy4)
+ self.label_3hour.setMinimumSize(QSize(0, 0))
+ self.label_3hour.setMaximumSize(QSize(16777215, 131))
+ self.label_3hour.setStyleSheet(u"")
+
+ self.ago3hour_verticalLayout.addWidget(self.label_3hour)
+
+ self.label_3hour_time = QLabel(self.centralwidget)
+ self.label_3hour_time.setObjectName(u"label_3hour_time")
+ sizePolicy3.setHeightForWidth(self.label_3hour_time.sizePolicy().hasHeightForWidth())
+ self.label_3hour_time.setSizePolicy(sizePolicy3)
+ self.label_3hour_time.setFont(font2)
+ self.label_3hour_time.setStyleSheet(u"background-color:rgb(27,49,70);\n"
+"color:#ffffff;")
+ self.label_3hour_time.setAlignment(Qt.AlignCenter)
+
+ self.ago3hour_verticalLayout.addWidget(self.label_3hour_time)
+
+
+ self.thumbnail_horizontalLayout.addLayout(self.ago3hour_verticalLayout)
+
+ self.ago2hour_verticalLayout = QVBoxLayout()
+ self.ago2hour_verticalLayout.setSpacing(0)
+ self.ago2hour_verticalLayout.setObjectName(u"ago2hour_verticalLayout")
+ self.label_2hour = QLabel(self.centralwidget)
+ self.label_2hour.setObjectName(u"label_2hour")
+ sizePolicy4.setHeightForWidth(self.label_2hour.sizePolicy().hasHeightForWidth())
+ self.label_2hour.setSizePolicy(sizePolicy4)
+ self.label_2hour.setMinimumSize(QSize(0, 0))
+ self.label_2hour.setMaximumSize(QSize(16777215, 131))
+ self.label_2hour.setStyleSheet(u"")
+
+ self.ago2hour_verticalLayout.addWidget(self.label_2hour)
+
+ self.label_2hour_time = QLabel(self.centralwidget)
+ self.label_2hour_time.setObjectName(u"label_2hour_time")
+ sizePolicy3.setHeightForWidth(self.label_2hour_time.sizePolicy().hasHeightForWidth())
+ self.label_2hour_time.setSizePolicy(sizePolicy3)
+ self.label_2hour_time.setFont(font2)
+ self.label_2hour_time.setStyleSheet(u"background-color:rgb(27,49,70);\n"
+"color:#ffffff;")
+ self.label_2hour_time.setAlignment(Qt.AlignCenter)
+
+ self.ago2hour_verticalLayout.addWidget(self.label_2hour_time)
+
+
+ self.thumbnail_horizontalLayout.addLayout(self.ago2hour_verticalLayout)
+
+ self.ago1hour_verticalLayout = QVBoxLayout()
+ self.ago1hour_verticalLayout.setSpacing(0)
+ self.ago1hour_verticalLayout.setObjectName(u"ago1hour_verticalLayout")
+ self.label_1hour = QLabel(self.centralwidget)
+ self.label_1hour.setObjectName(u"label_1hour")
+ sizePolicy4.setHeightForWidth(self.label_1hour.sizePolicy().hasHeightForWidth())
+ self.label_1hour.setSizePolicy(sizePolicy4)
+ self.label_1hour.setMinimumSize(QSize(0, 0))
+ self.label_1hour.setMaximumSize(QSize(16777215, 131))
+ self.label_1hour.setStyleSheet(u"")
+
+ self.ago1hour_verticalLayout.addWidget(self.label_1hour)
+
+ self.label_1hour_time = QLabel(self.centralwidget)
+ self.label_1hour_time.setObjectName(u"label_1hour_time")
+ sizePolicy3.setHeightForWidth(self.label_1hour_time.sizePolicy().hasHeightForWidth())
+ self.label_1hour_time.setSizePolicy(sizePolicy3)
+ self.label_1hour_time.setFont(font2)
+ self.label_1hour_time.setStyleSheet(u"background-color:rgb(27,49,70);\n"
+"color:#ffffff;")
+ self.label_1hour_time.setAlignment(Qt.AlignCenter)
+
+ self.ago1hour_verticalLayout.addWidget(self.label_1hour_time)
+
+
+ self.thumbnail_horizontalLayout.addLayout(self.ago1hour_verticalLayout)
+
+
+ self.verticalLayout.addLayout(self.thumbnail_horizontalLayout)
+
+ self.line = QFrame(self.centralwidget)
+ self.line.setObjectName(u"line")
+ self.line.setFrameShape(QFrame.HLine)
+ self.line.setFrameShadow(QFrame.Sunken)
+
+ self.verticalLayout.addWidget(self.line)
+
+ self.data_horizontalLayout = QHBoxLayout()
+ self.data_horizontalLayout.setObjectName(u"data_horizontalLayout")
+ self.data_horizontalLayout.setSizeConstraint(QLayout.SetMinimumSize)
+ self.horizontalLayout = QHBoxLayout()
+ self.horizontalLayout.setSpacing(6)
+ self.horizontalLayout.setObjectName(u"horizontalLayout")
+ self.verticalLayout_2 = QVBoxLayout()
+ self.verticalLayout_2.setSpacing(0)
+ self.verticalLayout_2.setObjectName(u"verticalLayout_2")
+ self.horizontalLayout_2 = QHBoxLayout()
+ self.horizontalLayout_2.setSpacing(0)
+ self.horizontalLayout_2.setObjectName(u"horizontalLayout_2")
+ self.timeseries_label_2 = QLabel(self.centralwidget)
+ self.timeseries_label_2.setObjectName(u"timeseries_label_2")
+ sizePolicy2.setHeightForWidth(self.timeseries_label_2.sizePolicy().hasHeightForWidth())
+ self.timeseries_label_2.setSizePolicy(sizePolicy2)
+ font3 = QFont()
+ font3.setFamilies([u"Noto Sans"])
+ font3.setPointSize(23)
+ self.timeseries_label_2.setFont(font3)
+ self.timeseries_label_2.setStyleSheet(u"background-color:rgb(27,49,70);\n"
+"color: #ffffff;")
+
+ self.horizontalLayout_2.addWidget(self.timeseries_label_2)
+
+ self.timeseries_button_2 = QPushButton(self.centralwidget)
+ self.timeseries_button_2.setObjectName(u"timeseries_button_2")
+ sizePolicy1.setHeightForWidth(self.timeseries_button_2.sizePolicy().hasHeightForWidth())
+ self.timeseries_button_2.setSizePolicy(sizePolicy1)
+ self.timeseries_button_2.setMinimumSize(QSize(0, 42))
+ self.timeseries_button_2.setStyleSheet(u"border:0px;\n"
+"background-color: #1b3146;")
+ icon6 = QIcon()
+ icon6.addFile(u"asset/graph.png", QSize(), QIcon.Normal, QIcon.Off)
+ self.timeseries_button_2.setIcon(icon6)
+ self.timeseries_button_2.setIconSize(QSize(32, 32))
+ self.timeseries_button_2.setAutoDefault(True)
+ self.timeseries_button_2.setFlat(True)
+
+ self.horizontalLayout_2.addWidget(self.timeseries_button_2)
+
+
+ self.verticalLayout_2.addLayout(self.horizontalLayout_2)
+
+ self.graph_horizontalLayout = QVBoxLayout()
+ self.graph_horizontalLayout.setObjectName(u"graph_horizontalLayout")
+
+ self.verticalLayout_2.addLayout(self.graph_horizontalLayout)
+
+
+ self.horizontalLayout.addLayout(self.verticalLayout_2)
+
+ self.timeseries_verticalLayout = QVBoxLayout()
+ self.timeseries_verticalLayout.setSpacing(0)
+ self.timeseries_verticalLayout.setObjectName(u"timeseries_verticalLayout")
+ self.timeseries_verticalLayout.setSizeConstraint(QLayout.SetMinimumSize)
+ self.timeseries_verticalLayout.setContentsMargins(-1, -1, 6, -1)
+ self.timeseries_horizontalLayout = QHBoxLayout()
+ self.timeseries_horizontalLayout.setSpacing(0)
+ self.timeseries_horizontalLayout.setObjectName(u"timeseries_horizontalLayout")
+ self.timeseries_label = QLabel(self.centralwidget)
+ self.timeseries_label.setObjectName(u"timeseries_label")
+ sizePolicy2.setHeightForWidth(self.timeseries_label.sizePolicy().hasHeightForWidth())
+ self.timeseries_label.setSizePolicy(sizePolicy2)
+ self.timeseries_label.setFont(font3)
+ self.timeseries_label.setStyleSheet(u"background-color:rgb(27,49,70);\n"
+"color: #ffffff;")
+
+ self.timeseries_horizontalLayout.addWidget(self.timeseries_label)
+
+ self.timeseries_button = QPushButton(self.centralwidget)
+ self.timeseries_button.setObjectName(u"timeseries_button")
+ sizePolicy1.setHeightForWidth(self.timeseries_button.sizePolicy().hasHeightForWidth())
+ self.timeseries_button.setSizePolicy(sizePolicy1)
+ self.timeseries_button.setMinimumSize(QSize(0, 42))
+ self.timeseries_button.setStyleSheet(u"border:0px;\n"
+"background-color: #1b3146;")
+ icon7 = QIcon()
+ icon7.addFile(u"asset/polar.png", QSize(), QIcon.Normal, QIcon.Off)
+ self.timeseries_button.setIcon(icon7)
+ self.timeseries_button.setIconSize(QSize(35, 35))
+ self.timeseries_button.setAutoDefault(True)
+ self.timeseries_button.setFlat(True)
+
+ self.timeseries_horizontalLayout.addWidget(self.timeseries_button)
+
+
+ self.timeseries_verticalLayout.addLayout(self.timeseries_horizontalLayout)
+
+ self.polar_horizontalLayout = QHBoxLayout()
+ self.polar_horizontalLayout.setObjectName(u"polar_horizontalLayout")
+
+ self.timeseries_verticalLayout.addLayout(self.polar_horizontalLayout)
+
+
+ self.horizontalLayout.addLayout(self.timeseries_verticalLayout)
+
+
+ self.data_horizontalLayout.addLayout(self.horizontalLayout)
+
+ self.etc_verticalLayout = QVBoxLayout()
+ self.etc_verticalLayout.setObjectName(u"etc_verticalLayout")
+ self.etc_verticalLayout.setSizeConstraint(QLayout.SetMinimumSize)
+ self.time_horizontalLayout = QHBoxLayout()
+ self.time_horizontalLayout.setSpacing(0)
+ self.time_horizontalLayout.setObjectName(u"time_horizontalLayout")
+ self.time_horizontalLayout.setSizeConstraint(QLayout.SetMinimumSize)
+ self.time_label = QLabel(self.centralwidget)
+ self.time_label.setObjectName(u"time_label")
+ sizePolicy5 = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)
+ sizePolicy5.setHorizontalStretch(0)
+ sizePolicy5.setVerticalStretch(0)
+ sizePolicy5.setHeightForWidth(self.time_label.sizePolicy().hasHeightForWidth())
+ self.time_label.setSizePolicy(sizePolicy5)
+ self.time_label.setFont(font3)
+ self.time_label.setStyleSheet(u"background-color:rgb(27,49,70);\n"
+"color: #ffffff;")
+
+ self.time_horizontalLayout.addWidget(self.time_label)
+
+ self.time_button = QPushButton(self.centralwidget)
+ self.time_button.setObjectName(u"time_button")
+ sizePolicy1.setHeightForWidth(self.time_button.sizePolicy().hasHeightForWidth())
+ self.time_button.setSizePolicy(sizePolicy1)
+ self.time_button.setMinimumSize(QSize(0, 42))
+ self.time_button.setStyleSheet(u"border:0px;\n"
+"background-color: #1b3146;")
+ icon8 = QIcon()
+ icon8.addFile(u"asset/clock.png", QSize(), QIcon.Normal, QIcon.Off)
+ self.time_button.setIcon(icon8)
+ self.time_button.setIconSize(QSize(32, 32))
+
+ self.time_horizontalLayout.addWidget(self.time_button)
+
+
+ self.etc_verticalLayout.addLayout(self.time_horizontalLayout)
+
+ self.real_time_label = QLabel(self.centralwidget)
+ self.real_time_label.setObjectName(u"real_time_label")
+ sizePolicy.setHeightForWidth(self.real_time_label.sizePolicy().hasHeightForWidth())
+ self.real_time_label.setSizePolicy(sizePolicy)
+ font4 = QFont()
+ font4.setFamilies([u"Noto Sans"])
+ font4.setPointSize(40)
+ self.real_time_label.setFont(font4)
+ self.real_time_label.setStyleSheet(u"color:#ffffff;")
+ self.real_time_label.setAlignment(Qt.AlignCenter)
+
+ self.etc_verticalLayout.addWidget(self.real_time_label)
+
+ self.prevailing_vis_horizontalLayout = QHBoxLayout()
+ self.prevailing_vis_horizontalLayout.setSpacing(0)
+ self.prevailing_vis_horizontalLayout.setObjectName(u"prevailing_vis_horizontalLayout")
+ self.prevailing_vis_horizontalLayout.setSizeConstraint(QLayout.SetMinimumSize)
+ self.prevailing_vis_label = QLabel(self.centralwidget)
+ self.prevailing_vis_label.setObjectName(u"prevailing_vis_label")
+ sizePolicy5.setHeightForWidth(self.prevailing_vis_label.sizePolicy().hasHeightForWidth())
+ self.prevailing_vis_label.setSizePolicy(sizePolicy5)
+ self.prevailing_vis_label.setFont(font3)
+ self.prevailing_vis_label.setStyleSheet(u"background-color:rgb(27,49,70);\n"
+"color: #ffffff;")
+
+ self.prevailing_vis_horizontalLayout.addWidget(self.prevailing_vis_label)
+
+ self.prevailing_vis_button = QPushButton(self.centralwidget)
+ self.prevailing_vis_button.setObjectName(u"prevailing_vis_button")
+ self.prevailing_vis_button.setEnabled(True)
+ sizePolicy1.setHeightForWidth(self.prevailing_vis_button.sizePolicy().hasHeightForWidth())
+ self.prevailing_vis_button.setSizePolicy(sizePolicy1)
+ self.prevailing_vis_button.setMinimumSize(QSize(0, 42))
+ self.prevailing_vis_button.setStyleSheet(u"border:0px;\n"
+"background-color: #1b3146;")
+ icon9 = QIcon()
+ icon9.addFile(u"asset/vis.png", QSize(), QIcon.Normal, QIcon.Off)
+ self.prevailing_vis_button.setIcon(icon9)
+ self.prevailing_vis_button.setIconSize(QSize(32, 32))
+
+ self.prevailing_vis_horizontalLayout.addWidget(self.prevailing_vis_button)
+
+
+ self.etc_verticalLayout.addLayout(self.prevailing_vis_horizontalLayout)
+
+ self.c_vis_label = QLabel(self.centralwidget)
+ self.c_vis_label.setObjectName(u"c_vis_label")
+ sizePolicy.setHeightForWidth(self.c_vis_label.sizePolicy().hasHeightForWidth())
+ self.c_vis_label.setSizePolicy(sizePolicy)
+ self.c_vis_label.setFont(font4)
+ self.c_vis_label.setStyleSheet(u"color:#ffffff;")
+ self.c_vis_label.setAlignment(Qt.AlignCenter)
+
+ self.etc_verticalLayout.addWidget(self.c_vis_label)
+
+ self.prediction_vis_horizontalLayout = QHBoxLayout()
+ self.prediction_vis_horizontalLayout.setSpacing(0)
+ self.prediction_vis_horizontalLayout.setObjectName(u"prediction_vis_horizontalLayout")
+ self.label = QLabel(self.centralwidget)
+ self.label.setObjectName(u"label")
+ sizePolicy5.setHeightForWidth(self.label.sizePolicy().hasHeightForWidth())
+ self.label.setSizePolicy(sizePolicy5)
+ self.label.setFont(font3)
+ self.label.setStyleSheet(u"background-color:rgb(27,49,70);color: rgb(69, 165, 255);")
+
+ self.prediction_vis_horizontalLayout.addWidget(self.label)
+
+ self.button = QPushButton(self.centralwidget)
+ self.button.setObjectName(u"button")
+ sizePolicy1.setHeightForWidth(self.button.sizePolicy().hasHeightForWidth())
+ self.button.setSizePolicy(sizePolicy1)
+ self.button.setMinimumSize(QSize(0, 42))
+ self.button.setStyleSheet(u"border:0px;background-color:rgb(27,49,70);color: rgb(69, 165, 255);")
+ icon10 = QIcon()
+ icon10.addFile(u"asset/pre_vis_1.png", QSize(), QIcon.Normal, QIcon.Off)
+ self.button.setIcon(icon10)
+ self.button.setIconSize(QSize(32, 32))
+ self.button.setFlat(False)
+
+ self.prediction_vis_horizontalLayout.addWidget(self.button)
+
+
+ self.etc_verticalLayout.addLayout(self.prediction_vis_horizontalLayout)
+
+ self.p_vis_label = QLabel(self.centralwidget)
+ self.p_vis_label.setObjectName(u"p_vis_label")
+ sizePolicy.setHeightForWidth(self.p_vis_label.sizePolicy().hasHeightForWidth())
+ self.p_vis_label.setSizePolicy(sizePolicy)
+ self.p_vis_label.setFont(font4)
+ self.p_vis_label.setStyleSheet(u"color: rgb(69, 165, 255);")
+ self.p_vis_label.setAlignment(Qt.AlignCenter)
+
+ self.etc_verticalLayout.addWidget(self.p_vis_label)
+
+
+ self.data_horizontalLayout.addLayout(self.etc_verticalLayout)
+
+
+ self.verticalLayout.addLayout(self.data_horizontalLayout)
+
+
+ self.gridLayout.addLayout(self.verticalLayout, 0, 0, 1, 1)
+
+ MainWindow.setCentralWidget(self.centralwidget)
+
+ self.retranslateUi(MainWindow)
+ self.actionExit.triggered.connect(MainWindow.close)
+
+ self.logo.setDefault(True)
+ self.maxfev_alert.setDefault(True)
+ self.alert.setDefault(True)
+ self.log_view.setDefault(True)
+ self.setting_button.setDefault(True)
+ self.timeseries_button_2.setDefault(True)
+ self.timeseries_button.setDefault(True)
+
+
+ QMetaObject.connectSlotsByName(MainWindow)
+ # setupUi
+
+ def retranslateUi(self, MainWindow):
+ MainWindow.setWindowTitle(QCoreApplication.translate("MainWindow", u"JS-08", None))
+ self.actionExit.setText(QCoreApplication.translate("MainWindow", u"&Quit", None))
+#if QT_CONFIG(tooltip)
+ self.actionExit.setToolTip(QCoreApplication.translate("MainWindow", u"Exit", None))
+#endif // QT_CONFIG(tooltip)
+#if QT_CONFIG(statustip)
+ self.actionExit.setStatusTip(QCoreApplication.translate("MainWindow", u"Exit JS-06", None))
+#endif // QT_CONFIG(statustip)
+#if QT_CONFIG(shortcut)
+ self.actionExit.setShortcut(QCoreApplication.translate("MainWindow", u"Ctrl+W", None))
+#endif // QT_CONFIG(shortcut)
+ self.actionsd.setText(QCoreApplication.translate("MainWindow", u"sd", None))
+ self.actionkm.setText(QCoreApplication.translate("MainWindow", u"km", None))
+ self.actionmi.setText(QCoreApplication.translate("MainWindow", u"mi", None))
+ self.actionInference.setText(QCoreApplication.translate("MainWindow", u"Inference", None))
+#if QT_CONFIG(shortcut)
+ self.actionInference.setShortcut(QCoreApplication.translate("MainWindow", u"I", None))
+#endif // QT_CONFIG(shortcut)
+ self.actionEdit_Target.setText(QCoreApplication.translate("MainWindow", u"Edit &Target", None))
+ self.actionEdit_Camera.setText(QCoreApplication.translate("MainWindow", u"Edit &Camera Info", None))
+ self.actionAbout.setText(QCoreApplication.translate("MainWindow", u"About", None))
+ self.actionConfiguration.setText(QCoreApplication.translate("MainWindow", u"Con&figuration", None))
+ self.thumbnail_info_label_2.setText("")
+ self.logo.setText("")
+ self.thumbnail_info_label.setText("")
+#if QT_CONFIG(tooltip)
+ self.maxfev_alert.setToolTip(QCoreApplication.translate("MainWindow", u"Optimal parameters not found: Number of calls to function has reached max fev = 5000.", None))
+#endif // QT_CONFIG(tooltip)
+ self.maxfev_alert.setText("")
+ self.blank_label_2.setText("")
+ self.alert.setText("")
+ self.blank_label_3.setText("")
+ self.log_view.setText("")
+ self.blank_label.setText("")
+ self.setting_button.setText("")
+ self.front_label.setText("")
+ self.rear_label.setText("")
+ self.label_6hour.setText("")
+ self.label_6hour_time.setText("")
+ self.label_5hour.setText("")
+ self.label_5hour_time.setText("")
+ self.label_4hour.setText("")
+ self.label_4hour_time.setText("")
+ self.label_3hour.setText("")
+ self.label_3hour_time.setText("")
+ self.label_2hour.setText("")
+ self.label_2hour_time.setText("")
+ self.label_1hour.setText("")
+ self.label_1hour_time.setText("")
+ self.timeseries_label_2.setText(QCoreApplication.translate("MainWindow", u" Time series", None))
+ self.timeseries_button_2.setText("")
+ self.timeseries_label.setText(QCoreApplication.translate("MainWindow", u" Discernment", None))
+ self.timeseries_button.setText("")
+ self.time_label.setText(QCoreApplication.translate("MainWindow", u" Current time", None))
+ self.time_button.setText("")
+ self.real_time_label.setText("")
+ self.prevailing_vis_label.setText(QCoreApplication.translate("MainWindow", u" Prevailing Visibility", None))
+ self.prevailing_vis_button.setText("")
+ self.c_vis_label.setText(QCoreApplication.translate("MainWindow", u"- m", None))
+ self.label.setText(QCoreApplication.translate("MainWindow", u" Prediction Visibility", None))
+ self.button.setText("")
+ self.p_vis_label.setText(QCoreApplication.translate("MainWindow", u"- m", None))
+ # retranslateUi
+
diff --git a/src/resources/main_window.ui b/src/resources/main_window.ui
index ca94d06..9cba03d 100644
--- a/src/resources/main_window.ui
+++ b/src/resources/main_window.ui
@@ -41,10 +41,11 @@
- resources/icon/logo.pngresources/icon/logo.png
+ asset/logo.pngasset/logo.png
- background-color:rgb(22,32,42);
+ background-color:rgb(22,32,42);
+color: rgb(255, 255, 255);
@@ -77,6 +78,9 @@
-
+
+ 0
+
0
@@ -84,184 +88,413 @@
0
-
-
+
0
-
- QLayout::SetMaximumSize
-
-
-
-
- 0
+
+
+
+ 0
+ 0
+
-
-
-
-
-
- 0
- 0
-
-
-
-
- Noto Sans
- 30
-
-
-
- background-color:rgb(27,49,70);
-color:rgb(28,136,227);
-
-
- Monitoring
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- Noto Sans
- 30
-
-
-
- background-color:rgb(27,49,70);
+
+
+ 0
+ 50
+
+
+
+
+ Noto Sans
+ 30
+
+
+
+ background-color:rgb(27,49,70);
color: rgb(255, 0, 0);
-
-
-
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- 0
- 55
-
-
-
- border:0px;
+
+
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 50
+
+
+
+ border:0px;
background-color: #1b3146;
-
-
-
-
-
-
- asset/green.pngasset/green.png
-
-
-
- 30
- 30
-
-
-
- true
-
-
- true
-
-
- true
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- 16
- 55
-
-
-
- border:0px;
+
+
+
+
+
+
+ asset/f_logo.pngasset/f_logo.png
+
+
+
+ 295
+ 50
+
+
+
+ 300
+
+
+ true
+
+
+ true
+
+
+ true
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 50
+
+
+
+
+ Noto Sans
+ 30
+
+
+
+ background-color:rgb(27,49,70);
+color: rgb(255, 0, 0);
+
+
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 50
+
+
+
+ Optimal parameters not found: Number of calls to function has reached max fev = 5000.
+
+
+ border:0px;
background-color: #1b3146;
-
-
-
-
-
-
- -
-
-
- true
-
-
-
- 0
- 0
-
-
-
-
- 0
- 55
-
-
-
- OpenHandCursor
-
-
- border:0px;
+
+
+
+
+
+
+ asset/alert.pngasset/alert.png
+
+
+
+ 30
+ 30
+
+
+
+ true
+
+
+ true
+
+
+ true
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 16
+ 50
+
+
+
+ border:0px;
background-color: #1b3146;
-
-
-
-
-
-
- asset/settings.pngasset/settings.png
-
-
-
- 40
- 40
-
-
-
- true
-
-
- true
-
-
- true
-
-
-
-
+
+
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 50
+
+
+
+ border:0px;
+background-color: #1b3146;
+
+
+
+
+
+
+ asset/green.pngasset/green.png
+
+
+
+ 30
+ 30
+
+
+
+ true
+
+
+ true
+
+
+ true
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 16
+ 50
+
+
+
+ border:0px;
+background-color: #1b3146;
+
+
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 50
+
+
+
+ OpenHandCursor
+
+
+ border:0px;
+background-color: #1b3146;
+
+
+
+
+
+
+ asset/log.pngasset/log.png
+
+
+
+ 40
+ 40
+
+
+
+ true
+
+
+ true
+
+
+ true
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 16
+ 50
+
+
+
+ border:0px;
+background-color: #1b3146;
+
+
+
+
+
+
+ -
+
+
+ true
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 50
+
+
+
+ OpenHandCursor
+
+
+ border:0px;
+background-color: #1b3146;
+
+
+
+
+
+
+ asset/settings.pngasset/settings.png
+
+
+
+ 40
+ 40
+
+
+
+ true
+
+
+ true
+
+
+ true
+
+
+
+
+
+ -
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+
+
+
+
+
+ -
+
+
+ 0
+
+
+ QLayout::SetMaximumSize
+
-
0
+
+ 0
+
+
+ 0
+
@@ -269,7 +502,7 @@ background-color: #1b3146;
-
- 6
+ 2
-
@@ -278,6 +511,12 @@ background-color: #1b3146;
-
+
+
+ 0
+ 0
+
+
0
@@ -291,7 +530,7 @@ background-color: #1b3146;
- background-color: rgb(255, 255, 255);
+
@@ -309,6 +548,7 @@ background-color: #1b3146;
Noto Sans
+ 11
75
true
@@ -334,6 +574,12 @@ color:#ffffff;
-
+
+
+ 0
+ 0
+
+
0
@@ -347,7 +593,7 @@ color:#ffffff;
- background-color: rgb(255, 255, 255);
+
@@ -365,6 +611,7 @@ color:#ffffff;
Noto Sans
+ 11
75
true
@@ -390,6 +637,12 @@ color:#ffffff;
-
+
+
+ 0
+ 0
+
+
0
@@ -403,7 +656,7 @@ color:#ffffff;
- background-color: rgb(255, 255, 255);
+
@@ -421,6 +674,7 @@ color:#ffffff;
Noto Sans
+ 11
75
true
@@ -446,6 +700,12 @@ color:#ffffff;
-
+
+
+ 0
+ 0
+
+
0
@@ -459,7 +719,7 @@ color:#ffffff;
- background-color: rgb(255, 255, 255);
+
@@ -477,6 +737,7 @@ color:#ffffff;
Noto Sans
+ 11
75
true
@@ -502,6 +763,12 @@ color:#ffffff;
-
+
+
+ 0
+ 0
+
+
0
@@ -515,7 +782,7 @@ color:#ffffff;
- background-color: rgb(255, 255, 255);
+
@@ -533,6 +800,7 @@ color:#ffffff;
Noto Sans
+ 11
75
true
@@ -558,6 +826,12 @@ color:#ffffff;
-
+
+
+ 0
+ 0
+
+
0
@@ -571,7 +845,7 @@ color:#ffffff;
- background-color: rgb(255, 255, 255);
+
@@ -589,6 +863,7 @@ color:#ffffff;
Noto Sans
+ 11
75
true
@@ -617,111 +892,182 @@ color:#ffffff;
-
-
+
QLayout::SetMinimumSize
-
-
-
- QLayout::SetMinimumSize
-
-
- 12
+
+
+ 6
-
-
+
0
-
-
-
-
- 0
- 0
-
-
-
-
- Noto Sans
- 23
-
+
+
+ 0
-
- background-color:rgb(27,49,70);
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ Noto Sans
+ 23
+
+
+
+ background-color:rgb(27,49,70);
color: #ffffff;
-
-
- Time series
-
-
+
+
+ Time series
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 42
+
+
+
+ border:0px;
+background-color: #1b3146;
+
+
+
+
+
+
+ asset/graph.pngasset/graph.png
+
+
+
+ 32
+ 32
+
+
+
+ true
+
+
+ true
+
+
+ true
+
+
+
+
-
-
-
-
- 0
- 0
-
-
-
-
- 0
- 42
-
-
-
- border:0px;
-background-color: #1b3146;
-
-
-
-
-
-
- resources/icon/graph.pngresources/icon/graph.png
-
-
-
- 32
- 32
-
-
-
- true
-
-
- true
-
-
- true
-
-
+
-
-
+
+
+ 0
+
+
+ QLayout::SetMinimumSize
+
+
+ 6
+
-
-
-
-
- 0
- 0
-
+
+
+ 0
-
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ Noto Sans
+ 23
+
+
+
+ background-color:rgb(27,49,70);
+color: #ffffff;
+
+
+ Discernment
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 42
+
+
+
+ border:0px;
+background-color: #1b3146;
+
+
+
+
+
+
+ asset/polar.pngasset/polar.png
+
+
+
+ 35
+ 35
+
+
+
+ true
+
+
+ true
+
+
+ true
+
+
+
+
-
-
-
-
- 0
- 0
-
-
-
+
@@ -786,7 +1132,7 @@ background-color: #1b3146;
- resources/icon/clock.pngresources/icon/clock.png
+ asset/clock.pngasset/clock.png
@@ -856,6 +1202,9 @@ color: #ffffff;
-
+
+ true
+
0
@@ -877,7 +1226,7 @@ background-color: #1b3146;
- resources/icon/vis.pngresources/icon/vis.png
+ asset/vis.pngasset/vis.png
@@ -904,10 +1253,10 @@ background-color: #1b3146;
- color:rgb(28,136,227);
+ color:#ffffff;
- - km
+ - m
Qt::AlignCenter
@@ -934,8 +1283,7 @@ background-color: #1b3146;
- background-color:rgb(27,49,70);
-color: #ffffff;
+ background-color:rgb(27,49,70);color: rgb(69, 165, 255);
Prediction Visibility
@@ -943,7 +1291,7 @@ color: #ffffff;
-
-
+
0
@@ -957,15 +1305,14 @@ color: #ffffff;
- border:0px;
-background-color: #1b3146;
+ border:0px;background-color:rgb(27,49,70);color: rgb(69, 165, 255);
- resources/icon/vis.pngresources/icon/vis.png
+ asset/pre_vis_1.pngasset/pre_vis_1.png
@@ -973,6 +1320,9 @@ background-color: #1b3146;
32
+
+ false
+
@@ -992,10 +1342,10 @@ background-color: #1b3146;
- color:#ffffff
+ color: rgb(69, 165, 255);
- - km
+ - m
Qt::AlignCenter
@@ -1010,54 +1360,6 @@ background-color: #1b3146;
-
&Quit
@@ -1140,9 +1442,7 @@ color:#ffffff;
-
-
-
+
actionExit
diff --git a/src/resources/pyside6-uic.exe b/src/resources/pyside6-uic.exe
new file mode 100644
index 0000000..60d24b6
Binary files /dev/null and b/src/resources/pyside6-uic.exe differ
diff --git a/src/resources/resources.qrc b/src/resources/resources.qrc
index f86138c..7646d2b 100644
--- a/src/resources/resources.qrc
+++ b/src/resources/resources.qrc
@@ -1,13 +1 @@
-
-
- icon/clock.png
- icon/graph.png
- icon/settings.png
- icon/settings_on.png
- icon/vis.png
- icon/green.png
-
-
- icon/logo.png
-
-
+
diff --git a/src/resources/rtsp_setting.py b/src/resources/rtsp_setting.py
new file mode 100644
index 0000000..4e6e476
--- /dev/null
+++ b/src/resources/rtsp_setting.py
@@ -0,0 +1,191 @@
+# -*- coding: utf-8 -*-
+
+################################################################################
+## Form generated from reading UI file 'rtsp_setting.ui'
+##
+## Created by: Qt User Interface Compiler version 6.3.0
+##
+## 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 (QAbstractButton, QApplication, QDialog, QDialogButtonBox,
+ QGridLayout, QGroupBox, QLabel, QLineEdit,
+ QSizePolicy, QWidget)
+
+class Ui_Dialog(object):
+ def setupUi(self, Dialog):
+ if not Dialog.objectName():
+ Dialog.setObjectName(u"Dialog")
+ Dialog.resize(493, 416)
+ self.gridLayout = QGridLayout(Dialog)
+ self.gridLayout.setObjectName(u"gridLayout")
+ self.groupBox = QGroupBox(Dialog)
+ self.groupBox.setObjectName(u"groupBox")
+ self.gridLayout_4 = QGridLayout(self.groupBox)
+ self.gridLayout_4.setObjectName(u"gridLayout_4")
+ self.label_2 = QLabel(self.groupBox)
+ self.label_2.setObjectName(u"label_2")
+ self.label_2.setAlignment(Qt.AlignCenter)
+
+ self.gridLayout_4.addWidget(self.label_2, 1, 0, 1, 1)
+
+ self.front_rtsp_lineEdit = QLineEdit(self.groupBox)
+ self.front_rtsp_lineEdit.setObjectName(u"front_rtsp_lineEdit")
+
+ self.gridLayout_4.addWidget(self.front_rtsp_lineEdit, 1, 1, 1, 1)
+
+ self.label_3 = QLabel(self.groupBox)
+ self.label_3.setObjectName(u"label_3")
+ self.label_3.setAlignment(Qt.AlignCenter)
+
+ self.gridLayout_4.addWidget(self.label_3, 2, 0, 1, 1)
+
+ self.front_resize_rtsp_lineEdit = QLineEdit(self.groupBox)
+ self.front_resize_rtsp_lineEdit.setObjectName(u"front_resize_rtsp_lineEdit")
+
+ self.gridLayout_4.addWidget(self.front_resize_rtsp_lineEdit, 2, 1, 1, 1)
+
+ self.label = QLabel(self.groupBox)
+ self.label.setObjectName(u"label")
+ self.label.setAlignment(Qt.AlignCenter)
+
+ self.gridLayout_4.addWidget(self.label, 0, 0, 1, 1)
+
+ self.front_model_lineEdit = QLineEdit(self.groupBox)
+ self.front_model_lineEdit.setObjectName(u"front_model_lineEdit")
+
+ self.gridLayout_4.addWidget(self.front_model_lineEdit, 0, 1, 1, 1)
+
+
+ self.gridLayout.addWidget(self.groupBox, 0, 0, 1, 1)
+
+ self.groupBox_2 = QGroupBox(Dialog)
+ self.groupBox_2.setObjectName(u"groupBox_2")
+ self.gridLayout_5 = QGridLayout(self.groupBox_2)
+ self.gridLayout_5.setObjectName(u"gridLayout_5")
+ self.label_4 = QLabel(self.groupBox_2)
+ self.label_4.setObjectName(u"label_4")
+ self.label_4.setAlignment(Qt.AlignCenter)
+
+ self.gridLayout_5.addWidget(self.label_4, 0, 0, 1, 1)
+
+ self.label_5 = QLabel(self.groupBox_2)
+ self.label_5.setObjectName(u"label_5")
+ self.label_5.setAlignment(Qt.AlignCenter)
+
+ self.gridLayout_5.addWidget(self.label_5, 1, 0, 1, 1)
+
+ self.rear_model_lineEdit = QLineEdit(self.groupBox_2)
+ self.rear_model_lineEdit.setObjectName(u"rear_model_lineEdit")
+
+ self.gridLayout_5.addWidget(self.rear_model_lineEdit, 0, 1, 1, 1)
+
+ self.rear_rtsp_lineEdit = QLineEdit(self.groupBox_2)
+ self.rear_rtsp_lineEdit.setObjectName(u"rear_rtsp_lineEdit")
+
+ self.gridLayout_5.addWidget(self.rear_rtsp_lineEdit, 1, 1, 1, 1)
+
+ self.label_6 = QLabel(self.groupBox_2)
+ self.label_6.setObjectName(u"label_6")
+ self.label_6.setAlignment(Qt.AlignCenter)
+
+ self.gridLayout_5.addWidget(self.label_6, 2, 0, 1, 1)
+
+ self.rear_resize_rtsp_lineEdit = QLineEdit(self.groupBox_2)
+ self.rear_resize_rtsp_lineEdit.setObjectName(u"rear_resize_rtsp_lineEdit")
+
+ self.gridLayout_5.addWidget(self.rear_resize_rtsp_lineEdit, 2, 1, 1, 1)
+
+
+ self.gridLayout.addWidget(self.groupBox_2, 1, 0, 1, 1)
+
+ self.buttonBox = QDialogButtonBox(Dialog)
+ self.buttonBox.setObjectName(u"buttonBox")
+ self.buttonBox.setOrientation(Qt.Horizontal)
+ self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel|QDialogButtonBox.Ok)
+
+ self.gridLayout.addWidget(self.buttonBox, 3, 0, 1, 1)
+
+ self.groupBox_3 = QGroupBox(Dialog)
+ self.groupBox_3.setObjectName(u"groupBox_3")
+ self.gridLayout_6 = QGridLayout(self.groupBox_3)
+ self.gridLayout_6.setObjectName(u"gridLayout_6")
+ self.label_7 = QLabel(self.groupBox_3)
+ self.label_7.setObjectName(u"label_7")
+ self.label_7.setAlignment(Qt.AlignCenter)
+
+ self.gridLayout_6.addWidget(self.label_7, 0, 0, 1, 1)
+
+ self.data_path_lineEdit = QLineEdit(self.groupBox_3)
+ self.data_path_lineEdit.setObjectName(u"data_path_lineEdit")
+
+ self.gridLayout_6.addWidget(self.data_path_lineEdit, 0, 1, 1, 1)
+
+ self.rgb_path_lineEdit = QLineEdit(self.groupBox_3)
+ self.rgb_path_lineEdit.setObjectName(u"rgb_path_lineEdit")
+
+ self.gridLayout_6.addWidget(self.rgb_path_lineEdit, 2, 1, 1, 1)
+
+ self.label_8 = QLabel(self.groupBox_3)
+ self.label_8.setObjectName(u"label_8")
+ self.label_8.setAlignment(Qt.AlignCenter)
+
+ self.gridLayout_6.addWidget(self.label_8, 1, 0, 1, 1)
+
+ self.target_path_lineEdit = QLineEdit(self.groupBox_3)
+ self.target_path_lineEdit.setObjectName(u"target_path_lineEdit")
+
+ self.gridLayout_6.addWidget(self.target_path_lineEdit, 1, 1, 1, 1)
+
+ self.label_9 = QLabel(self.groupBox_3)
+ self.label_9.setObjectName(u"label_9")
+ self.label_9.setAlignment(Qt.AlignCenter)
+
+ self.gridLayout_6.addWidget(self.label_9, 2, 0, 1, 1)
+
+ self.label_10 = QLabel(self.groupBox_3)
+ self.label_10.setObjectName(u"label_10")
+ self.label_10.setAlignment(Qt.AlignCenter)
+
+ self.gridLayout_6.addWidget(self.label_10, 3, 0, 1, 1)
+
+ self.image_path_lineEdit = QLineEdit(self.groupBox_3)
+ self.image_path_lineEdit.setObjectName(u"image_path_lineEdit")
+
+ self.gridLayout_6.addWidget(self.image_path_lineEdit, 3, 1, 1, 1)
+
+
+ self.gridLayout.addWidget(self.groupBox_3, 2, 0, 1, 1)
+
+
+ self.retranslateUi(Dialog)
+ self.buttonBox.accepted.connect(Dialog.accept)
+ self.buttonBox.rejected.connect(Dialog.reject)
+
+ QMetaObject.connectSlotsByName(Dialog)
+ # setupUi
+
+ def retranslateUi(self, Dialog):
+ Dialog.setWindowTitle(QCoreApplication.translate("Dialog", u"JS-08 Setting", None))
+ self.groupBox.setTitle(QCoreApplication.translate("Dialog", u"Front Camera", None))
+ self.label_2.setText(QCoreApplication.translate("Dialog", u"RTSP", None))
+ self.label_3.setText(QCoreApplication.translate("Dialog", u"Resize RTSP", None))
+ self.label.setText(QCoreApplication.translate("Dialog", u"Model", None))
+ self.groupBox_2.setTitle(QCoreApplication.translate("Dialog", u"Rear Camera", None))
+ self.label_4.setText(QCoreApplication.translate("Dialog", u"Model", None))
+ self.label_5.setText(QCoreApplication.translate("Dialog", u"RTSP", None))
+ self.label_6.setText(QCoreApplication.translate("Dialog", u"Resize RTSP", None))
+ self.groupBox_3.setTitle(QCoreApplication.translate("Dialog", u"Path", None))
+ self.label_7.setText(QCoreApplication.translate("Dialog", u"Data", None))
+ self.label_8.setText(QCoreApplication.translate("Dialog", u"Target", None))
+ self.label_9.setText(QCoreApplication.translate("Dialog", u"RGB", None))
+ self.label_10.setText(QCoreApplication.translate("Dialog", u"Image", None))
+ # retranslateUi
+
diff --git a/src/resources/rtsp_setting.ui b/src/resources/rtsp_setting.ui
new file mode 100644
index 0000000..56c6b0d
--- /dev/null
+++ b/src/resources/rtsp_setting.ui
@@ -0,0 +1,234 @@
+
+
+ Dialog
+
+
+
+ 0
+ 0
+ 493
+ 538
+
+
+
+ JS-08 Setting
+
+
+ -
+
+
+ Path
+
+
+
-
+
+
+ Data
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+ -
+
+
+ Target
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+ -
+
+
+ RGB
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ Log
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+ Image
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+ Front Camera
+
+
+
-
+
+
+ RTSP
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+ -
+
+
+ Resize RTSP
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+ -
+
+
+ Model
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+ Rear Camera
+
+
+
-
+
+
+ Model
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+ RTSP
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ Resize RTSP
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+ QDialogButtonBox::Cancel|QDialogButtonBox::Ok
+
+
+
+
+
+
+
+
+ buttonBox
+ accepted()
+ Dialog
+ accept()
+
+
+ 248
+ 254
+
+
+ 157
+ 274
+
+
+
+
+ buttonBox
+ rejected()
+ Dialog
+ reject()
+
+
+ 316
+ 260
+
+
+ 286
+ 274
+
+
+
+
+
diff --git a/src/resources/setting_window.py b/src/resources/setting_window.py
new file mode 100644
index 0000000..94effb8
--- /dev/null
+++ b/src/resources/setting_window.py
@@ -0,0 +1,548 @@
+# -*- coding: utf-8 -*-
+
+################################################################################
+## Form generated from reading UI file 'setting_window.ui'
+##
+## Created by: Qt User Interface Compiler version 6.3.0
+##
+## 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 (QAbstractButton, QApplication, QCheckBox, QComboBox,
+ QDialog, QDialogButtonBox, QGridLayout, QHBoxLayout,
+ QHeaderView, QLabel, QLayout, QLineEdit,
+ QPushButton, QSizePolicy, QSpinBox, QTableWidget,
+ QTableWidgetItem, QTextBrowser, QVBoxLayout, QWidget)
+
+class Ui_Dialog(object):
+ def setupUi(self, Dialog):
+ if not Dialog.objectName():
+ Dialog.setObjectName(u"Dialog")
+ Dialog.resize(1207, 767)
+ sizePolicy = QSizePolicy(QSizePolicy.Maximum, QSizePolicy.Preferred)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(Dialog.sizePolicy().hasHeightForWidth())
+ Dialog.setSizePolicy(sizePolicy)
+ self.gridLayout = QGridLayout(Dialog)
+ self.gridLayout.setSpacing(0)
+ self.gridLayout.setObjectName(u"gridLayout")
+ self.gridLayout.setContentsMargins(0, 0, 0, 0)
+ self.gridWidget = QWidget(Dialog)
+ self.gridWidget.setObjectName(u"gridWidget")
+ self.gridWidget.setStyleSheet(u"background-color:rgb(22,32,42);")
+ self.gridLayout_2 = QGridLayout(self.gridWidget)
+ self.gridLayout_2.setObjectName(u"gridLayout_2")
+ self.main_verticalLayout = QVBoxLayout()
+ self.main_verticalLayout.setObjectName(u"main_verticalLayout")
+ self.top_horizontalLayout = QHBoxLayout()
+ self.top_horizontalLayout.setObjectName(u"top_horizontalLayout")
+ self.setting_verticalLayout = QVBoxLayout()
+ self.setting_verticalLayout.setObjectName(u"setting_verticalLayout")
+ self.setting_horizontalLayout = QHBoxLayout()
+ self.setting_horizontalLayout.setSpacing(0)
+ self.setting_horizontalLayout.setObjectName(u"setting_horizontalLayout")
+ self.target_setting_label = QLabel(self.gridWidget)
+ self.target_setting_label.setObjectName(u"target_setting_label")
+ sizePolicy1 = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Maximum)
+ sizePolicy1.setHorizontalStretch(0)
+ sizePolicy1.setVerticalStretch(0)
+ sizePolicy1.setHeightForWidth(self.target_setting_label.sizePolicy().hasHeightForWidth())
+ self.target_setting_label.setSizePolicy(sizePolicy1)
+ font = QFont()
+ font.setFamilies([u"Noto Sans"])
+ font.setPointSize(23)
+ self.target_setting_label.setFont(font)
+ self.target_setting_label.setStyleSheet(u"background-color:rgb(27,49,70);\n"
+"color: #ffffff;")
+
+ self.setting_horizontalLayout.addWidget(self.target_setting_label)
+
+ self.flip_button = QPushButton(self.gridWidget)
+ self.flip_button.setObjectName(u"flip_button")
+ sizePolicy2 = QSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum)
+ sizePolicy2.setHorizontalStretch(0)
+ sizePolicy2.setVerticalStretch(0)
+ sizePolicy2.setHeightForWidth(self.flip_button.sizePolicy().hasHeightForWidth())
+ self.flip_button.setSizePolicy(sizePolicy2)
+ self.flip_button.setMinimumSize(QSize(0, 42))
+ font1 = QFont()
+ font1.setFamilies([u"Noto Sans"])
+ font1.setPointSize(15)
+ self.flip_button.setFont(font1)
+ self.flip_button.setCursor(QCursor(Qt.PointingHandCursor))
+ self.flip_button.setStyleSheet(u"border:0px;\n"
+"background-color: #1b3146;\n"
+"color: #ffffff;")
+ icon = QIcon()
+ icon.addFile(u"asset/flip_off.png", QSize(), QIcon.Normal, QIcon.Off)
+ self.flip_button.setIcon(icon)
+ self.flip_button.setIconSize(QSize(40, 40))
+ self.flip_button.setFlat(True)
+
+ self.setting_horizontalLayout.addWidget(self.flip_button)
+
+
+ self.setting_verticalLayout.addLayout(self.setting_horizontalLayout)
+
+ self.image_label = QLabel(self.gridWidget)
+ self.image_label.setObjectName(u"image_label")
+ sizePolicy3 = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)
+ sizePolicy3.setHorizontalStretch(0)
+ sizePolicy3.setVerticalStretch(0)
+ sizePolicy3.setHeightForWidth(self.image_label.sizePolicy().hasHeightForWidth())
+ self.image_label.setSizePolicy(sizePolicy3)
+
+ self.setting_verticalLayout.addWidget(self.image_label)
+
+
+ self.top_horizontalLayout.addLayout(self.setting_verticalLayout)
+
+
+ self.main_verticalLayout.addLayout(self.top_horizontalLayout)
+
+ self.bottom_horizontalLayout = QHBoxLayout()
+ self.bottom_horizontalLayout.setSpacing(12)
+ self.bottom_horizontalLayout.setObjectName(u"bottom_horizontalLayout")
+ self.target_list_verticalLayout = QVBoxLayout()
+ self.target_list_verticalLayout.setSpacing(0)
+ self.target_list_verticalLayout.setObjectName(u"target_list_verticalLayout")
+ self.target_list_verticalLayout.setContentsMargins(6, -1, -1, -1)
+ self.target_list_label = QLabel(self.gridWidget)
+ self.target_list_label.setObjectName(u"target_list_label")
+ sizePolicy1.setHeightForWidth(self.target_list_label.sizePolicy().hasHeightForWidth())
+ self.target_list_label.setSizePolicy(sizePolicy1)
+ self.target_list_label.setFont(font)
+ self.target_list_label.setStyleSheet(u"background-color:rgb(27,49,70);\n"
+"color: #ffffff;")
+
+ self.target_list_verticalLayout.addWidget(self.target_list_label)
+
+ self.tableWidget = QTableWidget(self.gridWidget)
+ self.tableWidget.setObjectName(u"tableWidget")
+ self.tableWidget.setMaximumSize(QSize(700, 500))
+
+ self.target_list_verticalLayout.addWidget(self.tableWidget)
+
+
+ self.bottom_horizontalLayout.addLayout(self.target_list_verticalLayout)
+
+ self.value_verticalLayout = QVBoxLayout()
+ self.value_verticalLayout.setSpacing(0)
+ self.value_verticalLayout.setObjectName(u"value_verticalLayout")
+ self.value_label = QLabel(self.gridWidget)
+ self.value_label.setObjectName(u"value_label")
+ sizePolicy1.setHeightForWidth(self.value_label.sizePolicy().hasHeightForWidth())
+ self.value_label.setSizePolicy(sizePolicy1)
+ self.value_label.setFont(font)
+ self.value_label.setStyleSheet(u"background-color:rgb(27,49,70);\n"
+"color: #ffffff;")
+
+ self.value_verticalLayout.addWidget(self.value_label)
+
+ self.horizontalLayout = QHBoxLayout()
+ self.horizontalLayout.setSpacing(0)
+ self.horizontalLayout.setObjectName(u"horizontalLayout")
+ self.graph_verticalLayout = QVBoxLayout()
+ self.graph_verticalLayout.setSpacing(0)
+ self.graph_verticalLayout.setObjectName(u"graph_verticalLayout")
+
+ self.horizontalLayout.addLayout(self.graph_verticalLayout)
+
+ self.verticalLayout = QVBoxLayout()
+ self.verticalLayout.setSpacing(0)
+ self.verticalLayout.setObjectName(u"verticalLayout")
+ self.verticalLayout.setSizeConstraint(QLayout.SetMaximumSize)
+ self.label = QLabel(self.gridWidget)
+ self.label.setObjectName(u"label")
+
+ self.verticalLayout.addWidget(self.label)
+
+ self.red_checkBox = QCheckBox(self.gridWidget)
+ self.red_checkBox.setObjectName(u"red_checkBox")
+ sizePolicy4 = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Maximum)
+ sizePolicy4.setHorizontalStretch(0)
+ sizePolicy4.setVerticalStretch(0)
+ sizePolicy4.setHeightForWidth(self.red_checkBox.sizePolicy().hasHeightForWidth())
+ self.red_checkBox.setSizePolicy(sizePolicy4)
+ font2 = QFont()
+ font2.setFamilies([u"Noto Sans"])
+ font2.setBold(False)
+ self.red_checkBox.setFont(font2)
+ self.red_checkBox.setStyleSheet(u"\n"
+"color: #ffffff;")
+ self.red_checkBox.setChecked(True)
+
+ self.verticalLayout.addWidget(self.red_checkBox)
+
+ self.green_checkBox = QCheckBox(self.gridWidget)
+ self.green_checkBox.setObjectName(u"green_checkBox")
+ sizePolicy4.setHeightForWidth(self.green_checkBox.sizePolicy().hasHeightForWidth())
+ self.green_checkBox.setSizePolicy(sizePolicy4)
+ self.green_checkBox.setFont(font2)
+ self.green_checkBox.setStyleSheet(u"\n"
+"color: #ffffff;")
+ self.green_checkBox.setChecked(True)
+
+ self.verticalLayout.addWidget(self.green_checkBox)
+
+ self.blue_checkBox = QCheckBox(self.gridWidget)
+ self.blue_checkBox.setObjectName(u"blue_checkBox")
+ sizePolicy4.setHeightForWidth(self.blue_checkBox.sizePolicy().hasHeightForWidth())
+ self.blue_checkBox.setSizePolicy(sizePolicy4)
+ self.blue_checkBox.setFont(font2)
+ self.blue_checkBox.setStyleSheet(u"\n"
+"color: #ffffff;")
+ self.blue_checkBox.setChecked(True)
+
+ self.verticalLayout.addWidget(self.blue_checkBox)
+
+ self.label_2 = QLabel(self.gridWidget)
+ self.label_2.setObjectName(u"label_2")
+
+ self.verticalLayout.addWidget(self.label_2)
+
+
+ self.horizontalLayout.addLayout(self.verticalLayout)
+
+
+ self.value_verticalLayout.addLayout(self.horizontalLayout)
+
+
+ self.bottom_horizontalLayout.addLayout(self.value_verticalLayout)
+
+ self.etc_verticalLayout = QVBoxLayout()
+ self.etc_verticalLayout.setObjectName(u"etc_verticalLayout")
+ self.setting_label = QLabel(self.gridWidget)
+ self.setting_label.setObjectName(u"setting_label")
+ sizePolicy1.setHeightForWidth(self.setting_label.sizePolicy().hasHeightForWidth())
+ self.setting_label.setSizePolicy(sizePolicy1)
+ self.setting_label.setFont(font)
+ self.setting_label.setStyleSheet(u"background-color:rgb(27,49,70);\n"
+"color: #ffffff;")
+
+ self.etc_verticalLayout.addWidget(self.setting_label)
+
+ self.data_csv_horizontalLayout = QHBoxLayout()
+ self.data_csv_horizontalLayout.setSpacing(0)
+ self.data_csv_horizontalLayout.setObjectName(u"data_csv_horizontalLayout")
+ self.data_csv_path_label = QLabel(self.gridWidget)
+ self.data_csv_path_label.setObjectName(u"data_csv_path_label")
+ sizePolicy3.setHeightForWidth(self.data_csv_path_label.sizePolicy().hasHeightForWidth())
+ self.data_csv_path_label.setSizePolicy(sizePolicy3)
+ font3 = QFont()
+ font3.setFamilies([u"Noto Sans"])
+ font3.setPointSize(10)
+ self.data_csv_path_label.setFont(font3)
+ self.data_csv_path_label.setStyleSheet(u"background-color:rgb(27,49,70);\n"
+"color: #ffffff;")
+
+ self.data_csv_horizontalLayout.addWidget(self.data_csv_path_label)
+
+ self.data_csv_path_textBrowser = QTextBrowser(self.gridWidget)
+ self.data_csv_path_textBrowser.setObjectName(u"data_csv_path_textBrowser")
+ sizePolicy1.setHeightForWidth(self.data_csv_path_textBrowser.sizePolicy().hasHeightForWidth())
+ self.data_csv_path_textBrowser.setSizePolicy(sizePolicy1)
+ self.data_csv_path_textBrowser.setMaximumSize(QSize(16777215, 50))
+ self.data_csv_path_textBrowser.setStyleSheet(u"background-color: rgb(255, 255, 255);")
+
+ self.data_csv_horizontalLayout.addWidget(self.data_csv_path_textBrowser)
+
+ self.data_csv_path_button = QPushButton(self.gridWidget)
+ self.data_csv_path_button.setObjectName(u"data_csv_path_button")
+ sizePolicy1.setHeightForWidth(self.data_csv_path_button.sizePolicy().hasHeightForWidth())
+ self.data_csv_path_button.setSizePolicy(sizePolicy1)
+ self.data_csv_path_button.setMaximumSize(QSize(50, 50))
+ font4 = QFont()
+ font4.setFamilies([u"Arial"])
+ font4.setPointSize(17)
+ self.data_csv_path_button.setFont(font4)
+ self.data_csv_path_button.setStyleSheet(u"background-color:rgb(27,49,70);\n"
+"color: #ffffff;")
+
+ self.data_csv_horizontalLayout.addWidget(self.data_csv_path_button)
+
+
+ self.etc_verticalLayout.addLayout(self.data_csv_horizontalLayout)
+
+ self.target_csv_horizontalLayout = QHBoxLayout()
+ self.target_csv_horizontalLayout.setSpacing(0)
+ self.target_csv_horizontalLayout.setObjectName(u"target_csv_horizontalLayout")
+ self.target_csv_path_label = QLabel(self.gridWidget)
+ self.target_csv_path_label.setObjectName(u"target_csv_path_label")
+ sizePolicy3.setHeightForWidth(self.target_csv_path_label.sizePolicy().hasHeightForWidth())
+ self.target_csv_path_label.setSizePolicy(sizePolicy3)
+ self.target_csv_path_label.setFont(font3)
+ self.target_csv_path_label.setStyleSheet(u"background-color:rgb(27,49,70);\n"
+"color: #ffffff;")
+
+ self.target_csv_horizontalLayout.addWidget(self.target_csv_path_label)
+
+ self.target_csv_path_textBrowser = QTextBrowser(self.gridWidget)
+ self.target_csv_path_textBrowser.setObjectName(u"target_csv_path_textBrowser")
+ sizePolicy1.setHeightForWidth(self.target_csv_path_textBrowser.sizePolicy().hasHeightForWidth())
+ self.target_csv_path_textBrowser.setSizePolicy(sizePolicy1)
+ self.target_csv_path_textBrowser.setMaximumSize(QSize(16777215, 50))
+ self.target_csv_path_textBrowser.setStyleSheet(u"background-color: rgb(255, 255, 255);")
+
+ self.target_csv_horizontalLayout.addWidget(self.target_csv_path_textBrowser)
+
+ self.target_csv_path_button = QPushButton(self.gridWidget)
+ self.target_csv_path_button.setObjectName(u"target_csv_path_button")
+ sizePolicy1.setHeightForWidth(self.target_csv_path_button.sizePolicy().hasHeightForWidth())
+ self.target_csv_path_button.setSizePolicy(sizePolicy1)
+ self.target_csv_path_button.setMaximumSize(QSize(50, 50))
+ self.target_csv_path_button.setFont(font4)
+ self.target_csv_path_button.setStyleSheet(u"background-color:rgb(27,49,70);\n"
+"color: #ffffff;")
+
+ self.target_csv_horizontalLayout.addWidget(self.target_csv_path_button)
+
+
+ self.etc_verticalLayout.addLayout(self.target_csv_horizontalLayout)
+
+ self.image_save_horizontalLayout = QHBoxLayout()
+ self.image_save_horizontalLayout.setSpacing(0)
+ self.image_save_horizontalLayout.setObjectName(u"image_save_horizontalLayout")
+ self.image_save_path_label = QLabel(self.gridWidget)
+ self.image_save_path_label.setObjectName(u"image_save_path_label")
+ sizePolicy3.setHeightForWidth(self.image_save_path_label.sizePolicy().hasHeightForWidth())
+ self.image_save_path_label.setSizePolicy(sizePolicy3)
+ self.image_save_path_label.setFont(font3)
+ self.image_save_path_label.setStyleSheet(u"background-color:rgb(27,49,70);\n"
+"color: #ffffff;")
+
+ self.image_save_horizontalLayout.addWidget(self.image_save_path_label)
+
+ self.image_save_path_textBrowser = QTextBrowser(self.gridWidget)
+ self.image_save_path_textBrowser.setObjectName(u"image_save_path_textBrowser")
+ sizePolicy1.setHeightForWidth(self.image_save_path_textBrowser.sizePolicy().hasHeightForWidth())
+ self.image_save_path_textBrowser.setSizePolicy(sizePolicy1)
+ self.image_save_path_textBrowser.setMaximumSize(QSize(16777215, 50))
+ self.image_save_path_textBrowser.setStyleSheet(u"background-color: rgb(255, 255, 255);")
+
+ self.image_save_horizontalLayout.addWidget(self.image_save_path_textBrowser)
+
+ self.image_save_path_button = QPushButton(self.gridWidget)
+ self.image_save_path_button.setObjectName(u"image_save_path_button")
+ sizePolicy1.setHeightForWidth(self.image_save_path_button.sizePolicy().hasHeightForWidth())
+ self.image_save_path_button.setSizePolicy(sizePolicy1)
+ self.image_save_path_button.setMaximumSize(QSize(50, 50))
+ self.image_save_path_button.setFont(font4)
+ self.image_save_path_button.setStyleSheet(u"background-color:rgb(27,49,70);\n"
+"color: #ffffff;")
+
+ self.image_save_horizontalLayout.addWidget(self.image_save_path_button)
+
+
+ self.etc_verticalLayout.addLayout(self.image_save_horizontalLayout)
+
+ self.vis_limit_horizontalLayout_2 = QHBoxLayout()
+ self.vis_limit_horizontalLayout_2.setSpacing(6)
+ self.vis_limit_horizontalLayout_2.setObjectName(u"vis_limit_horizontalLayout_2")
+ self.vis_limit_label_2 = QLabel(self.gridWidget)
+ self.vis_limit_label_2.setObjectName(u"vis_limit_label_2")
+ sizePolicy3.setHeightForWidth(self.vis_limit_label_2.sizePolicy().hasHeightForWidth())
+ self.vis_limit_label_2.setSizePolicy(sizePolicy3)
+ self.vis_limit_label_2.setFont(font3)
+ self.vis_limit_label_2.setStyleSheet(u"background-color:rgb(27,49,70);\n"
+"color: #ffffff;")
+
+ self.vis_limit_horizontalLayout_2.addWidget(self.vis_limit_label_2)
+
+ self.image_size_comboBox = QComboBox(self.gridWidget)
+ self.image_size_comboBox.addItem("")
+ self.image_size_comboBox.addItem("")
+ self.image_size_comboBox.addItem("")
+ self.image_size_comboBox.setObjectName(u"image_size_comboBox")
+ self.image_size_comboBox.setStyleSheet(u"background-color: rgb(255, 255, 255);")
+
+ self.vis_limit_horizontalLayout_2.addWidget(self.image_size_comboBox)
+
+
+ self.etc_verticalLayout.addLayout(self.vis_limit_horizontalLayout_2)
+
+ self.vis_limit_horizontalLayout = QHBoxLayout()
+ self.vis_limit_horizontalLayout.setSpacing(6)
+ self.vis_limit_horizontalLayout.setObjectName(u"vis_limit_horizontalLayout")
+ self.vis_limit_label = QLabel(self.gridWidget)
+ self.vis_limit_label.setObjectName(u"vis_limit_label")
+ sizePolicy3.setHeightForWidth(self.vis_limit_label.sizePolicy().hasHeightForWidth())
+ self.vis_limit_label.setSizePolicy(sizePolicy3)
+ self.vis_limit_label.setFont(font3)
+ self.vis_limit_label.setStyleSheet(u"background-color:rgb(27,49,70);\n"
+"color: #ffffff;")
+
+ self.vis_limit_horizontalLayout.addWidget(self.vis_limit_label)
+
+ self.vis_limit_spinBox = QSpinBox(self.gridWidget)
+ self.vis_limit_spinBox.setObjectName(u"vis_limit_spinBox")
+ sizePolicy1.setHeightForWidth(self.vis_limit_spinBox.sizePolicy().hasHeightForWidth())
+ self.vis_limit_spinBox.setSizePolicy(sizePolicy1)
+ self.vis_limit_spinBox.setStyleSheet(u"background-color: rgb(255, 255, 255);")
+ self.vis_limit_spinBox.setMaximum(20000)
+ self.vis_limit_spinBox.setSingleStep(1)
+ self.vis_limit_spinBox.setDisplayIntegerBase(10)
+
+ self.vis_limit_horizontalLayout.addWidget(self.vis_limit_spinBox)
+
+
+ self.etc_verticalLayout.addLayout(self.vis_limit_horizontalLayout)
+
+ self.id_horizontalLayout = QHBoxLayout()
+ self.id_horizontalLayout.setSpacing(6)
+ self.id_horizontalLayout.setObjectName(u"id_horizontalLayout")
+ self.id_label = QLabel(self.gridWidget)
+ self.id_label.setObjectName(u"id_label")
+ sizePolicy3.setHeightForWidth(self.id_label.sizePolicy().hasHeightForWidth())
+ self.id_label.setSizePolicy(sizePolicy3)
+ self.id_label.setFont(font3)
+ self.id_label.setStyleSheet(u"background-color:rgb(27,49,70);\n"
+"color: #ffffff;")
+
+ self.id_horizontalLayout.addWidget(self.id_label)
+
+ self.id_lineEdit = QLineEdit(self.gridWidget)
+ self.id_lineEdit.setObjectName(u"id_lineEdit")
+ sizePolicy5 = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed)
+ sizePolicy5.setHorizontalStretch(0)
+ sizePolicy5.setVerticalStretch(0)
+ sizePolicy5.setHeightForWidth(self.id_lineEdit.sizePolicy().hasHeightForWidth())
+ self.id_lineEdit.setSizePolicy(sizePolicy5)
+ self.id_lineEdit.setStyleSheet(u"background-color: rgb(255, 255, 255);")
+
+ self.id_horizontalLayout.addWidget(self.id_lineEdit)
+
+
+ self.etc_verticalLayout.addLayout(self.id_horizontalLayout)
+
+ self.pw_horizontalLayout = QHBoxLayout()
+ self.pw_horizontalLayout.setSpacing(6)
+ self.pw_horizontalLayout.setObjectName(u"pw_horizontalLayout")
+ self.pw_label = QLabel(self.gridWidget)
+ self.pw_label.setObjectName(u"pw_label")
+ sizePolicy3.setHeightForWidth(self.pw_label.sizePolicy().hasHeightForWidth())
+ self.pw_label.setSizePolicy(sizePolicy3)
+ self.pw_label.setFont(font3)
+ self.pw_label.setStyleSheet(u"background-color:rgb(27,49,70);\n"
+"color: #ffffff;")
+
+ self.pw_horizontalLayout.addWidget(self.pw_label)
+
+ self.pw_lineEdit = QLineEdit(self.gridWidget)
+ self.pw_lineEdit.setObjectName(u"pw_lineEdit")
+ sizePolicy5.setHeightForWidth(self.pw_lineEdit.sizePolicy().hasHeightForWidth())
+ self.pw_lineEdit.setSizePolicy(sizePolicy5)
+ self.pw_lineEdit.setStyleSheet(u"background-color: rgb(255, 255, 255);")
+
+ self.pw_horizontalLayout.addWidget(self.pw_lineEdit)
+
+
+ self.etc_verticalLayout.addLayout(self.pw_horizontalLayout)
+
+ self.afd_horizontalLayout = QHBoxLayout()
+ self.afd_horizontalLayout.setSpacing(6)
+ self.afd_horizontalLayout.setObjectName(u"afd_horizontalLayout")
+ self.afd_label = QLabel(self.gridWidget)
+ self.afd_label.setObjectName(u"afd_label")
+ sizePolicy3.setHeightForWidth(self.afd_label.sizePolicy().hasHeightForWidth())
+ self.afd_label.setSizePolicy(sizePolicy3)
+ self.afd_label.setFont(font3)
+ self.afd_label.setStyleSheet(u"background-color:rgb(27,49,70);\n"
+"color: #ffffff;")
+
+ self.afd_horizontalLayout.addWidget(self.afd_label)
+
+ self.afd_checkBox = QCheckBox(self.gridWidget)
+ self.afd_checkBox.setObjectName(u"afd_checkBox")
+ sizePolicy5.setHeightForWidth(self.afd_checkBox.sizePolicy().hasHeightForWidth())
+ self.afd_checkBox.setSizePolicy(sizePolicy5)
+ self.afd_checkBox.setStyleSheet(u"QCheckBox::indicator { width: 40px; height: 40px; };")
+ self.afd_checkBox.setIconSize(QSize(16, 16))
+ self.afd_checkBox.setChecked(False)
+ self.afd_checkBox.setAutoRepeat(False)
+ self.afd_checkBox.setTristate(False)
+
+ self.afd_horizontalLayout.addWidget(self.afd_checkBox)
+
+
+ self.etc_verticalLayout.addLayout(self.afd_horizontalLayout)
+
+ self.buttonBox = QDialogButtonBox(self.gridWidget)
+ self.buttonBox.setObjectName(u"buttonBox")
+ sizePolicy4.setHeightForWidth(self.buttonBox.sizePolicy().hasHeightForWidth())
+ self.buttonBox.setSizePolicy(sizePolicy4)
+ font5 = QFont()
+ font5.setFamilies([u"Noto Sans"])
+ font5.setPointSize(9)
+ self.buttonBox.setFont(font5)
+ self.buttonBox.setStyleSheet(u"background-color:rgb(27,49,70);\n"
+"color: #ffffff;")
+ self.buttonBox.setOrientation(Qt.Horizontal)
+ self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel|QDialogButtonBox.Ok)
+ self.buttonBox.setCenterButtons(False)
+
+ self.etc_verticalLayout.addWidget(self.buttonBox)
+
+
+ self.bottom_horizontalLayout.addLayout(self.etc_verticalLayout)
+
+
+ self.main_verticalLayout.addLayout(self.bottom_horizontalLayout)
+
+
+ self.gridLayout_2.addLayout(self.main_verticalLayout, 0, 0, 1, 1)
+
+
+ self.gridLayout.addWidget(self.gridWidget, 0, 0, 1, 1)
+
+
+ self.retranslateUi(Dialog)
+
+ self.flip_button.setDefault(True)
+ self.image_size_comboBox.setCurrentIndex(0)
+
+
+ QMetaObject.connectSlotsByName(Dialog)
+ # setupUi
+
+ def retranslateUi(self, Dialog):
+ Dialog.setWindowTitle(QCoreApplication.translate("Dialog", u"Setting", None))
+ self.target_setting_label.setText(QCoreApplication.translate("Dialog", u" Front Target Setting", None))
+ self.flip_button.setText("")
+ self.image_label.setText("")
+ self.target_list_label.setText(QCoreApplication.translate("Dialog", u" Target list", None))
+ self.value_label.setText(QCoreApplication.translate("Dialog", u" ext \u03b1 Value", None))
+ self.label.setText("")
+ self.red_checkBox.setText(QCoreApplication.translate("Dialog", u"Red", None))
+ self.green_checkBox.setText(QCoreApplication.translate("Dialog", u"Green", None))
+ self.blue_checkBox.setText(QCoreApplication.translate("Dialog", u"Blue", None))
+ self.label_2.setText("")
+ self.setting_label.setText(QCoreApplication.translate("Dialog", u" Settings", None))
+ self.data_csv_path_label.setText(QCoreApplication.translate("Dialog", u" Data file Path: ", None))
+ self.data_csv_path_button.setText(QCoreApplication.translate("Dialog", u"\u21a9", None))
+ self.target_csv_path_label.setText(QCoreApplication.translate("Dialog", u" Target file Path: ", None))
+ self.target_csv_path_button.setText(QCoreApplication.translate("Dialog", u"\u21a9", None))
+ self.image_save_path_label.setText(QCoreApplication.translate("Dialog", u" Image save Path: ", None))
+ self.image_save_path_button.setText(QCoreApplication.translate("Dialog", u"\u21a9", None))
+ self.vis_limit_label_2.setText(QCoreApplication.translate("Dialog", u" Image size: ", None))
+ self.image_size_comboBox.setItemText(0, QCoreApplication.translate("Dialog", u"Original (PNG)", None))
+ self.image_size_comboBox.setItemText(1, QCoreApplication.translate("Dialog", u"Reduce (JPG)", None))
+ self.image_size_comboBox.setItemText(2, QCoreApplication.translate("Dialog", u"Resize to FHD (PNG)", None))
+
+ self.vis_limit_label.setText(QCoreApplication.translate("Dialog", u" Visibility alert limit: ", None))
+ self.vis_limit_spinBox.setSuffix(QCoreApplication.translate("Dialog", u" m", None))
+ self.vis_limit_spinBox.setPrefix("")
+ self.id_label.setText(QCoreApplication.translate("Dialog", u" ID: ", None))
+ self.pw_label.setText(QCoreApplication.translate("Dialog", u" P/W: ", None))
+ self.afd_label.setText(QCoreApplication.translate("Dialog", u" File delete: ", None))
+ self.afd_checkBox.setText("")
+ # retranslateUi
+
diff --git a/src/resources/settings.ui b/src/resources/setting_window.ui
similarity index 73%
rename from src/resources/settings.ui
rename to src/resources/setting_window.ui
index cd2102e..7f19d3f 100644
--- a/src/resources/settings.ui
+++ b/src/resources/setting_window.ui
@@ -6,8 +6,8 @@
0
0
- 1159
- 888
+ 1207
+ 767
@@ -95,6 +95,9 @@ color: #ffffff;
15
+
+ PointingHandCursor
+
border:0px;
background-color: #1b3146;
@@ -177,19 +180,13 @@ color: #ffffff;
-
-
-
+
+
- 0
- 250
+ 700
+ 500
-
- background-color:rgb(25,39,52);
-
-
-
-
@@ -223,20 +220,123 @@ color: #ffffff;
-
-
-
-
- 0
- 250
-
-
-
- background-color:rgb(25,39,52);
-
-
-
+
+
+ 0
-
+
-
+
+
+ 0
+
+
+
+ -
+
+
+ 0
+
+
+ QLayout::SetMaximumSize
+
+
-
+
+
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ Noto Sans
+ 50
+ false
+
+
+
+
+color: #ffffff;
+
+
+ Red
+
+
+ true
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ Noto Sans
+ 50
+ false
+
+
+
+
+color: #ffffff;
+
+
+ Green
+
+
+ true
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ Noto Sans
+ 50
+ false
+
+
+
+
+color: #ffffff;
+
+
+ Blue
+
+
+ true
+
+
+
+ -
+
+
+
+
+
+
+
+
+
@@ -273,7 +373,7 @@ color: #ffffff;
-
-
+
0
0
@@ -285,7 +385,7 @@ color: #ffffff;
-
+ background-color:rgb(27,49,70);
color: #ffffff;
@@ -326,6 +426,12 @@ color: #ffffff;
50
+
+
+ Arial
+ 17
+
+
background-color:rgb(27,49,70);
color: #ffffff;
@@ -345,7 +451,7 @@ color: #ffffff;
-
-
+
0
0
@@ -357,7 +463,7 @@ color: #ffffff;
-
+ background-color:rgb(27,49,70);
color: #ffffff;
@@ -398,6 +504,12 @@ color: #ffffff;
50
+
+
+ Arial
+ 17
+
+
background-color:rgb(27,49,70);
color: #ffffff;
@@ -417,7 +529,7 @@ color: #ffffff;
-
-
+
0
0
@@ -429,7 +541,7 @@ color: #ffffff;
-
+ background-color:rgb(27,49,70);
color: #ffffff;
@@ -470,6 +582,12 @@ color: #ffffff;
50
+
+
+ Arial
+ 17
+
+
background-color:rgb(27,49,70);
color: #ffffff;
@@ -484,12 +602,12 @@ color: #ffffff;
-
- 0
+ 6
-
-
+
0
0
@@ -501,7 +619,7 @@ color: #ffffff;
-
+ background-color:rgb(27,49,70);
color: #ffffff;
@@ -519,12 +637,17 @@ color: #ffffff;
-
- Original
+ Original (PNG)
+
+
+ -
+
+ Reduce (JPG)
-
- FHD
+ Resize to FHD (PNG)
@@ -534,12 +657,12 @@ color: #ffffff;
-
- 0
+ 6
-
-
+
0
0
@@ -551,7 +674,7 @@ color: #ffffff;
-
+ background-color:rgb(27,49,70);
color: #ffffff;
@@ -592,12 +715,12 @@ color: #ffffff;
-
- 0
+ 6
-
-
+
0
0
@@ -609,7 +732,7 @@ color: #ffffff;
-
+ background-color:rgb(27,49,70);
color: #ffffff;
@@ -635,12 +758,12 @@ color: #ffffff;
-
- 0
+ 6
-
-
+
0
0
@@ -652,7 +775,7 @@ color: #ffffff;
-
+ background-color:rgb(27,49,70);
color: #ffffff;
@@ -676,55 +799,65 @@ color: #ffffff;
-
-
-
-
- Noto Sans
- 10
-
-
-
- background-color:rgb(27,49,70);
-color: #ffffff;
-
-
- Other QSetting 1
-
-
-
- -
-
-
-
- Noto Sans
- 10
-
-
-
- background-color:rgb(27,49,70);
-color: #ffffff;
-
-
- Other QSetting 2
-
-
-
- -
-
-
-
- Noto Sans
- 10
-
+
+
+ 6
-
- background-color:rgb(27,49,70);
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ Noto Sans
+ 10
+
+
+
+ background-color:rgb(27,49,70);
color: #ffffff;
-
-
- Other QSetting 3
-
-
+
+
+ File delete:
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ QCheckBox::indicator { width: 40px; height: 40px; };
+
+
+
+
+
+
+ 16
+ 16
+
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+
+
-
@@ -748,7 +881,10 @@ color: #ffffff;
Qt::Horizontal
- QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Help|QDialogButtonBox::Ok
+ QDialogButtonBox::Cancel|QDialogButtonBox::Ok
+
+
+ false
diff --git a/src/resources/thumbnail_view.py b/src/resources/thumbnail_view.py
new file mode 100644
index 0000000..bcc2aca
--- /dev/null
+++ b/src/resources/thumbnail_view.py
@@ -0,0 +1,193 @@
+# -*- coding: utf-8 -*-
+
+################################################################################
+## Form generated from reading UI file 'thumbnail_view.ui'
+##
+## Created by: Qt User Interface Compiler version 6.3.0
+##
+## 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 (QAction, QBrush, QColor, QConicalGradient,
+ QCursor, QFont, QFontDatabase, QGradient,
+ QIcon, QImage, QKeySequence, QLinearGradient,
+ QPainter, QPalette, QPixmap, QRadialGradient,
+ QTransform)
+from PySide6.QtWidgets import (QApplication, QGridLayout, QHBoxLayout, QLabel,
+ QLayout, QMainWindow, QSizePolicy, QTabWidget,
+ QVBoxLayout, QWidget)
+
+class Ui_MainWindow(object):
+ def setupUi(self, MainWindow):
+ if not MainWindow.objectName():
+ MainWindow.setObjectName(u"MainWindow")
+ MainWindow.setEnabled(True)
+ MainWindow.resize(1035, 816)
+ sizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(MainWindow.sizePolicy().hasHeightForWidth())
+ MainWindow.setSizePolicy(sizePolicy)
+ MainWindow.setMinimumSize(QSize(400, 300))
+ font = QFont()
+ font.setFamilies([u"Noto Sans"])
+ font.setPointSize(9)
+ font.setBold(False)
+ font.setItalic(False)
+ MainWindow.setFont(font)
+ MainWindow.setMouseTracking(False)
+ MainWindow.setStyleSheet(u"background-color:rgb(22,32,42);\n"
+"border-color: rgb(255, 255, 255);")
+ MainWindow.setToolButtonStyle(Qt.ToolButtonIconOnly)
+ MainWindow.setTabShape(QTabWidget.Rounded)
+ MainWindow.setUnifiedTitleAndToolBarOnMac(True)
+ self.actionExit = QAction(MainWindow)
+ self.actionExit.setObjectName(u"actionExit")
+ self.actionsd = QAction(MainWindow)
+ self.actionsd.setObjectName(u"actionsd")
+ self.actionkm = QAction(MainWindow)
+ self.actionkm.setObjectName(u"actionkm")
+ self.actionkm.setCheckable(True)
+ self.actionkm.setEnabled(True)
+ self.actionmi = QAction(MainWindow)
+ self.actionmi.setObjectName(u"actionmi")
+ self.actionmi.setCheckable(True)
+ self.actionmi.setEnabled(True)
+ self.actionInference = QAction(MainWindow)
+ self.actionInference.setObjectName(u"actionInference")
+ self.actionInference.setCheckable(True)
+ self.actionInference.setChecked(False)
+ self.actionEdit_Target = QAction(MainWindow)
+ self.actionEdit_Target.setObjectName(u"actionEdit_Target")
+ self.actionEdit_Target.setCheckable(False)
+ self.actionEdit_Camera = QAction(MainWindow)
+ self.actionEdit_Camera.setObjectName(u"actionEdit_Camera")
+ self.actionEdit_Camera.setEnabled(True)
+ self.actionAbout = QAction(MainWindow)
+ self.actionAbout.setObjectName(u"actionAbout")
+ self.actionConfiguration = QAction(MainWindow)
+ self.actionConfiguration.setObjectName(u"actionConfiguration")
+ self.centralwidget = QWidget(MainWindow)
+ self.centralwidget.setObjectName(u"centralwidget")
+ self.centralwidget.setMaximumSize(QSize(16777215, 16777215))
+ self.centralwidget.setMouseTracking(False)
+ self.centralwidget.setStyleSheet(u"")
+ self.gridLayout = QGridLayout(self.centralwidget)
+ self.gridLayout.setSpacing(0)
+ self.gridLayout.setObjectName(u"gridLayout")
+ self.gridLayout.setContentsMargins(0, 0, 0, 0)
+ self.verticalLayout = QVBoxLayout()
+ self.verticalLayout.setSpacing(2)
+ self.verticalLayout.setObjectName(u"verticalLayout")
+ self.verticalLayout.setContentsMargins(0, 2, 0, 0)
+ self.label_horizontalLayout = QHBoxLayout()
+ self.label_horizontalLayout.setSpacing(2)
+ self.label_horizontalLayout.setObjectName(u"label_horizontalLayout")
+ self.label_horizontalLayout.setSizeConstraint(QLayout.SetDefaultConstraint)
+ self.front_label = QLabel(self.centralwidget)
+ self.front_label.setObjectName(u"front_label")
+ sizePolicy1 = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Maximum)
+ sizePolicy1.setHorizontalStretch(0)
+ sizePolicy1.setVerticalStretch(0)
+ sizePolicy1.setHeightForWidth(self.front_label.sizePolicy().hasHeightForWidth())
+ self.front_label.setSizePolicy(sizePolicy1)
+ font1 = QFont()
+ font1.setFamilies([u"Noto Sans"])
+ font1.setPointSize(17)
+ font1.setBold(False)
+ self.front_label.setFont(font1)
+ self.front_label.setStyleSheet(u"background-color:rgb(27,49,70);\n"
+"color: rgb(255, 255, 255);")
+ self.front_label.setAlignment(Qt.AlignCenter)
+
+ self.label_horizontalLayout.addWidget(self.front_label)
+
+ self.rear_label = QLabel(self.centralwidget)
+ self.rear_label.setObjectName(u"rear_label")
+ sizePolicy1.setHeightForWidth(self.rear_label.sizePolicy().hasHeightForWidth())
+ self.rear_label.setSizePolicy(sizePolicy1)
+ self.rear_label.setFont(font1)
+ self.rear_label.setStyleSheet(u"background-color:rgb(27,49,70);\n"
+"color: rgb(255, 255, 255);")
+ self.rear_label.setAlignment(Qt.AlignCenter)
+
+ self.label_horizontalLayout.addWidget(self.rear_label)
+
+
+ self.verticalLayout.addLayout(self.label_horizontalLayout)
+
+ self.image_horizontalLayout = QHBoxLayout()
+ self.image_horizontalLayout.setSpacing(2)
+ self.image_horizontalLayout.setObjectName(u"image_horizontalLayout")
+ self.front_image = QLabel(self.centralwidget)
+ self.front_image.setObjectName(u"front_image")
+ sizePolicy2 = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)
+ sizePolicy2.setHorizontalStretch(0)
+ sizePolicy2.setVerticalStretch(0)
+ sizePolicy2.setHeightForWidth(self.front_image.sizePolicy().hasHeightForWidth())
+ self.front_image.setSizePolicy(sizePolicy2)
+ font2 = QFont()
+ font2.setFamilies([u"Noto Sans"])
+ font2.setPointSize(20)
+ self.front_image.setFont(font2)
+ self.front_image.setStyleSheet(u"color: rgb(255, 255, 255);")
+ self.front_image.setAlignment(Qt.AlignCenter)
+
+ self.image_horizontalLayout.addWidget(self.front_image)
+
+ self.rear_image = QLabel(self.centralwidget)
+ self.rear_image.setObjectName(u"rear_image")
+ sizePolicy2.setHeightForWidth(self.rear_image.sizePolicy().hasHeightForWidth())
+ self.rear_image.setSizePolicy(sizePolicy2)
+ self.rear_image.setFont(font2)
+ self.rear_image.setStyleSheet(u"color: rgb(255, 255, 255);")
+ self.rear_image.setAlignment(Qt.AlignCenter)
+
+ self.image_horizontalLayout.addWidget(self.rear_image)
+
+
+ self.verticalLayout.addLayout(self.image_horizontalLayout)
+
+
+ self.gridLayout.addLayout(self.verticalLayout, 0, 0, 1, 1)
+
+ MainWindow.setCentralWidget(self.centralwidget)
+
+ self.retranslateUi(MainWindow)
+ self.actionExit.triggered.connect(MainWindow.close)
+
+ QMetaObject.connectSlotsByName(MainWindow)
+ # setupUi
+
+ def retranslateUi(self, MainWindow):
+ MainWindow.setWindowTitle(QCoreApplication.translate("MainWindow", u"JS-08", None))
+ self.actionExit.setText(QCoreApplication.translate("MainWindow", u"&Quit", None))
+#if QT_CONFIG(tooltip)
+ self.actionExit.setToolTip(QCoreApplication.translate("MainWindow", u"Exit", None))
+#endif // QT_CONFIG(tooltip)
+#if QT_CONFIG(statustip)
+ self.actionExit.setStatusTip(QCoreApplication.translate("MainWindow", u"Exit JS-06", None))
+#endif // QT_CONFIG(statustip)
+#if QT_CONFIG(shortcut)
+ self.actionExit.setShortcut(QCoreApplication.translate("MainWindow", u"Ctrl+W", None))
+#endif // QT_CONFIG(shortcut)
+ self.actionsd.setText(QCoreApplication.translate("MainWindow", u"sd", None))
+ self.actionkm.setText(QCoreApplication.translate("MainWindow", u"km", None))
+ self.actionmi.setText(QCoreApplication.translate("MainWindow", u"mi", None))
+ self.actionInference.setText(QCoreApplication.translate("MainWindow", u"Inference", None))
+#if QT_CONFIG(shortcut)
+ self.actionInference.setShortcut(QCoreApplication.translate("MainWindow", u"I", None))
+#endif // QT_CONFIG(shortcut)
+ self.actionEdit_Target.setText(QCoreApplication.translate("MainWindow", u"Edit &Target", None))
+ self.actionEdit_Camera.setText(QCoreApplication.translate("MainWindow", u"Edit &Camera Info", None))
+ self.actionAbout.setText(QCoreApplication.translate("MainWindow", u"About", None))
+ self.actionConfiguration.setText(QCoreApplication.translate("MainWindow", u"Con&figuration", None))
+ self.front_label.setText(QCoreApplication.translate("MainWindow", u"Front", None))
+ self.rear_label.setText(QCoreApplication.translate("MainWindow", u"Rear", None))
+ self.front_image.setText(QCoreApplication.translate("MainWindow", u"No file", None))
+ self.rear_image.setText(QCoreApplication.translate("MainWindow", u"No file", None))
+ # retranslateUi
+
diff --git a/src/resources/thumbnail_view.ui b/src/resources/thumbnail_view.ui
index f8c1849..5d87186 100644
--- a/src/resources/thumbnail_view.ui
+++ b/src/resources/thumbnail_view.ui
@@ -85,27 +85,27 @@ border-color: rgb(255, 255, 255);
-
- 0
+ 2
- 5
+ 0
- 5
+ 2
- 5
+ 0
- 5
+ 0
-
- 6
+ 2
- QLayout::SetMinimumSize
+ QLayout::SetDefaultConstraint
-
@@ -118,7 +118,9 @@ border-color: rgb(255, 255, 255);
Noto Sans
- 15
+ 17
+ 50
+ false
@@ -144,7 +146,9 @@ color: rgb(255, 255, 255);
Noto Sans
- 15
+ 17
+ 50
+ false
@@ -164,7 +168,7 @@ color: rgb(255, 255, 255);
-
- 6
+ 2
-
@@ -174,22 +178,17 @@ color: rgb(255, 255, 255);
0
-
-
- 952
- 362
-
-
- 30
+ Noto Sans
+ 20
color: rgb(255, 255, 255);
- <html><head/><body><p><br/></p></body></html>
+ No file
Qt::AlignCenter
@@ -204,22 +203,17 @@ color: rgb(255, 255, 255);
0
-
-
- 952
- 362
-
-
- 30
+ Noto Sans
+ 20
color: rgb(255, 255, 255);
- <html><head/><body><p><br/></p></body></html>
+ No file
Qt::AlignCenter
@@ -315,7 +309,7 @@ color: rgb(255, 255, 255);
-
+
diff --git a/src/resources/user_list.py b/src/resources/user_list.py
new file mode 100644
index 0000000..53047db
--- /dev/null
+++ b/src/resources/user_list.py
@@ -0,0 +1,130 @@
+# -*- coding: utf-8 -*-
+
+################################################################################
+## Form generated from reading UI file 'user_list.ui'
+##
+## Created by: Qt User Interface Compiler version 6.3.0
+##
+## 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, QDialog, QGridLayout, QHBoxLayout,
+ QLabel, QLayout, QLineEdit, QListWidget,
+ QListWidgetItem, QPushButton, QSizePolicy, QSpacerItem,
+ QVBoxLayout, QWidget)
+
+class Ui_Dialog(object):
+ def setupUi(self, Dialog):
+ if not Dialog.objectName():
+ Dialog.setObjectName(u"Dialog")
+ Dialog.resize(417, 310)
+ Dialog.setStyleSheet(u"")
+ self.gridLayout = QGridLayout(Dialog)
+ self.gridLayout.setObjectName(u"gridLayout")
+ self.horizontalLayout = QHBoxLayout()
+ self.horizontalLayout.setObjectName(u"horizontalLayout")
+ self.verticalLayout_3 = QVBoxLayout()
+ self.verticalLayout_3.setObjectName(u"verticalLayout_3")
+ self.listWidget = QListWidget(Dialog)
+ self.listWidget.setObjectName(u"listWidget")
+ font = QFont()
+ font.setFamilies([u"Noto Sans KR Medium"])
+ font.setPointSize(14)
+ self.listWidget.setFont(font)
+ self.listWidget.setStyleSheet(u"background-color:rgb(255, 255, 255);")
+
+ self.verticalLayout_3.addWidget(self.listWidget)
+
+ self.gridLayout_2 = QGridLayout()
+ self.gridLayout_2.setObjectName(u"gridLayout_2")
+ self.user_id = QLineEdit(Dialog)
+ self.user_id.setObjectName(u"user_id")
+ self.user_id.setStyleSheet(u"background-color:rgb(255, 255, 255);")
+
+ self.gridLayout_2.addWidget(self.user_id, 0, 0, 1, 1)
+
+ self.user_pw = QLineEdit(Dialog)
+ self.user_pw.setObjectName(u"user_pw")
+ self.user_pw.setStyleSheet(u"background-color:rgb(255, 255, 255);")
+
+ self.gridLayout_2.addWidget(self.user_pw, 0, 1, 1, 1)
+
+
+ self.verticalLayout_3.addLayout(self.gridLayout_2)
+
+
+ self.horizontalLayout.addLayout(self.verticalLayout_3)
+
+ self.verticalLayout_2 = QVBoxLayout()
+ self.verticalLayout_2.setSpacing(6)
+ self.verticalLayout_2.setObjectName(u"verticalLayout_2")
+ self.verticalLayout_2.setSizeConstraint(QLayout.SetDefaultConstraint)
+ self.add_button = QPushButton(Dialog)
+ self.add_button.setObjectName(u"add_button")
+ self.add_button.setStyleSheet(u"background-color:rgb(255, 255, 255);")
+
+ self.verticalLayout_2.addWidget(self.add_button)
+
+ self.delete_button = QPushButton(Dialog)
+ self.delete_button.setObjectName(u"delete_button")
+ self.delete_button.setStyleSheet(u"background-color:rgb(255, 255, 255);")
+
+ self.verticalLayout_2.addWidget(self.delete_button)
+
+ self.save_button = QPushButton(Dialog)
+ self.save_button.setObjectName(u"save_button")
+ self.save_button.setStyleSheet(u"background-color:rgb(255, 255, 255);")
+
+ self.verticalLayout_2.addWidget(self.save_button)
+
+ self.cancel_button = QPushButton(Dialog)
+ self.cancel_button.setObjectName(u"cancel_button")
+ self.cancel_button.setStyleSheet(u"background-color:rgb(255, 255, 255);")
+
+ self.verticalLayout_2.addWidget(self.cancel_button)
+
+ self.verticalSpacer = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding)
+
+ self.verticalLayout_2.addItem(self.verticalSpacer)
+
+ self.info = QLabel(Dialog)
+ self.info.setObjectName(u"info")
+ font1 = QFont()
+ font1.setFamilies([u"Noto Sans KR Medium"])
+ font1.setPointSize(10)
+ self.info.setFont(font1)
+ self.info.setStyleSheet(u"color:rgb(22,32,42);")
+ self.info.setAlignment(Qt.AlignCenter)
+
+ self.verticalLayout_2.addWidget(self.info)
+
+
+ self.horizontalLayout.addLayout(self.verticalLayout_2)
+
+
+ self.gridLayout.addLayout(self.horizontalLayout, 0, 0, 1, 1)
+
+
+ self.retranslateUi(Dialog)
+
+ QMetaObject.connectSlotsByName(Dialog)
+ # setupUi
+
+ def retranslateUi(self, Dialog):
+ Dialog.setWindowTitle(QCoreApplication.translate("Dialog", u"User List", None))
+ self.user_id.setPlaceholderText(QCoreApplication.translate("Dialog", u"User ID", None))
+ self.user_pw.setPlaceholderText(QCoreApplication.translate("Dialog", u"User Password", None))
+ self.add_button.setText(QCoreApplication.translate("Dialog", u"\ucd94\uac00", None))
+ self.delete_button.setText(QCoreApplication.translate("Dialog", u"\uc0ad\uc81c", None))
+ self.save_button.setText(QCoreApplication.translate("Dialog", u"\uc800\uc7a5", None))
+ self.cancel_button.setText(QCoreApplication.translate("Dialog", u"\ucde8\uc18c", None))
+ self.info.setText(QCoreApplication.translate("Dialog", u"\uc0ac\uc6a9\uc790 \ucd94\uac00", None))
+ # retranslateUi
+
diff --git a/src/resources/user_list.ui b/src/resources/user_list.ui
new file mode 100644
index 0000000..4fc12c2
--- /dev/null
+++ b/src/resources/user_list.ui
@@ -0,0 +1,154 @@
+
+
+ Dialog
+
+
+
+ 0
+ 0
+ 417
+ 310
+
+
+
+ User List
+
+
+
+
+
+ -
+
+
-
+
+
-
+
+
+
+ Noto Sans KR Medium
+ 14
+
+
+
+ background-color:rgb(255, 255, 255);
+
+
+
+ -
+
+
-
+
+
+ background-color:rgb(255, 255, 255);
+
+
+ User ID
+
+
+
+ -
+
+
+ background-color:rgb(255, 255, 255);
+
+
+ User Password
+
+
+
+
+
+
+
+ -
+
+
+ 6
+
+
+ QLayout::SetDefaultConstraint
+
+
-
+
+
+ background-color:rgb(255, 255, 255);
+
+
+ 추가
+
+
+
+ -
+
+
+ background-color:rgb(255, 255, 255);
+
+
+ 삭제
+
+
+
+ -
+
+
+ background-color:rgb(255, 255, 255);
+
+
+ 저장
+
+
+
+ -
+
+
+ background-color:rgb(255, 255, 255);
+
+
+ 취소
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+ QSizePolicy::Expanding
+
+
+
+ 20
+ 40
+
+
+
+
+ -
+
+
+
+ Noto Sans KR Medium
+ 10
+
+
+
+ color:rgb(22,32,42);
+
+
+ 사용자 추가
+
+
+ Qt::AlignCenter
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/resources/user_menu.py b/src/resources/user_menu.py
new file mode 100644
index 0000000..03c3d1d
--- /dev/null
+++ b/src/resources/user_menu.py
@@ -0,0 +1,430 @@
+# -*- coding: utf-8 -*-
+
+################################################################################
+## Form generated from reading UI file 'user_menu.ui'
+##
+## Created by: Qt User Interface Compiler version 6.3.0
+##
+## 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 (QAbstractButton, QApplication, QComboBox, QDialog,
+ QDialogButtonBox, QGridLayout, QHBoxLayout, QLabel,
+ QLineEdit, QPushButton, QSizePolicy, QSpinBox,
+ QTextBrowser, QVBoxLayout, QWidget)
+
+class Ui_Dialog(object):
+ def setupUi(self, Dialog):
+ if not Dialog.objectName():
+ Dialog.setObjectName(u"Dialog")
+ Dialog.resize(421, 517)
+ sizePolicy = QSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(Dialog.sizePolicy().hasHeightForWidth())
+ Dialog.setSizePolicy(sizePolicy)
+ self.gridLayout = QGridLayout(Dialog)
+ self.gridLayout.setSpacing(0)
+ self.gridLayout.setObjectName(u"gridLayout")
+ self.gridLayout.setContentsMargins(0, 0, 0, 0)
+ self.gridWidget = QWidget(Dialog)
+ self.gridWidget.setObjectName(u"gridWidget")
+ sizePolicy1 = QSizePolicy(QSizePolicy.Maximum, QSizePolicy.Minimum)
+ sizePolicy1.setHorizontalStretch(0)
+ sizePolicy1.setVerticalStretch(0)
+ sizePolicy1.setHeightForWidth(self.gridWidget.sizePolicy().hasHeightForWidth())
+ self.gridWidget.setSizePolicy(sizePolicy1)
+ self.gridWidget.setStyleSheet(u"background-color:rgb(22,32,42);")
+ self.gridLayout_2 = QGridLayout(self.gridWidget)
+ self.gridLayout_2.setObjectName(u"gridLayout_2")
+ self.etc_verticalLayout = QVBoxLayout()
+ self.etc_verticalLayout.setObjectName(u"etc_verticalLayout")
+ self.setting_label = QLabel(self.gridWidget)
+ self.setting_label.setObjectName(u"setting_label")
+ sizePolicy2 = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Maximum)
+ sizePolicy2.setHorizontalStretch(0)
+ sizePolicy2.setVerticalStretch(0)
+ sizePolicy2.setHeightForWidth(self.setting_label.sizePolicy().hasHeightForWidth())
+ self.setting_label.setSizePolicy(sizePolicy2)
+ font = QFont()
+ font.setFamilies([u"Noto Sans"])
+ font.setPointSize(23)
+ self.setting_label.setFont(font)
+ self.setting_label.setStyleSheet(u"background-color:rgb(27,49,70);\n"
+"color: #ffffff;")
+
+ self.etc_verticalLayout.addWidget(self.setting_label)
+
+ self.data_csv_horizontalLayout = QHBoxLayout()
+ self.data_csv_horizontalLayout.setSpacing(0)
+ self.data_csv_horizontalLayout.setObjectName(u"data_csv_horizontalLayout")
+ self.data_csv_path_label = QLabel(self.gridWidget)
+ self.data_csv_path_label.setObjectName(u"data_csv_path_label")
+ sizePolicy3 = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)
+ sizePolicy3.setHorizontalStretch(0)
+ sizePolicy3.setVerticalStretch(0)
+ sizePolicy3.setHeightForWidth(self.data_csv_path_label.sizePolicy().hasHeightForWidth())
+ self.data_csv_path_label.setSizePolicy(sizePolicy3)
+ self.data_csv_path_label.setMinimumSize(QSize(0, 50))
+ font1 = QFont()
+ font1.setFamilies([u"Noto Sans KR Medium"])
+ font1.setPointSize(10)
+ self.data_csv_path_label.setFont(font1)
+ self.data_csv_path_label.setStyleSheet(u"background-color:rgb(27,49,70);\n"
+"color: #ffffff;")
+
+ self.data_csv_horizontalLayout.addWidget(self.data_csv_path_label)
+
+ self.data_csv_path_textBrowser = QTextBrowser(self.gridWidget)
+ self.data_csv_path_textBrowser.setObjectName(u"data_csv_path_textBrowser")
+ sizePolicy3.setHeightForWidth(self.data_csv_path_textBrowser.sizePolicy().hasHeightForWidth())
+ self.data_csv_path_textBrowser.setSizePolicy(sizePolicy3)
+ self.data_csv_path_textBrowser.setMinimumSize(QSize(0, 50))
+ self.data_csv_path_textBrowser.setMaximumSize(QSize(16777215, 50))
+ self.data_csv_path_textBrowser.setStyleSheet(u"background-color: rgb(255, 255, 255);")
+
+ self.data_csv_horizontalLayout.addWidget(self.data_csv_path_textBrowser)
+
+ self.data_csv_path_button = QPushButton(self.gridWidget)
+ self.data_csv_path_button.setObjectName(u"data_csv_path_button")
+ sizePolicy3.setHeightForWidth(self.data_csv_path_button.sizePolicy().hasHeightForWidth())
+ self.data_csv_path_button.setSizePolicy(sizePolicy3)
+ self.data_csv_path_button.setMinimumSize(QSize(0, 50))
+ self.data_csv_path_button.setMaximumSize(QSize(50, 50))
+ font2 = QFont()
+ font2.setFamilies([u"Arial"])
+ font2.setPointSize(17)
+ self.data_csv_path_button.setFont(font2)
+ self.data_csv_path_button.setStyleSheet(u"background-color:rgb(27,49,70);\n"
+"color: #ffffff;")
+
+ self.data_csv_horizontalLayout.addWidget(self.data_csv_path_button)
+
+
+ self.etc_verticalLayout.addLayout(self.data_csv_horizontalLayout)
+
+ self.target_csv_horizontalLayout = QHBoxLayout()
+ self.target_csv_horizontalLayout.setSpacing(0)
+ self.target_csv_horizontalLayout.setObjectName(u"target_csv_horizontalLayout")
+ self.target_csv_path_label = QLabel(self.gridWidget)
+ self.target_csv_path_label.setObjectName(u"target_csv_path_label")
+ sizePolicy3.setHeightForWidth(self.target_csv_path_label.sizePolicy().hasHeightForWidth())
+ self.target_csv_path_label.setSizePolicy(sizePolicy3)
+ self.target_csv_path_label.setMinimumSize(QSize(0, 50))
+ self.target_csv_path_label.setFont(font1)
+ self.target_csv_path_label.setStyleSheet(u"background-color:rgb(27,49,70);\n"
+"color: #ffffff;")
+
+ self.target_csv_horizontalLayout.addWidget(self.target_csv_path_label)
+
+ self.target_csv_path_textBrowser = QTextBrowser(self.gridWidget)
+ self.target_csv_path_textBrowser.setObjectName(u"target_csv_path_textBrowser")
+ sizePolicy3.setHeightForWidth(self.target_csv_path_textBrowser.sizePolicy().hasHeightForWidth())
+ self.target_csv_path_textBrowser.setSizePolicy(sizePolicy3)
+ self.target_csv_path_textBrowser.setMinimumSize(QSize(0, 50))
+ self.target_csv_path_textBrowser.setMaximumSize(QSize(16777215, 50))
+ self.target_csv_path_textBrowser.setStyleSheet(u"background-color: rgb(255, 255, 255);")
+
+ self.target_csv_horizontalLayout.addWidget(self.target_csv_path_textBrowser)
+
+ self.target_csv_path_button = QPushButton(self.gridWidget)
+ self.target_csv_path_button.setObjectName(u"target_csv_path_button")
+ sizePolicy3.setHeightForWidth(self.target_csv_path_button.sizePolicy().hasHeightForWidth())
+ self.target_csv_path_button.setSizePolicy(sizePolicy3)
+ self.target_csv_path_button.setMinimumSize(QSize(0, 50))
+ self.target_csv_path_button.setMaximumSize(QSize(50, 50))
+ self.target_csv_path_button.setFont(font2)
+ self.target_csv_path_button.setStyleSheet(u"background-color:rgb(27,49,70);\n"
+"color: #ffffff;")
+
+ self.target_csv_horizontalLayout.addWidget(self.target_csv_path_button)
+
+
+ self.etc_verticalLayout.addLayout(self.target_csv_horizontalLayout)
+
+ self.image_save_horizontalLayout = QHBoxLayout()
+ self.image_save_horizontalLayout.setSpacing(0)
+ self.image_save_horizontalLayout.setObjectName(u"image_save_horizontalLayout")
+ self.image_save_path_label = QLabel(self.gridWidget)
+ self.image_save_path_label.setObjectName(u"image_save_path_label")
+ sizePolicy3.setHeightForWidth(self.image_save_path_label.sizePolicy().hasHeightForWidth())
+ self.image_save_path_label.setSizePolicy(sizePolicy3)
+ self.image_save_path_label.setMinimumSize(QSize(0, 50))
+ self.image_save_path_label.setFont(font1)
+ self.image_save_path_label.setStyleSheet(u"background-color:rgb(27,49,70);\n"
+"color: #ffffff;")
+
+ self.image_save_horizontalLayout.addWidget(self.image_save_path_label)
+
+ self.image_save_path_textBrowser = QTextBrowser(self.gridWidget)
+ self.image_save_path_textBrowser.setObjectName(u"image_save_path_textBrowser")
+ sizePolicy3.setHeightForWidth(self.image_save_path_textBrowser.sizePolicy().hasHeightForWidth())
+ self.image_save_path_textBrowser.setSizePolicy(sizePolicy3)
+ self.image_save_path_textBrowser.setMinimumSize(QSize(0, 50))
+ self.image_save_path_textBrowser.setMaximumSize(QSize(16777215, 50))
+ self.image_save_path_textBrowser.setStyleSheet(u"background-color: rgb(255, 255, 255);")
+
+ self.image_save_horizontalLayout.addWidget(self.image_save_path_textBrowser)
+
+ self.image_save_path_button = QPushButton(self.gridWidget)
+ self.image_save_path_button.setObjectName(u"image_save_path_button")
+ sizePolicy3.setHeightForWidth(self.image_save_path_button.sizePolicy().hasHeightForWidth())
+ self.image_save_path_button.setSizePolicy(sizePolicy3)
+ self.image_save_path_button.setMinimumSize(QSize(0, 50))
+ self.image_save_path_button.setMaximumSize(QSize(50, 50))
+ self.image_save_path_button.setFont(font2)
+ self.image_save_path_button.setStyleSheet(u"background-color:rgb(27,49,70);\n"
+"color: #ffffff;")
+
+ self.image_save_horizontalLayout.addWidget(self.image_save_path_button)
+
+
+ self.etc_verticalLayout.addLayout(self.image_save_horizontalLayout)
+
+ self.vis_limit_horizontalLayout_2 = QHBoxLayout()
+ self.vis_limit_horizontalLayout_2.setSpacing(6)
+ self.vis_limit_horizontalLayout_2.setObjectName(u"vis_limit_horizontalLayout_2")
+ self.vis_limit_label_2 = QLabel(self.gridWidget)
+ self.vis_limit_label_2.setObjectName(u"vis_limit_label_2")
+ sizePolicy3.setHeightForWidth(self.vis_limit_label_2.sizePolicy().hasHeightForWidth())
+ self.vis_limit_label_2.setSizePolicy(sizePolicy3)
+ self.vis_limit_label_2.setMinimumSize(QSize(0, 34))
+ self.vis_limit_label_2.setFont(font1)
+ self.vis_limit_label_2.setStyleSheet(u"background-color:rgb(27,49,70);\n"
+"color: #ffffff;")
+
+ self.vis_limit_horizontalLayout_2.addWidget(self.vis_limit_label_2)
+
+ self.image_size_comboBox = QComboBox(self.gridWidget)
+ self.image_size_comboBox.addItem("")
+ self.image_size_comboBox.addItem("")
+ self.image_size_comboBox.addItem("")
+ self.image_size_comboBox.setObjectName(u"image_size_comboBox")
+ sizePolicy4 = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Minimum)
+ sizePolicy4.setHorizontalStretch(0)
+ sizePolicy4.setVerticalStretch(0)
+ sizePolicy4.setHeightForWidth(self.image_size_comboBox.sizePolicy().hasHeightForWidth())
+ self.image_size_comboBox.setSizePolicy(sizePolicy4)
+ self.image_size_comboBox.setMinimumSize(QSize(0, 34))
+ self.image_size_comboBox.setStyleSheet(u"background-color: rgb(255, 255, 255);")
+
+ self.vis_limit_horizontalLayout_2.addWidget(self.image_size_comboBox)
+
+
+ self.etc_verticalLayout.addLayout(self.vis_limit_horizontalLayout_2)
+
+ self.vis_limit_horizontalLayout = QHBoxLayout()
+ self.vis_limit_horizontalLayout.setSpacing(6)
+ self.vis_limit_horizontalLayout.setObjectName(u"vis_limit_horizontalLayout")
+ self.vis_limit_label = QLabel(self.gridWidget)
+ self.vis_limit_label.setObjectName(u"vis_limit_label")
+ sizePolicy3.setHeightForWidth(self.vis_limit_label.sizePolicy().hasHeightForWidth())
+ self.vis_limit_label.setSizePolicy(sizePolicy3)
+ self.vis_limit_label.setMinimumSize(QSize(0, 34))
+ self.vis_limit_label.setFont(font1)
+ self.vis_limit_label.setStyleSheet(u"background-color:rgb(27,49,70);\n"
+"color: #ffffff;")
+
+ self.vis_limit_horizontalLayout.addWidget(self.vis_limit_label)
+
+ self.vis_limit_spinBox = QSpinBox(self.gridWidget)
+ self.vis_limit_spinBox.setObjectName(u"vis_limit_spinBox")
+ sizePolicy3.setHeightForWidth(self.vis_limit_spinBox.sizePolicy().hasHeightForWidth())
+ self.vis_limit_spinBox.setSizePolicy(sizePolicy3)
+ self.vis_limit_spinBox.setMinimumSize(QSize(0, 34))
+ self.vis_limit_spinBox.setStyleSheet(u"background-color: rgb(255, 255, 255);")
+ self.vis_limit_spinBox.setMaximum(20000)
+ self.vis_limit_spinBox.setSingleStep(1)
+ self.vis_limit_spinBox.setDisplayIntegerBase(10)
+
+ self.vis_limit_horizontalLayout.addWidget(self.vis_limit_spinBox)
+
+
+ self.etc_verticalLayout.addLayout(self.vis_limit_horizontalLayout)
+
+ self.id_horizontalLayout = QHBoxLayout()
+ self.id_horizontalLayout.setSpacing(6)
+ self.id_horizontalLayout.setObjectName(u"id_horizontalLayout")
+ self.id_label = QLabel(self.gridWidget)
+ self.id_label.setObjectName(u"id_label")
+ sizePolicy3.setHeightForWidth(self.id_label.sizePolicy().hasHeightForWidth())
+ self.id_label.setSizePolicy(sizePolicy3)
+ self.id_label.setMinimumSize(QSize(0, 34))
+ font3 = QFont()
+ font3.setFamilies([u"Noto Sans"])
+ font3.setPointSize(10)
+ self.id_label.setFont(font3)
+ self.id_label.setStyleSheet(u"background-color:rgb(27,49,70);\n"
+"color: #ffffff;")
+
+ self.id_horizontalLayout.addWidget(self.id_label)
+
+ self.id_lineEdit = QTextBrowser(self.gridWidget)
+ self.id_lineEdit.setObjectName(u"id_lineEdit")
+ sizePolicy3.setHeightForWidth(self.id_lineEdit.sizePolicy().hasHeightForWidth())
+ self.id_lineEdit.setSizePolicy(sizePolicy3)
+ self.id_lineEdit.setMinimumSize(QSize(0, 34))
+ self.id_lineEdit.setMaximumSize(QSize(196, 34))
+ self.id_lineEdit.setStyleSheet(u"background-color: rgb(255, 255, 255);")
+
+ self.id_horizontalLayout.addWidget(self.id_lineEdit)
+
+
+ self.etc_verticalLayout.addLayout(self.id_horizontalLayout)
+
+ self.pw_horizontalLayout_3 = QHBoxLayout()
+ self.pw_horizontalLayout_3.setSpacing(6)
+ self.pw_horizontalLayout_3.setObjectName(u"pw_horizontalLayout_3")
+ self.pw_label_3 = QLabel(self.gridWidget)
+ self.pw_label_3.setObjectName(u"pw_label_3")
+ sizePolicy3.setHeightForWidth(self.pw_label_3.sizePolicy().hasHeightForWidth())
+ self.pw_label_3.setSizePolicy(sizePolicy3)
+ self.pw_label_3.setMinimumSize(QSize(0, 34))
+ self.pw_label_3.setFont(font1)
+ self.pw_label_3.setStyleSheet(u"background-color:rgb(27,49,70);\n"
+"color: #ffffff;")
+
+ self.pw_horizontalLayout_3.addWidget(self.pw_label_3)
+
+ self.current_pw = QLineEdit(self.gridWidget)
+ self.current_pw.setObjectName(u"current_pw")
+ sizePolicy3.setHeightForWidth(self.current_pw.sizePolicy().hasHeightForWidth())
+ self.current_pw.setSizePolicy(sizePolicy3)
+ self.current_pw.setMinimumSize(QSize(0, 34))
+ self.current_pw.setStyleSheet(u"background-color: rgb(255, 255, 255);")
+
+ self.pw_horizontalLayout_3.addWidget(self.current_pw)
+
+
+ self.etc_verticalLayout.addLayout(self.pw_horizontalLayout_3)
+
+ self.pw_horizontalLayout = QHBoxLayout()
+ self.pw_horizontalLayout.setSpacing(6)
+ self.pw_horizontalLayout.setObjectName(u"pw_horizontalLayout")
+ self.pw_label = QLabel(self.gridWidget)
+ self.pw_label.setObjectName(u"pw_label")
+ sizePolicy3.setHeightForWidth(self.pw_label.sizePolicy().hasHeightForWidth())
+ self.pw_label.setSizePolicy(sizePolicy3)
+ self.pw_label.setMinimumSize(QSize(0, 34))
+ self.pw_label.setFont(font1)
+ self.pw_label.setStyleSheet(u"background-color:rgb(27,49,70);\n"
+"color: #ffffff;")
+
+ self.pw_horizontalLayout.addWidget(self.pw_label)
+
+ self.new_pw = QLineEdit(self.gridWidget)
+ self.new_pw.setObjectName(u"new_pw")
+ sizePolicy3.setHeightForWidth(self.new_pw.sizePolicy().hasHeightForWidth())
+ self.new_pw.setSizePolicy(sizePolicy3)
+ self.new_pw.setMinimumSize(QSize(0, 34))
+ self.new_pw.setStyleSheet(u"background-color: rgb(255, 255, 255);")
+
+ self.pw_horizontalLayout.addWidget(self.new_pw)
+
+
+ self.etc_verticalLayout.addLayout(self.pw_horizontalLayout)
+
+ self.pw_horizontalLayout_4 = QHBoxLayout()
+ self.pw_horizontalLayout_4.setSpacing(6)
+ self.pw_horizontalLayout_4.setObjectName(u"pw_horizontalLayout_4")
+ self.pw_label_4 = QLabel(self.gridWidget)
+ self.pw_label_4.setObjectName(u"pw_label_4")
+ sizePolicy3.setHeightForWidth(self.pw_label_4.sizePolicy().hasHeightForWidth())
+ self.pw_label_4.setSizePolicy(sizePolicy3)
+ self.pw_label_4.setMinimumSize(QSize(0, 34))
+ self.pw_label_4.setFont(font1)
+ self.pw_label_4.setStyleSheet(u"background-color:rgb(27,49,70);\n"
+"color: #ffffff;")
+
+ self.pw_horizontalLayout_4.addWidget(self.pw_label_4)
+
+ self.new_pw_check = QLineEdit(self.gridWidget)
+ self.new_pw_check.setObjectName(u"new_pw_check")
+ sizePolicy3.setHeightForWidth(self.new_pw_check.sizePolicy().hasHeightForWidth())
+ self.new_pw_check.setSizePolicy(sizePolicy3)
+ self.new_pw_check.setMinimumSize(QSize(0, 34))
+ self.new_pw_check.setStyleSheet(u"background-color: rgb(255, 255, 255);")
+
+ self.pw_horizontalLayout_4.addWidget(self.new_pw_check)
+
+
+ self.etc_verticalLayout.addLayout(self.pw_horizontalLayout_4)
+
+ self.horizontalLayout = QHBoxLayout()
+ self.horizontalLayout.setObjectName(u"horizontalLayout")
+ self.buttonBox = QDialogButtonBox(self.gridWidget)
+ self.buttonBox.setObjectName(u"buttonBox")
+ sizePolicy5 = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Maximum)
+ sizePolicy5.setHorizontalStretch(0)
+ sizePolicy5.setVerticalStretch(0)
+ sizePolicy5.setHeightForWidth(self.buttonBox.sizePolicy().hasHeightForWidth())
+ self.buttonBox.setSizePolicy(sizePolicy5)
+ font4 = QFont()
+ font4.setFamilies([u"Noto Sans KR Medium"])
+ font4.setPointSize(9)
+ self.buttonBox.setFont(font4)
+ self.buttonBox.setStyleSheet(u"background-color:rgb(27,49,70);\n"
+"color: #ffffff;")
+ self.buttonBox.setOrientation(Qt.Horizontal)
+ self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel|QDialogButtonBox.Ok)
+ self.buttonBox.setCenterButtons(False)
+
+ self.horizontalLayout.addWidget(self.buttonBox)
+
+ self.info = QLabel(self.gridWidget)
+ self.info.setObjectName(u"info")
+ self.info.setFont(font1)
+ self.info.setStyleSheet(u"color: rgb(255, 0, 0);")
+ self.info.setAlignment(Qt.AlignCenter)
+
+ self.horizontalLayout.addWidget(self.info)
+
+
+ self.etc_verticalLayout.addLayout(self.horizontalLayout)
+
+
+ self.gridLayout_2.addLayout(self.etc_verticalLayout, 0, 0, 1, 1)
+
+
+ self.gridLayout.addWidget(self.gridWidget, 0, 0, 1, 1)
+
+
+ self.retranslateUi(Dialog)
+
+ self.image_size_comboBox.setCurrentIndex(0)
+
+
+ QMetaObject.connectSlotsByName(Dialog)
+ # setupUi
+
+ def retranslateUi(self, Dialog):
+ Dialog.setWindowTitle(QCoreApplication.translate("Dialog", u"Setting", None))
+ self.setting_label.setText(QCoreApplication.translate("Dialog", u" Settings", None))
+ self.data_csv_path_label.setText(QCoreApplication.translate("Dialog", u" \ub370\uc774\ud130 \ud30c\uc77c \uacbd\ub85c", None))
+ self.data_csv_path_button.setText(QCoreApplication.translate("Dialog", u"\u21a9", None))
+ self.target_csv_path_label.setText(QCoreApplication.translate("Dialog", u" \ud0c0\uac9f \ud30c\uc77c \uacbd\ub85c", None))
+ self.target_csv_path_button.setText(QCoreApplication.translate("Dialog", u"\u21a9", None))
+ self.image_save_path_label.setText(QCoreApplication.translate("Dialog", u" \uc774\ubbf8\uc9c0 \uc800\uc7a5 \uacbd\ub85c", None))
+ self.image_save_path_button.setText(QCoreApplication.translate("Dialog", u"\u21a9", None))
+ self.vis_limit_label_2.setText(QCoreApplication.translate("Dialog", u" \uc774\ubbf8\uc9c0 \ud06c\uae30 \uc9c0\uc815 ", None))
+ self.image_size_comboBox.setItemText(0, QCoreApplication.translate("Dialog", u"Original (PNG)", None))
+ self.image_size_comboBox.setItemText(1, QCoreApplication.translate("Dialog", u"Reduce (JPG)", None))
+ self.image_size_comboBox.setItemText(2, QCoreApplication.translate("Dialog", u"Resize to FHD (PNG)", None))
+
+ self.vis_limit_label.setText(QCoreApplication.translate("Dialog", u" \ucd5c\uc800 \uc2dc\uc815 \uc54c\ub9bc \uae30\uc900", None))
+ self.vis_limit_spinBox.setSuffix(QCoreApplication.translate("Dialog", u" m", None))
+ self.vis_limit_spinBox.setPrefix("")
+ self.id_label.setText(QCoreApplication.translate("Dialog", u" ID", None))
+ self.pw_label_3.setText(QCoreApplication.translate("Dialog", u" \ud604\uc7ac \ube44\ubc00\ubc88\ud638", None))
+ self.pw_label.setText(QCoreApplication.translate("Dialog", u" \uc0c8 \ube44\ubc00\ubc88\ud638", None))
+ self.pw_label_4.setText(QCoreApplication.translate("Dialog", u" \uc0c8 \ube44\ubc00\ubc88\ud638 \ud655\uc778", None))
+ self.info.setText("")
+ # retranslateUi
+
diff --git a/src/resources/user_menu.ui b/src/resources/user_menu.ui
new file mode 100644
index 0000000..18cc708
--- /dev/null
+++ b/src/resources/user_menu.ui
@@ -0,0 +1,793 @@
+
+
+ Dialog
+
+
+
+ 0
+ 0
+ 421
+ 517
+
+
+
+
+ 0
+ 0
+
+
+
+ Setting
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ background-color:rgb(22,32,42);
+
+
+
-
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ Noto Sans
+ 23
+
+
+
+ background-color:rgb(27,49,70);
+color: #ffffff;
+
+
+ Settings
+
+
+
+ -
+
+
+ 0
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 50
+
+
+
+
+ Noto Sans KR Medium
+ 10
+
+
+
+ background-color:rgb(27,49,70);
+color: #ffffff;
+
+
+ 데이터 파일 경로
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 50
+
+
+
+
+ 16777215
+ 50
+
+
+
+ background-color: rgb(255, 255, 255);
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 50
+
+
+
+
+ 50
+ 50
+
+
+
+
+ Arial
+ 17
+
+
+
+ background-color:rgb(27,49,70);
+color: #ffffff;
+
+
+ ↩
+
+
+
+
+
+ -
+
+
+ 0
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 50
+
+
+
+
+ Noto Sans KR Medium
+ 10
+
+
+
+ background-color:rgb(27,49,70);
+color: #ffffff;
+
+
+ 타겟 파일 경로
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 50
+
+
+
+
+ 16777215
+ 50
+
+
+
+ background-color: rgb(255, 255, 255);
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 50
+
+
+
+
+ 50
+ 50
+
+
+
+
+ Arial
+ 17
+
+
+
+ background-color:rgb(27,49,70);
+color: #ffffff;
+
+
+ ↩
+
+
+
+
+
+ -
+
+
+ 0
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 50
+
+
+
+
+ Noto Sans KR Medium
+ 10
+
+
+
+ background-color:rgb(27,49,70);
+color: #ffffff;
+
+
+ 이미지 저장 경로
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 50
+
+
+
+
+ 16777215
+ 50
+
+
+
+ background-color: rgb(255, 255, 255);
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 50
+
+
+
+
+ 50
+ 50
+
+
+
+
+ Arial
+ 17
+
+
+
+ background-color:rgb(27,49,70);
+color: #ffffff;
+
+
+ ↩
+
+
+
+
+
+ -
+
+
+ 6
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 34
+
+
+
+
+ Noto Sans KR Medium
+ 10
+
+
+
+ background-color:rgb(27,49,70);
+color: #ffffff;
+
+
+ 이미지 크기 지정
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 34
+
+
+
+ background-color: rgb(255, 255, 255);
+
+
+ 0
+
+
-
+
+ Original (PNG)
+
+
+ -
+
+ Reduce (JPG)
+
+
+ -
+
+ Resize to FHD (PNG)
+
+
+
+
+
+
+ -
+
+
+ 6
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 34
+
+
+
+
+ Noto Sans KR Medium
+ 10
+
+
+
+ background-color:rgb(27,49,70);
+color: #ffffff;
+
+
+ 최저 시정 알림 기준
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 34
+
+
+
+ background-color: rgb(255, 255, 255);
+
+
+ m
+
+
+
+
+
+ 20000
+
+
+ 1
+
+
+ 10
+
+
+
+
+
+ -
+
+
+ 6
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 34
+
+
+
+
+ Noto Sans
+ 10
+
+
+
+ background-color:rgb(27,49,70);
+color: #ffffff;
+
+
+ ID
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 34
+
+
+
+
+ 196
+ 34
+
+
+
+ background-color: rgb(255, 255, 255);
+
+
+
+
+
+ -
+
+
+ 6
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 34
+
+
+
+
+ Noto Sans KR Medium
+ 10
+
+
+
+ background-color:rgb(27,49,70);
+color: #ffffff;
+
+
+ 현재 비밀번호
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 34
+
+
+
+ background-color: rgb(255, 255, 255);
+
+
+
+
+
+ -
+
+
+ 6
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 34
+
+
+
+
+ Noto Sans KR Medium
+ 10
+
+
+
+ background-color:rgb(27,49,70);
+color: #ffffff;
+
+
+ 새 비밀번호
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 34
+
+
+
+ background-color: rgb(255, 255, 255);
+
+
+
+
+
+ -
+
+
+ 6
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 34
+
+
+
+
+ Noto Sans KR Medium
+ 10
+
+
+
+ background-color:rgb(27,49,70);
+color: #ffffff;
+
+
+ 새 비밀번호 확인
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 34
+
+
+
+ background-color: rgb(255, 255, 255);
+
+
+
+
+
+ -
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ Noto Sans KR Medium
+ 9
+
+
+
+ background-color:rgb(27,49,70);
+color: #ffffff;
+
+
+ Qt::Horizontal
+
+
+ QDialogButtonBox::Cancel|QDialogButtonBox::Ok
+
+
+ false
+
+
+
+ -
+
+
+
+ Noto Sans KR Medium
+ 10
+
+
+
+ color: rgb(255, 0, 0);
+
+
+
+
+
+ Qt::AlignCenter
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/resources/visibility_test.py b/src/resources/visibility_test.py
new file mode 100644
index 0000000..3b68ae0
--- /dev/null
+++ b/src/resources/visibility_test.py
@@ -0,0 +1,389 @@
+# -*- coding: utf-8 -*-
+
+################################################################################
+## Form generated from reading UI file 'visibility_test.ui'
+##
+## Created by: Qt User Interface Compiler version 6.3.0
+##
+## 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 (QAbstractButton, QApplication, QDialog, QDialogButtonBox,
+ QGridLayout, QHBoxLayout, QHeaderView, QLabel,
+ QPushButton, QSizePolicy, QTableWidget, QTableWidgetItem,
+ QVBoxLayout, QWidget)
+
+class Ui_Dialog(object):
+ def setupUi(self, Dialog):
+ if not Dialog.objectName():
+ Dialog.setObjectName(u"Dialog")
+ Dialog.resize(1926, 846)
+ sizePolicy = QSizePolicy(QSizePolicy.Maximum, QSizePolicy.Preferred)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(Dialog.sizePolicy().hasHeightForWidth())
+ Dialog.setSizePolicy(sizePolicy)
+ self.gridLayout = QGridLayout(Dialog)
+ self.gridLayout.setSpacing(0)
+ self.gridLayout.setObjectName(u"gridLayout")
+ self.gridLayout.setContentsMargins(0, 0, 0, 0)
+ self.gridWidget = QWidget(Dialog)
+ self.gridWidget.setObjectName(u"gridWidget")
+ self.gridWidget.setStyleSheet(u"background-color:rgb(22,32,42);")
+ self.gridLayout_2 = QGridLayout(self.gridWidget)
+ self.gridLayout_2.setObjectName(u"gridLayout_2")
+ self.main_verticalLayout = QVBoxLayout()
+ self.main_verticalLayout.setObjectName(u"main_verticalLayout")
+ self.top_horizontalLayout = QHBoxLayout()
+ self.top_horizontalLayout.setObjectName(u"top_horizontalLayout")
+ self.setting_verticalLayout = QVBoxLayout()
+ self.setting_verticalLayout.setObjectName(u"setting_verticalLayout")
+ self.setting_horizontalLayout = QHBoxLayout()
+ self.setting_horizontalLayout.setSpacing(0)
+ self.setting_horizontalLayout.setObjectName(u"setting_horizontalLayout")
+ self.target_setting_label = QLabel(self.gridWidget)
+ self.target_setting_label.setObjectName(u"target_setting_label")
+ sizePolicy1 = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Maximum)
+ sizePolicy1.setHorizontalStretch(0)
+ sizePolicy1.setVerticalStretch(0)
+ sizePolicy1.setHeightForWidth(self.target_setting_label.sizePolicy().hasHeightForWidth())
+ self.target_setting_label.setSizePolicy(sizePolicy1)
+ font = QFont()
+ font.setFamilies([u"Noto Sans KR Medium"])
+ font.setPointSize(23)
+ self.target_setting_label.setFont(font)
+ self.target_setting_label.setStyleSheet(u"background-color:rgb(27,49,70);\n"
+"color: #ffffff;")
+
+ self.setting_horizontalLayout.addWidget(self.target_setting_label)
+
+ self.load_img = QPushButton(self.gridWidget)
+ self.load_img.setObjectName(u"load_img")
+ sizePolicy2 = QSizePolicy(QSizePolicy.Maximum, QSizePolicy.Minimum)
+ sizePolicy2.setHorizontalStretch(0)
+ sizePolicy2.setVerticalStretch(0)
+ sizePolicy2.setHeightForWidth(self.load_img.sizePolicy().hasHeightForWidth())
+ self.load_img.setSizePolicy(sizePolicy2)
+ self.load_img.setMaximumSize(QSize(16777215, 45))
+ font1 = QFont()
+ font1.setFamilies([u"Noto Sans KR Medium"])
+ self.load_img.setFont(font1)
+ self.load_img.setStyleSheet(u"background-color:rgb(255, 255, 255);")
+
+ self.setting_horizontalLayout.addWidget(self.load_img)
+
+
+ self.setting_verticalLayout.addLayout(self.setting_horizontalLayout)
+
+ self.image_label = QLabel(self.gridWidget)
+ self.image_label.setObjectName(u"image_label")
+ sizePolicy3 = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)
+ sizePolicy3.setHorizontalStretch(0)
+ sizePolicy3.setVerticalStretch(0)
+ sizePolicy3.setHeightForWidth(self.image_label.sizePolicy().hasHeightForWidth())
+ self.image_label.setSizePolicy(sizePolicy3)
+ self.image_label.setMinimumSize(QSize(1902, 464))
+ self.image_label.setMaximumSize(QSize(16777215, 16777215))
+
+ self.setting_verticalLayout.addWidget(self.image_label)
+
+
+ self.top_horizontalLayout.addLayout(self.setting_verticalLayout)
+
+
+ self.main_verticalLayout.addLayout(self.top_horizontalLayout)
+
+ self.bottom_horizontalLayout = QHBoxLayout()
+ self.bottom_horizontalLayout.setSpacing(12)
+ self.bottom_horizontalLayout.setObjectName(u"bottom_horizontalLayout")
+ self.target_list_verticalLayout = QVBoxLayout()
+ self.target_list_verticalLayout.setSpacing(0)
+ self.target_list_verticalLayout.setObjectName(u"target_list_verticalLayout")
+ self.target_list_verticalLayout.setContentsMargins(6, -1, -1, -1)
+ self.target_list_label = QLabel(self.gridWidget)
+ self.target_list_label.setObjectName(u"target_list_label")
+ sizePolicy1.setHeightForWidth(self.target_list_label.sizePolicy().hasHeightForWidth())
+ self.target_list_label.setSizePolicy(sizePolicy1)
+ self.target_list_label.setFont(font)
+ self.target_list_label.setStyleSheet(u"background-color:rgb(27,49,70);\n"
+"color: #ffffff;")
+
+ self.target_list_verticalLayout.addWidget(self.target_list_label)
+
+ self.tableWidget = QTableWidget(self.gridWidget)
+ self.tableWidget.setObjectName(u"tableWidget")
+ self.tableWidget.setMaximumSize(QSize(700, 500))
+
+ self.target_list_verticalLayout.addWidget(self.tableWidget)
+
+
+ self.bottom_horizontalLayout.addLayout(self.target_list_verticalLayout)
+
+ self.value_verticalLayout = QVBoxLayout()
+ self.value_verticalLayout.setSpacing(0)
+ self.value_verticalLayout.setObjectName(u"value_verticalLayout")
+ self.value_label = QLabel(self.gridWidget)
+ self.value_label.setObjectName(u"value_label")
+ sizePolicy1.setHeightForWidth(self.value_label.sizePolicy().hasHeightForWidth())
+ self.value_label.setSizePolicy(sizePolicy1)
+ self.value_label.setFont(font)
+ self.value_label.setStyleSheet(u"background-color:rgb(27,49,70);\n"
+"color: #ffffff;")
+
+ self.value_verticalLayout.addWidget(self.value_label)
+
+ self.gridLayout_3 = QGridLayout()
+ self.gridLayout_3.setObjectName(u"gridLayout_3")
+
+ self.value_verticalLayout.addLayout(self.gridLayout_3)
+
+
+ self.bottom_horizontalLayout.addLayout(self.value_verticalLayout)
+
+ self.etc_verticalLayout = QVBoxLayout()
+ self.etc_verticalLayout.setSpacing(3)
+ self.etc_verticalLayout.setObjectName(u"etc_verticalLayout")
+ self.setting_label = QLabel(self.gridWidget)
+ self.setting_label.setObjectName(u"setting_label")
+ sizePolicy1.setHeightForWidth(self.setting_label.sizePolicy().hasHeightForWidth())
+ self.setting_label.setSizePolicy(sizePolicy1)
+ self.setting_label.setFont(font)
+ self.setting_label.setStyleSheet(u"background-color:rgb(27,49,70);\n"
+"color: #ffffff;")
+
+ self.etc_verticalLayout.addWidget(self.setting_label)
+
+ self.afd_horizontalLayout = QHBoxLayout()
+ self.afd_horizontalLayout.setSpacing(6)
+ self.afd_horizontalLayout.setObjectName(u"afd_horizontalLayout")
+ self.vis_label = QLabel(self.gridWidget)
+ self.vis_label.setObjectName(u"vis_label")
+ sizePolicy4 = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum)
+ sizePolicy4.setHorizontalStretch(0)
+ sizePolicy4.setVerticalStretch(0)
+ sizePolicy4.setHeightForWidth(self.vis_label.sizePolicy().hasHeightForWidth())
+ self.vis_label.setSizePolicy(sizePolicy4)
+ font2 = QFont()
+ font2.setFamilies([u"Noto Sans KR Medium"])
+ font2.setPointSize(25)
+ self.vis_label.setFont(font2)
+ self.vis_label.setStyleSheet(u"background-color:rgb(27,49,70);\n"
+"color: #ffffff;")
+ self.vis_label.setAlignment(Qt.AlignCenter)
+
+ self.afd_horizontalLayout.addWidget(self.vis_label)
+
+ self.vis_btn = QPushButton(self.gridWidget)
+ self.vis_btn.setObjectName(u"vis_btn")
+ sizePolicy4.setHeightForWidth(self.vis_btn.sizePolicy().hasHeightForWidth())
+ self.vis_btn.setSizePolicy(sizePolicy4)
+ self.vis_btn.setFont(font2)
+ self.vis_btn.setStyleSheet(u"background-color:rgb(255, 255, 255);")
+
+ self.afd_horizontalLayout.addWidget(self.vis_btn)
+
+
+ self.etc_verticalLayout.addLayout(self.afd_horizontalLayout)
+
+ self.horizontalLayout = QHBoxLayout()
+ self.horizontalLayout.setObjectName(u"horizontalLayout")
+ self.verticalLayout = QVBoxLayout()
+ self.verticalLayout.setSpacing(2)
+ self.verticalLayout.setObjectName(u"verticalLayout")
+ self.first_vis_2 = QLabel(self.gridWidget)
+ self.first_vis_2.setObjectName(u"first_vis_2")
+ sizePolicy3.setHeightForWidth(self.first_vis_2.sizePolicy().hasHeightForWidth())
+ self.first_vis_2.setSizePolicy(sizePolicy3)
+ self.first_vis_2.setFont(font2)
+ self.first_vis_2.setStyleSheet(u"background-color:rgb(27,49,70);\n"
+"color: #ffffff;")
+ self.first_vis_2.setAlignment(Qt.AlignCenter)
+
+ self.verticalLayout.addWidget(self.first_vis_2)
+
+ self.first_vis = QLabel(self.gridWidget)
+ self.first_vis.setObjectName(u"first_vis")
+ sizePolicy5 = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Expanding)
+ sizePolicy5.setHorizontalStretch(0)
+ sizePolicy5.setVerticalStretch(0)
+ sizePolicy5.setHeightForWidth(self.first_vis.sizePolicy().hasHeightForWidth())
+ self.first_vis.setSizePolicy(sizePolicy5)
+ self.first_vis.setFont(font2)
+ self.first_vis.setStyleSheet(u"background-color:rgb(27,49,70);\n"
+"color: #ffffff;")
+ self.first_vis.setAlignment(Qt.AlignCenter)
+
+ self.verticalLayout.addWidget(self.first_vis)
+
+
+ self.horizontalLayout.addLayout(self.verticalLayout)
+
+ self.verticalLayout_2 = QVBoxLayout()
+ self.verticalLayout_2.setSpacing(2)
+ self.verticalLayout_2.setObjectName(u"verticalLayout_2")
+ self.second_vis_2 = QLabel(self.gridWidget)
+ self.second_vis_2.setObjectName(u"second_vis_2")
+ sizePolicy3.setHeightForWidth(self.second_vis_2.sizePolicy().hasHeightForWidth())
+ self.second_vis_2.setSizePolicy(sizePolicy3)
+ self.second_vis_2.setFont(font2)
+ self.second_vis_2.setStyleSheet(u"background-color:rgb(27,49,70);\n"
+"color: #ffffff;")
+ self.second_vis_2.setAlignment(Qt.AlignCenter)
+
+ self.verticalLayout_2.addWidget(self.second_vis_2)
+
+ self.second_vis = QLabel(self.gridWidget)
+ self.second_vis.setObjectName(u"second_vis")
+ sizePolicy5.setHeightForWidth(self.second_vis.sizePolicy().hasHeightForWidth())
+ self.second_vis.setSizePolicy(sizePolicy5)
+ self.second_vis.setFont(font2)
+ self.second_vis.setStyleSheet(u"background-color:rgb(27,49,70);\n"
+"color: #ffffff;")
+ self.second_vis.setAlignment(Qt.AlignCenter)
+
+ self.verticalLayout_2.addWidget(self.second_vis)
+
+
+ self.horizontalLayout.addLayout(self.verticalLayout_2)
+
+ self.verticalLayout_3 = QVBoxLayout()
+ self.verticalLayout_3.setSpacing(2)
+ self.verticalLayout_3.setObjectName(u"verticalLayout_3")
+ self.third_vis_2 = QLabel(self.gridWidget)
+ self.third_vis_2.setObjectName(u"third_vis_2")
+ sizePolicy3.setHeightForWidth(self.third_vis_2.sizePolicy().hasHeightForWidth())
+ self.third_vis_2.setSizePolicy(sizePolicy3)
+ self.third_vis_2.setFont(font2)
+ self.third_vis_2.setStyleSheet(u"background-color:rgb(27,49,70);\n"
+"color: #ffffff;")
+ self.third_vis_2.setAlignment(Qt.AlignCenter)
+
+ self.verticalLayout_3.addWidget(self.third_vis_2)
+
+ self.third_vis = QLabel(self.gridWidget)
+ self.third_vis.setObjectName(u"third_vis")
+ sizePolicy5.setHeightForWidth(self.third_vis.sizePolicy().hasHeightForWidth())
+ self.third_vis.setSizePolicy(sizePolicy5)
+ self.third_vis.setFont(font2)
+ self.third_vis.setStyleSheet(u"background-color:rgb(27,49,70);\n"
+"color: #ffffff;")
+ self.third_vis.setAlignment(Qt.AlignCenter)
+
+ self.verticalLayout_3.addWidget(self.third_vis)
+
+
+ self.horizontalLayout.addLayout(self.verticalLayout_3)
+
+ self.verticalLayout_4 = QVBoxLayout()
+ self.verticalLayout_4.setSpacing(2)
+ self.verticalLayout_4.setObjectName(u"verticalLayout_4")
+ self.fourth_vis_2 = QLabel(self.gridWidget)
+ self.fourth_vis_2.setObjectName(u"fourth_vis_2")
+ sizePolicy3.setHeightForWidth(self.fourth_vis_2.sizePolicy().hasHeightForWidth())
+ self.fourth_vis_2.setSizePolicy(sizePolicy3)
+ self.fourth_vis_2.setFont(font2)
+ self.fourth_vis_2.setStyleSheet(u"background-color:rgb(27,49,70);\n"
+"color: #ffffff;")
+ self.fourth_vis_2.setAlignment(Qt.AlignCenter)
+
+ self.verticalLayout_4.addWidget(self.fourth_vis_2)
+
+ self.fourth_vis = QLabel(self.gridWidget)
+ self.fourth_vis.setObjectName(u"fourth_vis")
+ sizePolicy5.setHeightForWidth(self.fourth_vis.sizePolicy().hasHeightForWidth())
+ self.fourth_vis.setSizePolicy(sizePolicy5)
+ self.fourth_vis.setFont(font2)
+ self.fourth_vis.setStyleSheet(u"background-color:rgb(27,49,70);\n"
+"color: #ffffff;")
+ self.fourth_vis.setAlignment(Qt.AlignCenter)
+
+ self.verticalLayout_4.addWidget(self.fourth_vis)
+
+
+ self.horizontalLayout.addLayout(self.verticalLayout_4)
+
+
+ self.etc_verticalLayout.addLayout(self.horizontalLayout)
+
+ self.vis_result = QLabel(self.gridWidget)
+ self.vis_result.setObjectName(u"vis_result")
+ sizePolicy6 = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
+ sizePolicy6.setHorizontalStretch(0)
+ sizePolicy6.setVerticalStretch(0)
+ sizePolicy6.setHeightForWidth(self.vis_result.sizePolicy().hasHeightForWidth())
+ self.vis_result.setSizePolicy(sizePolicy6)
+ font3 = QFont()
+ font3.setFamilies([u"Noto Sans KR Medium"])
+ font3.setPointSize(50)
+ self.vis_result.setFont(font3)
+ self.vis_result.setStyleSheet(u"background-color:rgb(27,49,70);\n"
+"color: #ffffff;")
+ self.vis_result.setAlignment(Qt.AlignCenter)
+
+ self.etc_verticalLayout.addWidget(self.vis_result)
+
+ self.buttonBox = QDialogButtonBox(self.gridWidget)
+ self.buttonBox.setObjectName(u"buttonBox")
+ sizePolicy7 = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Maximum)
+ sizePolicy7.setHorizontalStretch(0)
+ sizePolicy7.setVerticalStretch(0)
+ sizePolicy7.setHeightForWidth(self.buttonBox.sizePolicy().hasHeightForWidth())
+ self.buttonBox.setSizePolicy(sizePolicy7)
+ font4 = QFont()
+ font4.setFamilies([u"Noto Sans"])
+ font4.setPointSize(9)
+ self.buttonBox.setFont(font4)
+ self.buttonBox.setStyleSheet(u"background-color:rgb(27,49,70);\n"
+"color: #ffffff;")
+ self.buttonBox.setOrientation(Qt.Horizontal)
+ self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel|QDialogButtonBox.Ok)
+ self.buttonBox.setCenterButtons(False)
+
+ self.etc_verticalLayout.addWidget(self.buttonBox)
+
+
+ self.bottom_horizontalLayout.addLayout(self.etc_verticalLayout)
+
+
+ self.main_verticalLayout.addLayout(self.bottom_horizontalLayout)
+
+
+ self.gridLayout_2.addLayout(self.main_verticalLayout, 0, 0, 1, 1)
+
+
+ self.gridLayout.addWidget(self.gridWidget, 0, 0, 1, 1)
+
+
+ self.retranslateUi(Dialog)
+
+ QMetaObject.connectSlotsByName(Dialog)
+ # setupUi
+
+ def retranslateUi(self, Dialog):
+ Dialog.setWindowTitle(QCoreApplication.translate("Dialog", u"Setting", None))
+ self.target_setting_label.setText(QCoreApplication.translate("Dialog", u" \ud0c0\uac9f \uc138\ud305", None))
+ self.load_img.setText(QCoreApplication.translate("Dialog", u"\uc774\ubbf8\uc9c0 \ubd88\ub7ec\uc624\uae30", None))
+ self.image_label.setText("")
+ self.target_list_label.setText(QCoreApplication.translate("Dialog", u" \ud0c0\uac9f \ub9ac\uc2a4\ud2b8", None))
+ self.value_label.setText(QCoreApplication.translate("Dialog", u" \u03b1 \uadf8\ub798\ud504", None))
+ self.setting_label.setText(QCoreApplication.translate("Dialog", u" \uac00\uc2dc\uac70\ub9ac \ucd9c\ub825", None))
+ self.vis_label.setText(QCoreApplication.translate("Dialog", u"\uac00\uc2dc\uac70\ub9ac", None))
+ self.vis_btn.setText(QCoreApplication.translate("Dialog", u"\ucd9c\ub825", None))
+ self.first_vis_2.setText(QCoreApplication.translate("Dialog", u"NE", None))
+ self.first_vis.setText(QCoreApplication.translate("Dialog", u"- km", None))
+ self.second_vis_2.setText(QCoreApplication.translate("Dialog", u"EN", None))
+ self.second_vis.setText(QCoreApplication.translate("Dialog", u"- km", None))
+ self.third_vis_2.setText(QCoreApplication.translate("Dialog", u"ES", None))
+ self.third_vis.setText(QCoreApplication.translate("Dialog", u"- km", None))
+ self.fourth_vis_2.setText(QCoreApplication.translate("Dialog", u"SE", None))
+ self.fourth_vis.setText(QCoreApplication.translate("Dialog", u"- km", None))
+ self.vis_result.setText(QCoreApplication.translate("Dialog", u"- km", None))
+ # retranslateUi
+
diff --git a/src/resources/visibility_test.ui b/src/resources/visibility_test.ui
new file mode 100644
index 0000000..9a497cc
--- /dev/null
+++ b/src/resources/visibility_test.ui
@@ -0,0 +1,608 @@
+
+
+ Dialog
+
+
+
+ 0
+ 0
+ 1926
+ 846
+
+
+
+
+ 0
+ 0
+
+
+
+ Setting
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+ -
+
+
+ background-color:rgb(22,32,42);
+
+
+
-
+
+
-
+
+
-
+
+
-
+
+
+ 0
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ Noto Sans KR Medium
+ 23
+
+
+
+ background-color:rgb(27,49,70);
+color: #ffffff;
+
+
+ 타겟 세팅
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 16777215
+ 45
+
+
+
+
+ Noto Sans KR Medium
+
+
+
+ background-color:rgb(255, 255, 255);
+
+
+ 이미지 불러오기
+
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 1902
+ 464
+
+
+
+
+ 16777215
+ 16777215
+
+
+
+
+
+
+
+
+
+
+
+ -
+
+
+ 12
+
+
-
+
+
+ 0
+
+
+ 6
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ Noto Sans KR Medium
+ 23
+
+
+
+ background-color:rgb(27,49,70);
+color: #ffffff;
+
+
+ 타겟 리스트
+
+
+
+ -
+
+
+
+ 700
+ 500
+
+
+
+
+
+
+ -
+
+
+ 0
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ Noto Sans KR Medium
+ 23
+
+
+
+ background-color:rgb(27,49,70);
+color: #ffffff;
+
+
+ α 그래프
+
+
+
+ -
+
+
+
+
+ -
+
+
+ 3
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ Noto Sans KR Medium
+ 23
+
+
+
+ background-color:rgb(27,49,70);
+color: #ffffff;
+
+
+ 가시거리 출력
+
+
+
+ -
+
+
+ 6
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ Noto Sans KR Medium
+ 25
+
+
+
+ background-color:rgb(27,49,70);
+color: #ffffff;
+
+
+ 가시거리
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ Noto Sans KR Medium
+ 25
+
+
+
+ background-color:rgb(255, 255, 255);
+
+
+ 출력
+
+
+
+
+
+ -
+
+
-
+
+
+ 2
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ Noto Sans KR Medium
+ 25
+
+
+
+ background-color:rgb(27,49,70);
+color: #ffffff;
+
+
+ NE
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ Noto Sans KR Medium
+ 25
+
+
+
+ background-color:rgb(27,49,70);
+color: #ffffff;
+
+
+ - km
+
+
+ Qt::AlignCenter
+
+
+
+
+
+ -
+
+
+ 2
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ Noto Sans KR Medium
+ 25
+
+
+
+ background-color:rgb(27,49,70);
+color: #ffffff;
+
+
+ EN
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ Noto Sans KR Medium
+ 25
+
+
+
+ background-color:rgb(27,49,70);
+color: #ffffff;
+
+
+ - km
+
+
+ Qt::AlignCenter
+
+
+
+
+
+ -
+
+
+ 2
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ Noto Sans KR Medium
+ 25
+
+
+
+ background-color:rgb(27,49,70);
+color: #ffffff;
+
+
+ ES
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ Noto Sans KR Medium
+ 25
+
+
+
+ background-color:rgb(27,49,70);
+color: #ffffff;
+
+
+ - km
+
+
+ Qt::AlignCenter
+
+
+
+
+
+ -
+
+
+ 2
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ Noto Sans KR Medium
+ 25
+
+
+
+ background-color:rgb(27,49,70);
+color: #ffffff;
+
+
+ SE
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ Noto Sans KR Medium
+ 25
+
+
+
+ background-color:rgb(27,49,70);
+color: #ffffff;
+
+
+ - km
+
+
+ Qt::AlignCenter
+
+
+
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ Noto Sans KR Medium
+ 50
+
+
+
+ background-color:rgb(27,49,70);
+color: #ffffff;
+
+
+ - km
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ Noto Sans
+ 9
+
+
+
+ background-color:rgb(27,49,70);
+color: #ffffff;
+
+
+ Qt::Horizontal
+
+
+ QDialogButtonBox::Cancel|QDialogButtonBox::Ok
+
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/save_db.py b/src/save_db.py
deleted file mode 100644
index e97bd76..0000000
--- a/src/save_db.py
+++ /dev/null
@@ -1,46 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 2021-2022 Sijung Co., Ltd.
-#
-# Authors:
-# cotjdals5450@gmail.com (Seong Min Chae)
-# 5jx2oh@gmail.com (Jongjin Oh)
-
-"""
-This code is not include AWS Sensor, only Visibility
-"""
-
-
-import time
-from influxdb import InfluxDBClient, exceptions
-
-
-def SaveDB(vis_value):
- try:
- client = InfluxDBClient('localhost', 8086)
- save_time = time.time_ns()
- client.create_database("Sijung")
- client.switch_database("Sijung")
- points = [{"measurement": "JS06",
- "tags": {"name": "Sijung"},
- "fields": {"visibility": float(vis_value)},
- "time": save_time}]
- client.write_points(points=points, protocol="json")
- client.close()
-
- # Save every 1 minute.
- # time.sleep(3)
- return
-
- except exceptions as e:
- print(e)
-
-
-def main():
- for i in range(10000):
- num = i % 10
- SaveDB(num)
-
-
-if __name__ == '__main__':
- main()
diff --git a/src/save_log.py b/src/save_log.py
new file mode 100644
index 0000000..da15b19
--- /dev/null
+++ b/src/save_log.py
@@ -0,0 +1,59 @@
+#!/usr/bin/env python3
+#
+# Copyright 2021-2023 Sijung Co., Ltd.
+#
+# Authors:
+# cotjdals5450@gmail.com (Seong Min Chae)
+# 5jx2oh@gmail.com (Jongjin Oh)
+
+
+import os
+import time
+from cryptography.fernet import Fernet
+from model import JS08Settings
+
+
+os.makedirs(f'{JS08Settings.get("log_path")}/SET', exist_ok=True) # 폴더가 없으면 생성
+ym = time.strftime('%Y%m%d', time.localtime(time.time()))[2:] # 현재 날짜
+
+log_path = JS08Settings.get('log_path') # QSettings 에서 log 경로를 불러온다
+if os.path.isfile(f'{log_path}/Log_{ym}.txt'): # 만약 해당 경로에 Log 파일이 있으면,
+ key = JS08Settings.get_user('log_key')
+else:
+ key = Fernet.generate_key()
+ JS08Settings.set('log_key', key)
+ with open(f'{log_path}/SET/SET_{ym}.txt', 'a') as f:
+ f.write(str(key.decode('utf-8')))
+
+
+def log(ID: str, log_msg: str):
+ fernet = Fernet(key)
+
+ current_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
+ with open(f'{log_path}/Log_{ym}.txt', 'a') as f:
+ data = f'[{current_time}] {ID} >> {log_msg}'
+ encrypt_data = fernet.encrypt(bytes(data, 'utf-8'))
+ f.write(f'{str(encrypt_data)}\n')
+
+
+def decrypt_log(file: str):
+ date = file[file.find('Log_', 0) + 4:-4]
+ with open(f'{log_path}/SET/SET_{date}.txt') as fd:
+ data = fd.readlines()
+ fernet = Fernet(data[0])
+
+ result = []
+ with open(file, 'r') as fv:
+ data = fv.readlines()
+ for i in data:
+ if not i[:3] == 'key':
+ output = eval(i)
+ result.append(fernet.decrypt(output).decode('utf-8'))
+ return result
+
+
+if __name__ == '__main__':
+ # for i in range(0, 10):
+ # log('TEST', 'TEST Function')
+ a = decrypt_log('F://JS08/log/Log_230202.txt')
+ print(a)
diff --git a/src/setting.exe b/src/setting.exe
new file mode 100644
index 0000000..11f590b
Binary files /dev/null and b/src/setting.exe differ
diff --git a/src/setting.ico b/src/setting.ico
new file mode 100644
index 0000000..2a17e31
Binary files /dev/null and b/src/setting.ico differ
diff --git a/src/setting.py b/src/setting.py
new file mode 100644
index 0000000..457c87d
--- /dev/null
+++ b/src/setting.py
@@ -0,0 +1,65 @@
+#!/usr/bin/env python3
+#
+# Copyright 2021-2022 Sijung Co., Ltd.
+#
+# Authors:
+# cotjdals5450@gmail.com (Seong Min Chae)
+# 5jx2oh@gmail.com (Jongjin Oh)
+
+import os
+import sys
+import time
+
+from PySide6.QtWidgets import QDialog
+from PySide6.QtCore import Qt
+
+from model import JS08Settings
+from resources.rtsp_setting import Ui_Dialog
+
+
+class Setting(QDialog, Ui_Dialog):
+
+ def __init__(self):
+ super(Setting, self).__init__()
+
+ self.setupUi(self)
+
+ self.front_model_lineEdit.setText(JS08Settings.get('front_camera_name'))
+ self.front_rtsp_lineEdit.setText(JS08Settings.get('front_camera_rtsp'))
+ self.front_resize_rtsp_lineEdit.setText(JS08Settings.get('front_main'))
+
+ self.rear_model_lineEdit.setText(JS08Settings.get('rear_camera_name'))
+ self.rear_rtsp_lineEdit.setText(JS08Settings.get('rear_camera_rtsp'))
+ self.rear_resize_rtsp_lineEdit.setText(JS08Settings.get('rear_main'))
+
+ self.data_path_lineEdit.setText(JS08Settings.get('data_csv_path'))
+ self.target_path_lineEdit.setText(JS08Settings.get('target_csv_path'))
+ self.rgb_path_lineEdit.setText(JS08Settings.get('rgb_csv_path'))
+ self.image_path_lineEdit.setText(JS08Settings.get('image_save_path'))
+
+ self.buttonBox.accepted.connect(self.accept_click)
+
+ def accept_click(self):
+ JS08Settings.set('front_camera_name', self.front_model_lineEdit.text())
+ JS08Settings.set('front_camera_rtsp', self.front_rtsp_lineEdit.text())
+ JS08Settings.set('front_main', self.front_resize_rtsp_lineEdit.text())
+
+ JS08Settings.set('rear_camera_name', self.rear_model_lineEdit.text())
+ JS08Settings.set('rear_camera_rtsp', self.rear_rtsp_lineEdit.text())
+ JS08Settings.set('rear_main', self.rear_resize_rtsp_lineEdit.text())
+
+ JS08Settings.set('data_csv_path', self.data_path_lineEdit.text())
+ JS08Settings.set('target_csv_path', self.target_path_lineEdit.text())
+ JS08Settings.set('rgb_csv_path', self.rgb_path_lineEdit.text())
+ JS08Settings.set('image_save_path', self.image_path_lineEdit.text())
+
+ self.close()
+
+
+if __name__ == '__main__':
+ from PySide6.QtWidgets import QApplication
+
+ app = QApplication(sys.argv)
+ window = Setting()
+ window.show()
+ sys.exit(app.exec())
diff --git a/src/target_info.py b/src/target_info.py
new file mode 100644
index 0000000..8b64619
--- /dev/null
+++ b/src/target_info.py
@@ -0,0 +1,197 @@
+#!/usr/bin/env python3
+#
+# Copyright 2021-2022 Sijung Co., Ltd.
+#
+# Authors:
+# cotjdals5450@gmail.com (Seong Min Chae)
+# 5jx2oh@gmail.com (Jongjin Oh)
+
+import os
+import pandas as pd
+import numpy as np
+
+from cal_ext_coef import Coef
+from model import JS08Settings
+
+
+class TargetInfo:
+
+ def __init__(self):
+ self.coef = Coef()
+
+ self.list1, self.list2, self.list3, self.select_color = None, None, None, None
+
+ def minprint(self, epoch, left_range, right_range, distance, cv_img, camera):
+ """A function that outputs pixels for calculating the dissipation coefficient in the specified areas"""
+
+ cp_image = cv_img.copy()
+ # cv2.imwrite(f'test/{epoch}.png', cp_image)
+ min_x = []
+ min_y = []
+
+ for upper_left, lower_right in zip(left_range, right_range):
+ result = self.minrgb(upper_left, lower_right, cp_image)
+ min_x.append(result[0])
+ min_y.append(result[1])
+
+ visibility = self.get_rgb(epoch, min_x, min_y, cp_image, distance, camera)
+
+ if visibility is None:
+ visibility = 0
+
+ return visibility
+
+ def minrgb(self, upper_left, lower_right, cp_image):
+ """Extracts the minimum RGB value of the dragged area"""
+
+ up_y = min(upper_left[1], lower_right[1])
+ down_y = max(upper_left[1], lower_right[1])
+
+ left_x = min(upper_left[0], lower_right[0])
+ right_x = max(upper_left[0], lower_right[0])
+
+ target = cp_image[up_y:down_y, left_x:right_x, :]
+
+ r = target[:, :, 0]
+ g = target[:, :, 1]
+ b = target[:, :, 2]
+
+ r = np.clip(r, 0, 765)
+ sum_rgb = r + g + b
+
+ t_idx = np.where(sum_rgb == np.min(sum_rgb))
+
+ show_min_y = t_idx[0][0] + up_y
+ show_min_x = t_idx[1][0] + left_x
+
+ return show_min_x, show_min_y
+
+ def get_rgb(self, epoch: str, min_x, min_y, cp_image, distance, camera):
+ """Gets the RGB values of the coordinates."""
+
+ r_list = []
+ g_list = []
+ b_list = []
+
+ for x, y in zip(min_x, min_y):
+ r_list.append(cp_image[y, x, 0])
+ g_list.append(cp_image[y, x, 1])
+ b_list.append(cp_image[y, x, 2])
+
+ visibility = self.save_rgb(r_list, g_list, b_list, epoch, distance, camera)
+
+ return visibility
+
+ def save_rgb(self, r_list, g_list, b_list, epoch, distance, camera):
+ """Save the rgb information for each target."""
+
+ # save_path = os.path.join(f'rgb/{camera}/{epoch[:4]}/{epoch[4:8]}')
+ save_path = os.path.join(f'{JS08Settings.get("rgb_csv_path")}/{camera}/{epoch[:4]}/{epoch[4:8]}')
+ os.makedirs(save_path, exist_ok=True)
+
+ if r_list:
+ r_list = list(map(int, r_list))
+ g_list = list(map(int, g_list))
+ b_list = list(map(int, b_list))
+
+ col = ['target_name', 'r', 'g', 'b', 'distance']
+ result = pd.DataFrame(columns=col)
+ result['target_name'] = [f'target_{num}' for num in range(1, len(r_list) + 1)]
+ result['r'] = r_list
+ result['g'] = g_list
+ result['b'] = b_list
+ result['distance'] = distance
+ result.to_csv(f'{save_path}/{epoch}00.csv', mode='w', index=False)
+
+ try:
+ self.list1, self.list2, self.list3, self.select_color = self.coef.cal_curve(result)
+ except TypeError:
+ pass
+
+ visibility = self.extinc_print(self.list3, self.select_color)
+
+ return visibility
+
+ def extinc_print(self, alp_list: list, select_color: str = ''):
+ """Select an appropriate value among visibility by wavelength."""
+ visibility = 0
+
+ if select_color == 'red':
+ visibility = self.visibility_print(alp_list[0])
+ elif select_color == 'green':
+ visibility = self.visibility_print(alp_list[1])
+ elif select_color == 'blue':
+ visibility = self.visibility_print(alp_list[2])
+
+ return visibility
+
+ def visibility_print(self, ext_g: float=0.0):
+ """Print the visibility"""
+
+ vis_value = (3.912 / ext_g)
+ if vis_value > 20:
+ vis_value = 20
+ elif vis_value <= 0.01:
+ vis_value = 0.01
+
+ vis_value_str = f'{vis_value:.3f}'
+
+ return vis_value_str
+
+ def get_target(self, camera_name: str):
+ """Retrieves target information of a specific camera."""
+
+ save_path = JS08Settings.get('target_csv_path')
+
+ if os.path.isfile(f'{save_path}/{camera_name}/{camera_name}.csv'):
+ target_df = pd.read_csv(f'{save_path}/{camera_name}/{camera_name}.csv')
+ target_name = target_df['target_name'].tolist()
+ left_range = self.str_to_tuple(target_df['left_range'].tolist())
+ right_range = self.str_to_tuple(target_df['right_range'].tolist())
+ distance = target_df['distance'].tolist()
+ azimuth = target_df['azimuth'].tolist()
+
+ return target_name, left_range, right_range, distance, azimuth
+
+ else:
+ return [], [], [], [], []
+
+ def get_target_from_azimuth(self, camera_name: str, azimuth: str):
+ """Retrieves target information from azimuth of a specific camera"""
+
+ save_path = JS08Settings.get('target_csv_path')
+
+ if os.path.isfile(f'{save_path}/{camera_name}/{camera_name}.csv'):
+ target_df = pd.read_csv(f'{save_path}/{camera_name}/{camera_name}.csv')
+ azi_target = target_df.loc[(target_df['azimuth'] == f'{azimuth}'), :]
+
+ target_name = azi_target['target_name'].tolist()
+ left_range = self.str_to_tuple(azi_target['left_range'].tolist())
+ right_range = self.str_to_tuple(azi_target['right_range'].tolist())
+ distance = azi_target['distance'].tolist()
+
+ return target_name, left_range, right_range, distance, azimuth
+
+ else:
+
+ return [], [], [], [], []
+
+ def str_to_tuple(self, before_list):
+ """A function that converts the tuple list, which is the location information of the stored targets,
+ into a string and converts it back into a tuple form."""
+ tuple_list = [i.split(',') for i in before_list]
+ tuple_list = [(int(i[0][1:]), int(i[1][:-1])) for i in tuple_list]
+ return tuple_list
+
+
+if __name__ == '__main__':
+
+ target_info = TargetInfo()
+ front_target_name_W, front_left_range_W, front_right_range_W, front_distance_W, front_azimuth_W = \
+ target_info.get_target_from_azimuth(JS08Settings.get('front_camera_name'), 'W')
+
+ print(front_target_name_W)
+ print(front_left_range_W)
+ print(front_right_range_W)
+ print(front_distance_W)
+ print(front_azimuth_W)
diff --git a/src/target_info_test.py b/src/target_info_test.py
new file mode 100644
index 0000000..a56ad5e
--- /dev/null
+++ b/src/target_info_test.py
@@ -0,0 +1,196 @@
+#!/usr/bin/env python3
+#
+# Copyright 2021-2022 Sijung Co., Ltd.
+#
+# Authors:
+# cotjdals5450@gmail.com (Seong Min Chae)
+# 5jx2oh@gmail.com (Jongjin Oh)
+
+import os
+import pandas as pd
+import numpy as np
+
+from cal_ext_coef import Coef
+from model import JS08Settings
+
+
+class TargetInfo:
+
+ def __init__(self):
+ self.coef = Coef()
+
+ self.list1, self.list2, self.list3, self.select_color = None, None, None, None
+
+ def minprint(self, epoch, left_range, right_range, distance, cv_img, camera):
+ """A function that outputs pixels for calculating the dissipation coefficient in the specified areas"""
+
+ cp_image = cv_img.copy()
+ min_x = []
+ min_y = []
+
+ for upper_left, lower_right in zip(left_range, right_range):
+ result = self.minrgb(upper_left, lower_right, cp_image)
+ min_x.append(result[0])
+ min_y.append(result[1])
+
+ visibility = self.get_rgb(epoch, min_x, min_y, cp_image, distance, camera)
+
+ if visibility is None:
+ visibility = 0
+
+ return visibility
+
+ def minrgb(self, upper_left, lower_right, cp_image):
+ """Extracts the minimum RGB value of the dragged area"""
+
+ up_y = min(upper_left[1], lower_right[1])
+ down_y = max(upper_left[1], lower_right[1])
+
+ left_x = min(upper_left[0], lower_right[0])
+ right_x = max(upper_left[0], lower_right[0])
+
+ target = cp_image[up_y:down_y, left_x:right_x, :]
+
+ r = target[:, :, 0]
+ g = target[:, :, 1]
+ b = target[:, :, 2]
+
+ r = np.clip(r, 0, 765)
+ sum_rgb = r + g + b
+
+ t_idx = np.where(sum_rgb == np.min(sum_rgb))
+
+ show_min_y = t_idx[0][0] + up_y
+ show_min_x = t_idx[1][0] + left_x
+
+ return show_min_x, show_min_y
+
+ def get_rgb(self, epoch: str, min_x, min_y, cp_image, distance, camera):
+ """Gets the RGB values of the coordinates."""
+
+ r_list = []
+ g_list = []
+ b_list = []
+
+ for x, y in zip(min_x, min_y):
+ r_list.append(cp_image[y, x, 0])
+ g_list.append(cp_image[y, x, 1])
+ b_list.append(cp_image[y, x, 2])
+
+ visibility = self.save_rgb(r_list, g_list, b_list, epoch, distance, camera)
+
+ return visibility
+
+ def save_rgb(self, r_list, g_list, b_list, epoch, distance, camera):
+ """Save the rgb information for each target."""
+
+ # save_path = os.path.join(f'rgb/{camera}/{epoch[:4]}/{epoch[4:8]}')
+ # save_path = os.path.join(f'{JS08Settings.get("rgb_csv_path")}/{camera}/{epoch[:4]}/{epoch[4:8]}')
+ # os.makedirs(save_path, exist_ok=True)
+
+ if r_list:
+ r_list = list(map(int, r_list))
+ g_list = list(map(int, g_list))
+ b_list = list(map(int, b_list))
+
+ col = ['target_name', 'r', 'g', 'b', 'distance']
+ result = pd.DataFrame(columns=col)
+ result['target_name'] = [f'target_{num}' for num in range(1, len(r_list) + 1)]
+ result['r'] = r_list
+ result['g'] = g_list
+ result['b'] = b_list
+ result['distance'] = distance
+ # result.to_csv(f'{save_path}/{epoch}00.csv', mode='w', index=False)
+
+ try:
+ self.list1, self.list2, self.list3, self.select_color = self.coef.cal_curve(result)
+ except TypeError:
+ pass
+
+ visibility = self.extinc_print(self.list3, self.select_color)
+
+ return visibility
+
+ def extinc_print(self, alp_list: list, select_color: str = ''):
+ """Select an appropriate value among visibility by wavelength."""
+ visibility = 0
+
+ if select_color == 'red':
+ visibility = self.visibility_print(alp_list[0])
+ elif select_color == 'green':
+ visibility = self.visibility_print(alp_list[1])
+ elif select_color == 'blue':
+ visibility = self.visibility_print(alp_list[2])
+
+ return visibility
+
+ def visibility_print(self, ext_g: float=0.0):
+ """Print the visibility"""
+
+ vis_value = (3.912 / ext_g)
+ if vis_value > 20:
+ vis_value = 20
+ elif vis_value <= 0.01:
+ vis_value = 0.01
+
+ vis_value_str = f'{vis_value:.3f}'
+
+ return vis_value_str
+
+ def get_target(self, camera_name: str):
+ """Retrieves target information of a specific camera."""
+
+ save_path = JS08Settings.get('target_csv_path')
+
+ if os.path.isfile(f'{save_path}/{camera_name}/{camera_name}.csv'):
+ target_df = pd.read_csv(f'{save_path}/{camera_name}/{camera_name}.csv')
+ target_name = target_df['target_name'].tolist()
+ left_range = self.str_to_tuple(target_df['left_range'].tolist())
+ right_range = self.str_to_tuple(target_df['right_range'].tolist())
+ distance = target_df['distance'].tolist()
+ azimuth = target_df['azimuth'].tolist()
+
+ return target_name, left_range, right_range, distance, azimuth
+
+ else:
+ return [], [], [], [], []
+
+ def get_target_from_azimuth(self, camera_name: str, azimuth: str):
+ """Retrieves target information from azimuth of a specific camera"""
+
+ save_path = JS08Settings.get('target_csv_path')
+
+ if os.path.isfile(f'{save_path}/{camera_name}/{camera_name}.csv'):
+ target_df = pd.read_csv(f'{save_path}/{camera_name}/{camera_name}.csv')
+ azi_target = target_df.loc[(target_df['azimuth'] == f'{azimuth}'), :]
+
+ target_name = azi_target['target_name'].tolist()
+ left_range = self.str_to_tuple(azi_target['left_range'].tolist())
+ right_range = self.str_to_tuple(azi_target['right_range'].tolist())
+ distance = azi_target['distance'].tolist()
+
+ return target_name, left_range, right_range, distance, azimuth
+
+ else:
+
+ return [], [], [], [], []
+
+ def str_to_tuple(self, before_list):
+ """A function that converts the tuple list, which is the location information of the stored targets,
+ into a string and converts it back into a tuple form."""
+ tuple_list = [i.split(',') for i in before_list]
+ tuple_list = [(int(i[0][1:]), int(i[1][:-1])) for i in tuple_list]
+ return tuple_list
+
+
+if __name__ == '__main__':
+
+ target_info = TargetInfo()
+ front_target_name_W, front_left_range_W, front_right_range_W, front_distance_W, front_azimuth_W = \
+ target_info.get_target_from_azimuth(JS08Settings.get('front_camera_name'), 'W')
+
+ print(front_target_name_W)
+ print(front_left_range_W)
+ print(front_right_range_W)
+ print(front_distance_W)
+ print(front_azimuth_W)
diff --git a/src/test_pyecharts.py b/src/test_pyecharts.py
deleted file mode 100644
index 478e559..0000000
--- a/src/test_pyecharts.py
+++ /dev/null
@@ -1,68 +0,0 @@
-# # coding=utf-8
-# # from __future__ import unicode_literals
-# from pyecharts import Bar, Pie, Gauge
-#
-# attr = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
-# v1 = [2.0, 4.9, 7.0, 23.2, 25.6, 76.7, 135.6, 162.2, 32.6, 20.0, 6.4, 3.3]
-# v2 = [2.6, 5.9, 9.0, 26.4, 28.7, 70.7, 175.6, 182.2, 48.7, 18.8, 6.0, 2.3]
-# bar = Bar("Bar Graph", "precipitation and evaporation one year")
-# bar.add("precipitation", attr, v1, mark_line=["average"], mark_point=["max", "min"])
-# bar.add("evaporation", attr, v2, mark_line=["average"], mark_point=["max", "min"])
-# bar.height = 500
-# bar.width = 800
-# bar.render()
-#
-# gauge = Gauge("Gauge Graph")
-# gauge.add("이용률", "가운데", 66.66)
-#
-# attr = ['A', 'B', 'C', 'D', 'E', 'F']
-# v1 = [11, 12, 13, 10, 10, 10]
-# v2 = [19, 21, 32, 20, 20, 33]
-# pie = Pie('Pie Graph', title_pos='center', width=900)
-# pie.add('A', attr, v1, center=[25,50], is_random=True, radius=[30, 75], rosetype='radius')
-# pie.add('B', attr, v2, center=[75,50], is_random=True, radius=[30, 75], rosetype='area', is_legend_show=False,
-# is_label_show=True)
-# pie.render()
-
-# from PyQt5.QtCore import QUrl
-# from PyQt5.QtWidgets import QApplication, QWidget, QHBoxLayout, QFrame
-# from PyQt5.QtWebEngineWidgets import QWebEngineView
-# import sys
-#
-#
-# class UI(QWidget):
-# def __init__(self):
-# super().__init__()
-# self.initUI()
-# self.mainLayout()
-#
-# def initUI(self):
-# self.setWindowTitle("TEST")
-#
-# def mainLayout(self):
-# self.mainhboxLayout = QHBoxLayout(self)
-# self.frame = QFrame(self)
-# self.mainhboxLayout.addWidget(self.frame)
-# self.hboxLayout = QHBoxLayout(self.frame)
-#
-# self.myHtml = QWebEngineView()
-# # url = "http://www.baidu.com"
-# self.myHtml.load(QUrl("render.html"))
-#
-# self.hboxLayout.addWidget(self.myHtml)
-# self.setLayout(self.mainhboxLayout)
-#
-#
-# if __name__ == '__main__':
-# app = QApplication(sys.argv)
-# ex = UI()
-# ex.show()
-# sys.exit(app.exec_())
-
-import plotly.express as px
-df = px.data.wind()
-fig = px.line_polar(df, r='frequency', theta='direction', color='strength', line_close=True,
- color_discrete_sequence=px.colors.sequential.Plasma_r,
- template='plotly_dark', )
-fig.show()
-# self.m_output.setHtml(fig.to_html(include_plotlyjs='cdn'))
\ No newline at end of file
diff --git a/src/thumbnail_view.py b/src/thumbnail_view.py
new file mode 100644
index 0000000..39c22ce
--- /dev/null
+++ b/src/thumbnail_view.py
@@ -0,0 +1,49 @@
+#!/usr/bin/env python3
+#
+# Copyright 2021-2022 Sijung Co., Ltd.
+#
+# Authors:
+# cotjdals5450@gmail.com (Seong Min Chae)
+# 5jx2oh@gmail.com (Jongjin Oh)
+
+import os
+
+from PySide6.QtGui import QPixmap
+from PySide6.QtWidgets import QMainWindow
+from PySide6.QtCore import Qt
+
+from resources.thumbnail_view import Ui_MainWindow
+from model import JS08Settings
+
+
+class ThumbnailView(QMainWindow, Ui_MainWindow):
+
+ def __init__(self, image_file_name: str, date: int):
+ super().__init__()
+
+ self.setupUi(self)
+ self.front_image_path = f'{JS08Settings.get("image_save_path")}/vista/{JS08Settings.get("front_camera_name")}/' \
+ f'{date}/{image_file_name}.png'
+ self.rear_image_path = f'{JS08Settings.get("image_save_path")}/vista/{JS08Settings.get("rear_camera_name")}/' \
+ f'{date}/{image_file_name}.png'
+
+ if os.path.isfile(self.front_image_path) and os.path.isfile(self.rear_image_path):
+ print(self.size())
+ print(self.front_image.size())
+ self.front_image.setPixmap(
+ # QPixmap(self.front_image_path).scaled(self.width(), self.height(), Qt.IgnoreAspectRatio))
+ QPixmap(self.front_image_path).scaled(1035, 816, Qt.IgnoreAspectRatio))
+ self.rear_image.setPixmap(
+ QPixmap(self.rear_image_path).scaled(self.width(), self.height(), Qt.IgnoreAspectRatio))
+ else:
+ print('no file')
+
+
+if __name__ == '__main__':
+ import sys
+ from PySide6.QtWidgets import QApplication
+
+ app = QApplication(sys.argv)
+ ui = ThumbnailView('20230130083300', 230130)
+ ui.show()
+ sys.exit(app.exec())
diff --git a/src/user_edit.py b/src/user_edit.py
new file mode 100644
index 0000000..c4ed398
--- /dev/null
+++ b/src/user_edit.py
@@ -0,0 +1,143 @@
+#!/usr/bin/env python3
+#
+# Copyright 2021-2023 Sijung Co., Ltd.
+#
+# Authors:
+# cotjdals5450@gmail.com (Seong Min Chae)
+# 5jx2oh@gmail.com (Jongjin Oh)
+
+
+from PySide6.QtCore import Qt
+from PySide6.QtGui import QIcon
+from PySide6.QtWidgets import QDialog, QMessageBox
+
+from model import JS08Settings
+from resources.user_list import Ui_Dialog
+from save_log import log
+
+
+class UserEdit(QDialog, Ui_Dialog):
+
+ def __init__(self):
+ super().__init__()
+ self.setupUi(self)
+ self.setWindowIcon(QIcon('JS08_Logo.ico'))
+ self.info.clear()
+
+ self.user_dict = {}
+
+ self.user_id_list = list(JS08Settings.get_user('user').keys())
+ self.user_pw_list = list(JS08Settings.get_user('user').values())
+
+ self.listWidget.addItems(self.user_id_list)
+ self.listWidget.itemClicked.connect(self.itemClicked)
+ self.listWidget.clearSelection()
+
+ self.user_id.setReadOnly(True)
+ self.user_pw.setReadOnly(True)
+ self.user_id.textChanged.connect(self.change_id)
+ self.user_pw.textChanged.connect(self.change_pw)
+
+ self.current_user = ['', '']
+
+ self.add_button.clicked.connect(self.add)
+ self.delete_button.clicked.connect(self.delete)
+ self.save_button.clicked.connect(self.save)
+ self.cancel_button.clicked.connect(self.close)
+ self.cancel_button.setShortcut('Esc')
+
+ for ide, pw in zip(self.user_id_list, self.user_pw_list):
+ self.user_dict[ide] = pw
+
+ def add(self):
+ for ide, pw in zip(list(self.user_dict.keys()), list(self.user_dict.values())):
+ self.user_dict[ide] = pw
+
+ if not 'Add_user' in self.user_dict.keys():
+ self.listWidget.addItem('Add_user')
+ self.user_dict['Add_user'] = ''
+ else:
+ pass
+
+ self.listWidget.clearSelection()
+ log(JS08Settings.get('current_id'), 'Add User accounts')
+ # self.save()
+ self.info.setText('사용자 추가')
+
+ def delete(self):
+ try:
+ del self.user_dict[f'{self.listWidget.currentItem().text()}']
+ delete = self.listWidget.currentItem().text()
+
+ self.listWidget.takeItem(self.listWidget.currentRow())
+ self.listWidget.clearSelection()
+ self.user_id.clear()
+ self.user_pw.clear()
+ self.info.setText(f'{delete} 제거')
+ log(JS08Settings.get('current_id'), 'Delete User accounts')
+
+ except AttributeError:
+ QMessageBox.information(None, 'Info', '삭제할 유저를 선택하세요.')
+
+ def save(self):
+ if not self.listWidget.count() == 0:
+ item = self.listWidget.currentItem().text()
+
+ if not self.current_user[0] == '':
+ self.user_dict.__delitem__(item)
+ self.user_dict[self.current_user[0]] = self.current_user[1]
+ d1 = sorted(self.user_dict.items())
+ self.user_dict = dict(d1)
+
+ JS08Settings.set('user', self.user_dict)
+
+ self.listWidget.clearSelection()
+ self.listWidget.clear()
+ self.listWidget.addItems(self.user_dict.keys())
+ self.info.setText('사용자 저장')
+ log(f'{JS08Settings.get("admin_id")}', 'Save User accounts')
+
+ def change_id(self):
+ self.current_user[0] = self.user_id.text()
+ self.current_user[1] = self.user_pw.text()
+
+ def change_pw(self):
+ self.current_user[0] = self.user_id.text()
+ self.current_user[1] = self.user_pw.text()
+
+ def itemClicked(self):
+ self.user_id.setReadOnly(False)
+ self.user_pw.setReadOnly(False)
+
+ item = self.listWidget.currentItem().text()
+
+ if item in list(self.user_dict.keys()):
+ self.user_id.setText(list(self.user_dict.keys())[self.listWidget.currentRow()])
+ self.user_pw.setText(list(self.user_dict.values())[self.listWidget.currentRow()])
+ else:
+ self.user_id.setText(item)
+ self.user_pw.setText('')
+
+ def keyPressEvent(self, e):
+ if e.modifiers() & Qt.ControlModifier:
+ if e.key() == Qt.Key_T:
+ self.add()
+ if e.key() == Qt.Key_S:
+ self.save()
+ if e.key() == Qt.Key_W:
+ self.close()
+ if e.key() == Qt.Key_P:
+ print(f'USER DICT: {self.user_dict}')
+
+ if e.modifiers() & Qt.Key_Escape:
+ self.close()
+
+
+if __name__ == '__main__':
+ import sys
+ from PySide6.QtWidgets import QApplication
+
+ app = QApplication(sys.argv)
+ ui = UserEdit()
+ ui.show()
+ sys.exit(app.exec())
diff --git a/src/video_thread_mp.py b/src/video_thread_mp.py
index b58d47b..628ede3 100644
--- a/src/video_thread_mp.py
+++ b/src/video_thread_mp.py
@@ -1,224 +1,194 @@
-# !/usr/bin/env python3
+#!/usr/bin/env python3
+#
+# Copyright 2021-2022 Sijung Co., Ltd.
+#
+# Authors:
+# cotjdals5450@gmail.com (Seong Min Chae)
+# 5jx2oh@gmail.com (Jongjin Oh)
+
import os
+
import cv2
import time
import numpy as np
-import pandas as pd
-import multiprocessing as mp
-from multiprocessing import Process, Queue
-
-from PyQt5.QtCore import QThread, pyqtSignal, QObject
-import curve_save
-from model import JS06Settings
-
-
-def producer(q):
- # proc = mp.current_process()
- # print(f'{proc.name} multiprocessing start.')
-
- cap = cv2.VideoCapture("rtsp://admin:sijung5520@192.168.100.100/profile2/media.smp")
- while True:
- epoch = time.strftime("%Y%m%d%H%M%S", time.localtime(time.time()))
- date = epoch[2:6]
-
- if epoch[-2:] == "00":
- try:
- image_save_path = JS06Settings.get('image_save_path')
- os.makedirs(f'{image_save_path}/vista/{date}', exist_ok=True)
- os.makedirs(f'{image_save_path}/resize/{date}', exist_ok=True)
-
- _, frame = cap.read()
- cv2.imwrite(f'{image_save_path}/vista/{date}/{epoch}.png', frame)
- cv2.imwrite(f'{image_save_path}/resize/{date}/{epoch}.jpg', cv2.resize(frame, (315, 131)))
- cv2.destroyAllWindows()
-
- # left_range, right_range, distance = get_target("PNM_9030V")
- # visibility = minprint(epoch[:-2], left_range, right_range, distance, frame)
- #
- # q.put(visibility)
- time.sleep(1)
- except Exception as e:
- print(e)
- cap.release()
- cap = cv2.VideoCapture("rtsp://admin:sijung5520@192.168.100.100/profile2/media.smp")
- continue
-
-
-def minprint(epoch, left_range, right_range, distance, cv_img):
- """A function that outputs pixels for calculating the dissipation coefficient in the specified areas"""
- print("minprint 시작")
- # epoch = time.strftime("%Y%m%d%H%M", time.localtime(time.time()))
- cp_image = cv_img.copy()
- result = ()
- cnt = 1
- min_x = []
- min_y = []
-
- for upper_left, lower_right in zip(left_range, right_range):
- result = minrgb(upper_left, lower_right, cp_image)
- min_x.append(result[0])
- min_y.append(result[1])
- cnt += 1
-
- visibility = get_rgb(epoch, min_x, min_y, cp_image, distance)
- return visibility
-
-
-def minrgb(upper_left, lower_right, cp_image):
- """Extracts the minimum RGB value of the dragged area"""
-
- up_y = min(upper_left[1], lower_right[1])
- down_y = max(upper_left[1], lower_right[1])
-
- left_x = min(upper_left[0], lower_right[0])
- right_x = max(upper_left[0], lower_right[0])
-
- test = cp_image[up_y:down_y, left_x:right_x, :]
-
- r = test[:, :, 0]
- g = test[:, :, 1]
- b = test[:, :, 2]
-
- r = np.clip(r, 0, 765)
- sum_rgb = r + g + b
-
- t_idx = np.where(sum_rgb == np.min(sum_rgb))
- print("red : ", cp_image[t_idx[0][0] + up_y, t_idx[1][0] + left_x, 0])
- print("green : ", cp_image[t_idx[0][0] + up_y, t_idx[1][0] + left_x, 1])
- print("blue : ", cp_image[t_idx[0][0] + up_y, t_idx[1][0] + left_x, 2])
- show_min_y = t_idx[0][0] + up_y
- show_min_x = t_idx[1][0] + left_x
-
- return (show_min_x, show_min_y)
-
-
-def get_rgb(epoch: str, min_x, min_y, cp_image, distance):
- """Gets the RGB values of the coordinates."""
- r_list = []
- g_list = []
- b_list = []
-
- for x, y in zip(min_x, min_y):
- r_list.append(cp_image[y, x, 0])
- g_list.append(cp_image[y, x, 1])
- b_list.append(cp_image[y, x, 2])
-
- print("red list : ", r_list)
- print("green list : ", g_list)
- print("blue list : ", b_list)
-
- visibility = save_rgb(r_list, g_list, b_list, epoch, distance)
- return visibility
-
-
-def save_rgb(r_list, g_list, b_list, epoch, distance):
- """Save the rgb information for each target."""
- try:
- save_path = os.path.join(f"rgb/PNM_9030V")
- os.mkdir(save_path)
-
- except Exception as e:
- pass
-
- if r_list:
- r_list = list(map(int, r_list))
- g_list = list(map(int, g_list))
- b_list = list(map(int, b_list))
-
- col = ["target_name", "r", "g", "b", "distance"]
- result = pd.DataFrame(columns=col)
- result["target_name"] = [f"target_{num}" for num in range(1, len(r_list) + 1)]
- result["r"] = r_list
- result["g"] = g_list
- result["b"] = b_list
- result["distance"] = distance
- result.to_csv(f"{save_path}/{epoch}.csv", mode="w", index=False)
- list1, list2, list3, select_color = curve_save.cal_curve(result)
- visibility = extinc_print(list1, list2, list3, select_color)
- print(result)
- print("Save rgb")
-
- return visibility
-
-
-def extinc_print(c1_list: list = [0, 0, 0], c2_list: list = [0, 0, 0], alp_list: list = [0, 0, 0],
- select_color: str = ""):
- """Select an appropriate value among visibility by wavelength."""
- g_ext = round(alp_list[1], 1)
+from model import JS08Settings
+from target_info import TargetInfo
+from save_log import log
+
+
+def producer(queue):
+ front_cap_name = JS08Settings.get('front_camera_name')
+ rear_cap_name = JS08Settings.get('rear_camera_name')
+
+ front_cap = cv2.VideoCapture(JS08Settings.get('front_camera_rtsp'))
+ rear_cap = cv2.VideoCapture(JS08Settings.get('rear_camera_rtsp'))
+
+ NE, EN, ES, SE, SW, WS, WN, NW = [], [], [], [], [], [], [], []
+
+ if rear_cap.isOpened() and front_cap.isOpened():
+ print('Video thread start.')
+ target_info = TargetInfo()
+ while True:
+ epoch = time.strftime('%Y%m%d%H%M%S', time.localtime(time.time()))
+ date = epoch[2:8]
+
+ if epoch[-2:] == '00':
+ # start = time.time()
+ front_target_name, front_left_range, front_right_range, front_distance, front_azimuth = \
+ target_info.get_target(front_cap_name)
+
+ rear_target_name, rear_left_range, rear_right_range, rear_distance, rear_azimuth = \
+ target_info.get_target(rear_cap_name)
+
+ front_target_name_NE, front_left_range_NE, front_right_range_NE, front_distance_NE, front_azimuth_NE = \
+ target_info.get_target_from_azimuth(front_cap_name, 'NE')
+
+ front_target_name_EN, front_left_range_EN, front_right_range_EN, front_distance_EN, front_azimuth_EN = \
+ target_info.get_target_from_azimuth(front_cap_name, 'EN')
+
+ front_target_name_ES, front_left_range_ES, front_right_range_ES, front_distance_ES, front_azimuth_ES = \
+ target_info.get_target_from_azimuth(front_cap_name, 'ES')
+
+ front_target_name_SE, front_left_range_SE, front_right_range_SE, front_distance_SE, front_azimuth_SE = \
+ target_info.get_target_from_azimuth(front_cap_name, 'SE')
+
+ rear_target_name_SW, rear_left_range_SW, rear_right_range_SW, rear_distance_SW, rear_azimuth_SW = \
+ target_info.get_target_from_azimuth(rear_cap_name, 'SW')
+
+ rear_target_name_WS, rear_left_range_WS, rear_right_range_WS, rear_distance_WS, rear_azimuth_WS = \
+ target_info.get_target_from_azimuth(rear_cap_name, 'WS')
+
+ rear_target_name_WN, rear_left_range_WN, rear_right_range_WN, rear_distance_WN, rear_azimuth_WN = \
+ target_info.get_target_from_azimuth(rear_cap_name, 'WN')
+
+ rear_target_name_NW, rear_left_range_NW, rear_right_range_NW, rear_distance_NW, rear_azimuth_NW = \
+ target_info.get_target_from_azimuth(rear_cap_name, 'NW')
+
+ if len(front_left_range_NE) < 4 and len(rear_left_range_SW) < 4:
+ continue
+ else:
+ pass
+
+ image_save_path = JS08Settings.get('image_save_path')
+ os.makedirs(f'{image_save_path}/vista/{front_cap_name}/{date}', exist_ok=True)
+ os.makedirs(f'{image_save_path}/vista/{rear_cap_name}/{date}', exist_ok=True)
+ os.makedirs(f'{image_save_path}/thumbnail/{front_cap_name}/{date}', exist_ok=True)
+ os.makedirs(f'{image_save_path}/thumbnail/{rear_cap_name}/{date}', exist_ok=True)
+
+ # front_ret, front_frame = front_cap.read()
+ # rear_ret, rear_frame = rear_cap.read()
+
+ # front_cap.release()
+ # rear_cap.release()
+ if rear_cap.isOpened() is False or front_cap.isOpened() is False:
+ front_cap = cv2.VideoCapture(JS08Settings.get('front_camera_rtsp'))
+ rear_cap = cv2.VideoCapture(JS08Settings.get('rear_camera_rtsp'))
+
+ front_ret, front_frame = front_cap.read()
+ rear_ret, rear_frame = rear_cap.read()
+
+ if not front_ret or not rear_ret:
+ print(f'Found Error; Rebuilding stream in {time.strftime("%Y.%m.%d %H:%M:%S", time.localtime(time.time()))}')
+
+ try:
+ visibility_front = target_info.minprint(epoch[:-2], front_left_range, front_right_range,
+ front_distance, front_frame, front_cap_name)
+ visibility_rear = target_info.minprint(epoch[:-2], rear_left_range, rear_right_range,
+ rear_distance, rear_frame, rear_cap_name)
+ except AttributeError as e:
+ log(JS08Settings.get('current_id'), str(e))
+ continue
+
+ visibility_front_NE = target_info.minprint(epoch[:-2], front_left_range_NE, front_right_range_NE,
+ front_distance_NE, front_frame, front_cap_name)
+ visibility_front_EN = target_info.minprint(epoch[:-2], front_left_range_EN, front_right_range_EN,
+ front_distance_EN, front_frame, front_cap_name)
+ visibility_front_ES = target_info.minprint(epoch[:-2], front_left_range_ES, front_right_range_ES,
+ front_distance_ES, front_frame, front_cap_name)
+ visibility_front_SE = target_info.minprint(epoch[:-2], front_left_range_SE, front_right_range_SE,
+ front_distance_SE, front_frame, front_cap_name)
+
+ visibility_rear_SW = target_info.minprint(epoch[:-2], rear_left_range_SW, rear_right_range_SW,
+ rear_distance_SW, rear_frame, rear_cap_name)
+ visibility_rear_WS = target_info.minprint(epoch[:-2], rear_left_range_WS, rear_right_range_WS,
+ rear_distance_WS, rear_frame, rear_cap_name)
+ visibility_rear_WN = target_info.minprint(epoch[:-2], rear_left_range_WN, rear_right_range_WN,
+ rear_distance_WN, rear_frame, rear_cap_name)
+ visibility_rear_NW = target_info.minprint(epoch[:-2], rear_left_range_NW, rear_right_range_NW,
+ rear_distance_NW, rear_frame, rear_cap_name)
+
+ # for Moving Average
+ if len(NE) >= 20:
+ del NE[0]
+ del EN[0]
+ del ES[0]
+ del SE[0]
+ del SW[0]
+ del WS[0]
+ del WN[0]
+ del NW[0]
+
+ NE.append(float(visibility_front_NE))
+ EN.append(float(visibility_front_EN))
+ ES.append(float(visibility_front_ES))
+ SE.append(float(visibility_front_SE))
+ SW.append(float(visibility_rear_SW))
+ WS.append(float(visibility_rear_WS))
+ WN.append(float(visibility_rear_WN))
+ NW.append(float(visibility_rear_NW))
+
+ NE_average = round(float(np.mean(NE)))
+ EN_average = round(float(np.mean(EN)))
+ ES_average = round(float(np.mean(ES)))
+ SE_average = round(float(np.mean(SE)))
+ SW_average = round(float(np.mean(SW)))
+ WS_average = round(float(np.mean(WS)))
+ WN_average = round(float(np.mean(WN)))
+ NW_average = round(float(np.mean(NW)))
+
+ visibility = {'visibility_front': round(float(visibility_front), 3),
+ 'visibility_rear': round(float(visibility_rear), 3),
+ 'NE': round(float(NE_average), 3), 'EN': round(float(EN_average), 3),
+ 'ES': round(float(ES_average), 3), 'SE': round(float(SE_average), 3),
+ 'SW': round(float(SW_average), 3), 'WS': round(float(WS_average), 3),
+ 'WN': round(float(WN_average), 3), 'NW': round(float(NW_average), 3)}
+
+ queue.put(visibility)
+
+ if JS08Settings.get('image_size') == 0: # Original size
+ cv2.imwrite(f'{image_save_path}/vista/{front_cap_name}/{date}/{epoch}.png', front_frame)
+ cv2.imwrite(f'{image_save_path}/vista/{rear_cap_name}/{date}/{epoch}.png', rear_frame)
+
+ elif JS08Settings.get('image_size') == 1:
+ cv2.imwrite(f'{image_save_path}/vista/{front_cap_name}/{date}/{epoch}.jpg', front_frame)
+ cv2.imwrite(f'{image_save_path}/vista/{rear_cap_name}/{date}/{epoch}.jpg', rear_frame)
+
+ elif JS08Settings.get('image_size') == 2: # FHD size
+ front_frame = cv2.resize(front_frame, (1920, 640), interpolation=cv2.INTER_AREA)
+ rear_frame = cv2.resize(rear_frame, (1920, 640), interpolation=cv2.INTER_AREA)
+
+ cv2.imwrite(
+ f'{image_save_path}/vista/{front_cap_name}/{date}/{epoch}.png', front_frame)
+ cv2.imwrite(
+ f'{image_save_path}/vista/{rear_cap_name}/{date}/{epoch}.png', rear_frame)
+
+ # Save thumbnail image
+ # epoch = time.strftime('%Y-%m-%d %H:%M:00', time.localtime(time.time()))
+ front_frame = cv2.resize(front_frame, (314, 105), interpolation=cv2.INTER_AREA) # Thumbnail size
+ rear_frame = cv2.resize(rear_frame, (314, 105), interpolation=cv2.INTER_AREA)
+ cv2.imwrite(
+ f'{image_save_path}/thumbnail/{front_cap_name}/{date}/{epoch}.jpg', front_frame)
+ cv2.imwrite(
+ f'{image_save_path}/thumbnail/{rear_cap_name}/{date}/{epoch}.jpg', rear_frame)
+
+ # print(f'코드 실행시간 {round(time.time() - start, 3)} 초')
+ time.sleep(1)
+ front_cap.release()
+ rear_cap.release()
+ front_cap = cv2.VideoCapture(JS08Settings.get('front_camera_rtsp'))
+ rear_cap = cv2.VideoCapture(JS08Settings.get('rear_camera_rtsp'))
- if select_color == "red":
- visibility = visibility_print(alp_list[0])
- elif select_color == "green":
- visibility = visibility_print(alp_list[1])
+ cv2.destroyAllWindows()
else:
- visibility = visibility_print(alp_list[2])
-
- return visibility
-
-
-def visibility_print(ext_g: float = 0.0):
- """Print the visibility"""
- vis_value = 0
-
- vis_value = (3.912 / ext_g)
- if vis_value > 20:
- vis_value = 20
- elif vis_value < 0.01:
- vis_value = 0.01
-
- # self.data_storage(vis_value)
- vis_value_str = f"{vis_value:.2f}" + " km"
- return vis_value_str
-
-
-def get_target(camera_name: str):
- """Retrieves target information of a specific camera."""
-
- save_path = os.path.join(f"target/{camera_name}")
- print("Get target information")
- if os.path.isfile(f"{save_path}/{camera_name}.csv"):
- target_df = pd.read_csv(f"{save_path}/{camera_name}.csv")
- target_name = target_df["target_name"].tolist()
- left_range = target_df["left_range"].tolist()
- left_range = str_to_tuple(left_range)
- right_range = target_df["right_range"].tolist()
- right_range = str_to_tuple(right_range)
- distance = target_df["distance"].tolist()
- return left_range, right_range, distance
-
-
-def str_to_tuple(before_list):
- """A function that converts the tuple list, which is the location information of the stored targets,
- into a string and converts it back into a tuple form."""
- tuple_list = [i.split(',') for i in before_list]
- tuple_list = [(int(i[0][1:]), int(i[1][:-1])) for i in tuple_list]
- return tuple_list
-
-
-class VideoThread(QThread):
- update_pixmap_signal = pyqtSignal(str)
-
- def __init__(self, src: str = "", file_type: str = "None", q: Queue = None):
- super().__init__()
- self._run_flag = False
- self.src = src
- self.file_type = file_type
- self.q = q
-
- def run(self):
- self._run_flag = True
- ## 영상 입력이 카메라일 때
- if self.file_type == "Video":
- print("비디오 쓰레드 시작")
- while self._run_flag:
- if not self.q.empty():
- cv_img = self.q.get()
- self.update_pixmap_signal.emit(cv_img)
- # shut down capture system
-
- def stop(self):
- """Sets run flag to False and waits for thread to finish"""
- self._run_flag = False
- self.quit()
- self.wait()
+ print('cap closed')
diff --git a/src/visibility_target_test.py b/src/visibility_target_test.py
new file mode 100644
index 0000000..6472e59
--- /dev/null
+++ b/src/visibility_target_test.py
@@ -0,0 +1,615 @@
+#!/usr/bin/env python3
+#
+# Copyright 2021-2023 Sijung Co., Ltd.
+#
+# Authors:
+# cotjdals5450@gmail.com (Seong Min Chae)
+# 5jx2oh@gmail.com (Jongjin Oh)
+
+
+import os
+import cv2
+import time
+import numpy as np
+import pandas as pd
+import warnings
+warnings.filterwarnings(action='ignore')
+from scipy.optimize import curve_fit
+
+from PySide6.QtCore import (QPoint, QRect, Qt)
+from PySide6.QtGui import (QPixmap, QPainter, QBrush,
+ QColor, QPen, QImage, QFont, QMovie)
+from PySide6.QtWidgets import (QInputDialog, QDialog, QFileDialog,
+ QHeaderView, QTableWidget, QTableWidgetItem)
+from PySide6.QtCharts import QChart, QChartView, QValueAxis, QLineSeries
+
+from target_info_test import TargetInfo
+from resources.visibility_test import Ui_Dialog
+
+
+class JS08AdminSettingWidget(QDialog, Ui_Dialog):
+
+ def __init__(self):
+ super().__init__()
+ self.setupUi(self)
+
+ self.showFullScreen()
+ self.setWindowFlag(Qt.FramelessWindowHint)
+
+ self.begin = QPoint()
+ self.end = QPoint()
+
+ self.upper_left = ()
+ self.lower_right = ()
+
+ self.target_name = []
+ self.left_range = []
+ self.right_range = []
+ self.distance = []
+ self.azimuth = []
+ self.current_azi = ''
+
+ self.isDrawing = False
+
+ self.video_width = 0
+ self.video_height = 0
+
+ self.cp_image = None
+ self.img = None
+ self.end_drawing = True
+
+ self.x = None
+ self.chart_view = None
+ self.select_target = None
+ self.select_name = None
+ self.select_corner1 = None
+ self.select_corner2 = None
+
+ self.tableWidget.doubleClicked.connect(self.tableWidget_doubleClicked)
+
+ self.r_list = []
+ self.g_list = []
+ self.b_list = []
+ self.target_info = TargetInfo()
+
+ self.current_camera = 'PNO-A9081R01'
+ self.cam_flag = False
+ self.movie = None
+
+ self.image_load()
+
+ if len(self.left_range) > 0:
+ self.tableWidget.setEditTriggers(QTableWidget.NoEditTriggers)
+ self.show_target_table()
+
+ self.image_label.paintEvent = self.lbl_paintEvent
+ self.image_label.mousePressEvent = self.lbl_mousePressEvent
+ self.image_label.mouseMoveEvent = self.lbl_mouseMoveEvent
+ self.image_label.mouseReleaseEvent = self.lbl_mouseReleaseEvent
+
+ self.load_img.clicked.connect(self.load_img_btn)
+ self.vis_btn.clicked.connect(self.print_data)
+
+ self.buttonBox.accepted.connect(self.accept_click)
+ self.buttonBox.rejected.connect(self.reject_click)
+
+ def show_target_table(self):
+ # min_x = []
+ # min_y = []
+ self.r_list = []
+ self.g_list = []
+ self.b_list = []
+
+ copy_image = self.cp_image.copy()
+ row_count = len(self.distance)
+ self.tableWidget.setRowCount(row_count)
+ self.tableWidget.setColumnCount(3)
+ self.tableWidget.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
+ self.tableWidget.setHorizontalHeaderLabels(['Number', 'Distance', 'Azimuth'])
+
+ for upper_left, lower_right in zip(self.left_range, self.right_range):
+ result = self.target_info.minrgb(upper_left, lower_right, copy_image)
+ # min_x.append(result[0])
+ # min_y.append(result[1])
+
+ self.r_list.append(copy_image[result[1], result[0], 0])
+ self.g_list.append(copy_image[result[1], result[0], 1])
+ self.b_list.append(copy_image[result[1], result[0], 2])
+
+ for i in range(0, row_count):
+ item2 = QTableWidgetItem(f'{i + 1}')
+ item2.setTextAlignment(Qt.AlignVCenter | Qt.AlignHCenter)
+ item2.setForeground(QBrush(QColor(255, 255, 255)))
+ self.tableWidget.setItem(i, 0, item2)
+
+ item3 = QTableWidgetItem(f'{self.distance[i]} km')
+ item3.setTextAlignment(Qt.AlignVCenter | Qt.AlignHCenter)
+ item3.setForeground(QBrush(QColor(255, 255, 255)))
+ self.tableWidget.setItem(i, 1, item3)
+
+ item4 = QTableWidgetItem(f'{self.azimuth[i]}')
+ item4.setTextAlignment(Qt.AlignVCenter | Qt.AlignHCenter)
+ item4.setForeground(QBrush(QColor(255, 255, 255)))
+ self.tableWidget.setItem(i, 2, item4)
+
+ def func(self, x, c1, c2, a):
+ return c2 + (c1 - c2) * np.exp(-a * x)
+
+ def chart_update(self):
+
+ if self.gridLayout_3.count() == 0:
+ new_chart_view_NE = self.chart_draw('NE')
+ new_chart_view_EN = self.chart_draw('EN')
+ new_chart_view_ES = self.chart_draw('ES')
+ new_chart_view_SE = self.chart_draw('SE')
+ self.gridLayout_3.addWidget(new_chart_view_NE, 0, 0)
+ self.gridLayout_3.addWidget(new_chart_view_EN, 0, 1)
+ self.gridLayout_3.addWidget(new_chart_view_ES, 1, 0)
+ self.gridLayout_3.addWidget(new_chart_view_SE, 1, 1)
+ else:
+ new_chart_view_NE = self.chart_draw('NE')
+ new_chart_view_EN = self.chart_draw('EN')
+ new_chart_view_ES = self.chart_draw('ES')
+ new_chart_view_SE = self.chart_draw('SE')
+
+ self.gridLayout_3.removeWidget(self.chart_view)
+ self.gridLayout_3.addWidget(new_chart_view_NE, 0, 0)
+ self.gridLayout_3.addWidget(new_chart_view_EN, 0, 1)
+ self.gridLayout_3.addWidget(new_chart_view_ES, 1, 0)
+ self.gridLayout_3.addWidget(new_chart_view_SE, 1, 1)
+ self.gridLayout_3.update()
+
+ def chart_draw(self, azimuth: str):
+ """세팅창 그래프 칸에 소산계수 차트를 그리는 함수"""
+
+ # indices = []
+ # for i in range(len(self.azimuth)):
+ # if self.azimuth[i] == azimuth:
+ # indices.append(i)
+ # distance = []
+ distance = self.distance.copy()
+ # for i in indices:
+ # distance.append(self.distance[i])
+
+ distance.sort()
+ self.x = np.linspace(distance[0], distance[-1], 100, endpoint=True)
+ # self.x.sort()
+
+ # hanhwa_opt_r, hanhwa_cov_r = curve_fit(self.func, self.distance, self.r_list, maxfev=5000)
+ # hanhwa_opt_g, hanhwa_cov_g = curve_fit(self.func, self.distance, self.g_list, maxfev=5000)
+ # hanhwa_opt_b, hanhwa_cov_b = curve_fit(self.func, self.distance, self.b_list, maxfev=5000)
+ hanhwa_opt_r, hanhwa_cov_r = curve_fit(self.func, distance, self.r_list, maxfev=5000)
+ hanhwa_opt_g, hanhwa_cov_g = curve_fit(self.func, distance, self.g_list, maxfev=5000)
+ hanhwa_opt_b, hanhwa_cov_b = curve_fit(self.func, distance, self.b_list, maxfev=5000)
+
+ chart = QChart()
+ chart.setTheme(QChart.ChartThemeDark)
+ font = QFont('Noto Sans kr')
+ font.setPixelSize(20)
+ font.setBold(3)
+ chart.setTitleFont(font)
+ chart.setTitleBrush(QBrush(QColor('#ffffff')))
+ chart.setTitle(f'{azimuth} 소산계수 그래프')
+ # chart.setFont(QFont(''))
+ chart.setAnimationOptions(QChart.SeriesAnimations)
+ chart.setBackgroundBrush(QBrush(QColor(255, 255, 255)))
+
+ axis_x = QValueAxis()
+ axis_x.setTickCount(7)
+ axis_x.setLabelFormat('%i')
+ axis_x.setTitleText('Distance(km)')
+ axis_x.setTitleBrush(QBrush(QColor('#ffffff')))
+ axis_x.setRange(0, 6)
+ chart.addAxis(axis_x, Qt.AlignBottom)
+
+ axis_y = QValueAxis()
+ axis_y.setTickCount(7)
+ axis_y.setLabelFormat('%i')
+ axis_y.setTitleText('Intensity')
+ axis_y.setTitleBrush(QBrush('#ffffff'))
+ axis_y.setRange(0, 255)
+ chart.addAxis(axis_y, Qt.AlignLeft)
+
+ # # Red Graph
+ # # if self.red_checkBox.isChecked():
+ series1 = QLineSeries()
+ series1.setName('Red')
+ pen = QPen()
+ pen.setWidth(2)
+ series1.setPen(pen)
+ series1.setColor(QColor('Red'))
+
+ for dis in self.x:
+ series1.append(*(dis, self.func(dis, *hanhwa_opt_r)))
+ chart.addSeries(series1) # data feeding
+ series1.attachAxis(axis_x)
+ series1.attachAxis(axis_y)
+ #
+ # # Green Graph
+ # # if self.green_checkBox.isChecked():
+ series2 = QLineSeries()
+ series2.setName('Green')
+ pen = QPen()
+ pen.setWidth(2)
+ series2.setPen(pen)
+ series2.setColor(QColor('Green'))
+
+ for dis in self.x:
+ series2.append(*(dis, self.func(dis, *hanhwa_opt_g)))
+ chart.addSeries(series2) # data feeding
+
+ series2.attachAxis(axis_x)
+ series2.attachAxis(axis_y)
+ #
+ # # Blue Graph
+ # # if self.blue_checkBox.isChecked():
+ series3 = QLineSeries()
+ series3.setName('Blue')
+ pen = QPen()
+ pen.setWidth(2)
+ series3.setPen(pen)
+ series3.setColor(QColor('Blue'))
+
+ for dis in self.x:
+ series3.append(*(dis, self.func(dis, *hanhwa_opt_b)))
+ chart.addSeries(series3) # data feeding
+
+ series3.attachAxis(axis_x)
+ series3.attachAxis(axis_y)
+
+ chart.legend().setAlignment(Qt.AlignRight)
+
+ # displaying chart
+ chart.setBackgroundBrush(QBrush(QColor(22, 32, 42)))
+ chart_view = QChartView(chart)
+ chart_view.setRenderHint(QPainter.Antialiasing)
+ # chart_view.setMaximumSize(500, 500)
+
+ return chart_view
+
+ def image_load(self):
+ self.left_range = None
+ self.right_range = None
+
+ src = 'rtsp://admin:sijung5520@192.168.100.210/profile2/media.smp'
+ self.get_target(self.current_camera)
+
+ cap = cv2.VideoCapture(src)
+ ret, cv_img = cap.read()
+ self.img = cv2.imread('image.png', cv2.IMREAD_COLOR)
+ # cp_image = cv_img.copy()
+ cap.release()
+
+ # self.image_label.setPixmap(self.convert_cv_qt(cp_image))
+ self.image_label.setPixmap(self.convert_cv_qt(self.img))
+ self.show_target_table()
+ self.chart_update()
+ self.update()
+
+ def convert_cv_qt(self, cv_img):
+ """Convert CV image to QImage."""
+ cv_img = cv_img.copy()
+ cv_img = cv2.cvtColor(cv_img, cv2.COLOR_BGR2RGB)
+
+ self.cp_image = cv_img.copy()
+
+ self.video_height, self.video_width, ch = cv_img.shape
+
+ bytes_per_line = ch * self.video_width
+ convert_to_Qt_format = QImage(cv_img.data, self.video_width, self.video_height,
+ bytes_per_line, QImage.Format_RGB888)
+ p = convert_to_Qt_format.scaled(self.image_label.width(),
+ self.image_label.height(),
+ Qt.IgnoreAspectRatio, Qt.SmoothTransformation)
+
+ return QPixmap.fromImage(p)
+
+ def str_to_tuple(self, before_list):
+ """저장된 타겟들의 위치정보인 튜플 리스트가 문자열로 바뀌어 다시 튜플형태로 변환하는 함수"""
+ tuple_list = [i.split(',') for i in before_list]
+ tuple_list = [(int(i[0][1:]), int(i[1][:-1])) for i in tuple_list]
+ return tuple_list
+
+ # 타겟 조정 및 썸네일 관련 함수 시작
+ def thumbnail_pos(self, end_pos):
+ x = int((end_pos.x() / self.image_label.width()) * self.video_width)
+ y = int((end_pos.y() / self.image_label.height()) * self.video_height)
+ return x, y
+
+ def thumbnail(self, image):
+ height, width, channel = image.shape
+ bytesPerLine = channel * width
+ qImg = QImage(image.data.tobytes(), width, height, bytesPerLine, QImage.Format_RGB888)
+ return qImg
+
+ def save_target(self, camera: str):
+
+ file = f'{camera}.csv'
+ if self.left_range and os.path.isfile(file):
+ col = ['target_name', 'left_range', 'right_range', 'distance', 'azimuth']
+ result = pd.DataFrame(columns=col)
+ result['target_name'] = self.target_name
+ result['left_range'] = self.left_range
+ result['right_range'] = self.right_range
+ result['distance'] = self.distance
+ result['azimuth'] = self.azimuth
+ result.to_csv(file, mode='w', index=False)
+ print(f'[JS-08 Setting SAVED]')
+
+ def get_target(self, camera: str):
+
+ file = f'{camera}.csv'
+
+ # if os.path.isfile(f'{camera}.csv') is False:
+ # result = pd.DataFrame(columns=['target_name', 'left_range', 'right_range', 'distance', 'azimuth'])
+ # result['target_name'] = [1, 2, 3, 4]
+ # result['left_range'] = [(95, 711), (367, 716), (293, 300), (250, 124)]
+ # result['right_range'] = [(31, 831), (279, 836), (236, 350), (148, 211)]
+ # result['distance'] = [0.1, 1.0, 2.0, 3.0]
+ # result['azimuth'] = ['NE', 'NE', 'NE', 'NE']
+ # result.to_csv(file, mode='w', index=False)
+
+ target_df = pd.read_csv(f'{camera}.csv')
+ self.target_name = target_df['target_name'].tolist()
+ self.left_range = self.str_to_tuple(target_df['left_range'].tolist())
+ self.right_range = self.str_to_tuple(target_df['right_range'].tolist())
+ self.distance = target_df['distance'].tolist()
+ self.azimuth = target_df['azimuth'].tolist()
+
+ def get_target_info(self, camera_name: str):
+ """Retrieves target information of a specific camera."""
+
+ file = f'{camera_name}.csv'
+ if os.path.isfile(file):
+ target_df = pd.read_csv(file)
+ target_name = target_df['target_name'].tolist()
+ left_range = self.str_to_tuple(target_df['left_range'].tolist())
+ right_range = self.str_to_tuple(target_df['right_range'].tolist())
+ distance = target_df['distance'].tolist()
+ azimuth = target_df['azimuth'].tolist()
+ return target_name, left_range, right_range, distance, azimuth
+
+ else:
+ return [], [], [], [], []
+
+ def get_target_from_azimuth(self, camera_name: str, azimuth: str):
+ """Retrieves target information from azimuth of a specific camera"""
+
+ file = f'{camera_name}.csv'
+ if os.path.isfile(file):
+ target_df = pd.read_csv(file)
+ azi_target = target_df.loc[(target_df['azimuth'] == f'{azimuth}'), :]
+
+ target_name = azi_target['target_name'].tolist()
+ left_range = self.str_to_tuple(azi_target['left_range'].tolist())
+ right_range = self.str_to_tuple(azi_target['right_range'].tolist())
+ distance = azi_target['distance'].tolist()
+ return target_name, left_range, right_range, distance, azimuth
+
+ else:
+ return [], [], [], [], []
+
+ def print_data(self):
+ epoch = time.strftime('%Y-%m-%d %H:%M:00', time.localtime())
+ # self.movie = QMovie('loading.gif', )
+
+ # Visibility measurement start
+ front_target_name, front_left_range, front_right_range, front_distance, front_azimuth = \
+ self.get_target_info(self.current_camera)
+
+ front_target_name_NE, front_left_range_NE, front_right_range_NE, front_distance_NE, front_azimuth_NE = \
+ self.get_target_from_azimuth(self.current_camera, 'NE')
+ front_target_name_EN, front_left_range_EN, front_right_range_EN, front_distance_EN, front_azimuth_EN = \
+ self.get_target_from_azimuth(self.current_camera, 'EN')
+ front_target_name_ES, front_left_range_ES, front_right_range_ES, front_distance_ES, front_azimuth_ES = \
+ self.get_target_from_azimuth(self.current_camera, 'ES')
+ front_target_name_SE, front_left_range_SE, front_right_range_SE, front_distance_SE, front_azimuth_SE = \
+ self.get_target_from_azimuth(self.current_camera, 'SE')
+
+ visibility_front = self.target_info.minprint(epoch[:-2], front_left_range, front_right_range,
+ front_distance, self.img, self.current_camera)
+ visibility_NE = self.target_info.minprint(epoch[:-2], front_left_range_NE, front_right_range_NE,
+ front_distance_NE, self.img, self.current_camera)
+ visibility_EN = self.target_info.minprint(epoch[:-2], front_left_range_EN, front_right_range_EN,
+ front_distance_EN, self.img, self.current_camera)
+ visibility_ES = self.target_info.minprint(epoch[:-2], front_left_range_ES, front_right_range_ES,
+ front_distance_ES, self.img, self.current_camera)
+ visibility_SE = self.target_info.minprint(epoch[:-2], front_left_range_SE, front_right_range_SE,
+ front_distance_SE, self.img, self.current_camera)
+
+ self.first_vis.setText(f'{round(float(visibility_NE), 2)} km')
+ self.second_vis.setText(f'{round(float(visibility_EN), 2)} km')
+ self.third_vis.setText(f'{round(float(visibility_ES), 2)} km')
+ self.fourth_vis.setText(f'{round(float(visibility_SE), 2)} km')
+ self.vis_result.setText(f'{round(float(visibility_front), 2)} km')
+
+ def accept_click(self):
+ self.save_target(self.current_camera)
+ self.close()
+
+ def reject_click(self):
+ self.close()
+
+ # Event
+ def tableWidget_doubleClicked(self, event):
+ self.select_target = self.tableWidget.currentIndex().row()
+ self.update()
+
+ def load_img_btn(self, event):
+ file = QFileDialog.getOpenFileName(self, '')
+ if file:
+ print(file[0])
+
+ def lbl_paintEvent(self, event):
+ painter = QPainter(self.image_label)
+
+ back_ground_image = self.thumbnail(self.cp_image)
+ bk_image = QPixmap.fromImage(back_ground_image)
+ painter.drawPixmap(QRect(0, 0, self.image_label.width(),
+ self.image_label.height()), bk_image)
+
+ painter.setPen(QPen(Qt.white, 1, Qt.DotLine))
+
+ painter.drawLine((self.image_label.width() * 0.25), 0,
+ (self.image_label.width() * 0.25), self.image_label.height())
+ painter.drawLine((self.image_label.width() * 0.5), 0,
+ (self.image_label.width() * 0.5), self.image_label.height())
+ painter.drawLine((self.image_label.width() * 0.75), 0,
+ (self.image_label.width() * 0.75), self.image_label.height())
+
+ if self.cam_flag:
+ painter.setPen(QPen(Qt.black, 1, Qt.DotLine))
+ painter.drawText(self.image_label.width() * 0.125, 20, 'SW')
+ painter.drawText(self.image_label.width() * 0.375, 20, 'WS')
+ painter.drawText(self.image_label.width() * 0.625, 20, 'WN')
+ painter.drawText(self.image_label.width() * 0.875, 20, 'NW')
+ painter.setPen(QPen(Qt.white, 1, Qt.DotLine))
+ elif self.cam_flag is False:
+ painter.setPen(QPen(Qt.black, 1, Qt.DotLine))
+ painter.drawText(self.image_label.width() * 0.125, 20, 'NE')
+ painter.drawText(self.image_label.width() * 0.375, 20, 'EN')
+ painter.drawText(self.image_label.width() * 0.625, 20, 'ES')
+ painter.drawText(self.image_label.width() * 0.875, 20, 'SE')
+ painter.setPen(QPen(Qt.white, 1, Qt.DotLine))
+
+ if self.left_range and self.right_range:
+ for name, corner1, corner2 in zip(self.target_name, self.left_range, self.right_range):
+ br = QBrush(QColor(100, 10, 10, 40))
+ painter.setBrush(br)
+ painter.setPen(QPen(Qt.red, 2, Qt.SolidLine))
+ corner1_1 = int(corner1[0] / self.video_width * self.image_label.width())
+ corner1_2 = int(corner1[1] / self.video_height * self.image_label.height())
+ corner2_1 = int((corner2[0] - corner1[0]) / self.video_width * self.image_label.width())
+ corner2_2 = int((corner2[1] - corner1[1]) / self.video_height * self.image_label.height())
+ painter.drawRect(QRect(corner1_1, corner1_2, corner2_1, corner2_2))
+ painter.drawText(corner1_1 + corner2_1, corner1_2 - 5, f'{name}')
+
+ if self.isDrawing:
+ br = QBrush(QColor(100, 10, 10, 40))
+ painter.setBrush(br)
+ painter.setPen(QPen(Qt.red, 2, Qt.SolidLine))
+ painter.drawRect(QRect(self.begin, self.end))
+
+ # th_x, th_y = self.thumbnail_pos(self.end)
+ # th_qImage = self.thumbnail(self.cp_image[th_y - 50:th_y + 50, th_x - 50:th_x + 50, :])
+ # thumbnail_image = QPixmap.fromImage(th_qImage)
+ # painter.drawPixmap(QRect(self.end.x(), self.end.y(), 200, 200), thumbnail_image)
+
+ if self.end_drawing:
+ painter.eraseRect(QRect(self.begin, self.end))
+ self.end_drawing = False
+ self.isDrawing = False
+ painter.end()
+
+ def lbl_mousePressEvent(self, event):
+ """마우스 클릭시 발생하는 이벤트, QLabel method overriding"""
+
+ # 좌 클릭시 실행
+ if event.buttons() == Qt.LeftButton:
+ # self.begin = event.globalPosition().toPoint()
+ # self.end = event.globalPosition().toPoint()
+ self.begin = event.pos()
+ self.end = event.pos()
+ self.upper_left = (int((self.begin.x() / self.image_label.width()) * self.video_width),
+ int((self.begin.y() / self.image_label.height()) * self.video_height))
+
+ self.isDrawing = True
+
+ # 우 클릭시 실행
+ elif event.buttons() == Qt.RightButton:
+ text, ok = QInputDialog.getText(self, 'Delete target', 'Input target number to delete')
+ if ok:
+ if text == '':
+ del self.target_name[-1]
+ del self.left_range[-1]
+ del self.right_range[-1]
+ del self.distance[-1]
+ del self.azimuth[-1]
+
+ else:
+ if len(self.target_name) > 0:
+ text = int(text)
+ del self.target_name[text - 1]
+ del self.left_range[text - 1]
+ del self.right_range[text - 1]
+ del self.distance[text - 1]
+ del self.azimuth[text - 1]
+
+ for i in range(len(self.target_name)):
+ self.target_name[i] = i + 1
+
+ self.show_target_table()
+
+ def lbl_mouseMoveEvent(self, event):
+ """마우스가 움직일 때 발생하는 이벤트, QLabel method overriding"""
+ if event.buttons() == Qt.LeftButton:
+ # self.end = event.globalPosition().toPoint()
+ self.end = event.pos()
+ self.image_label.update()
+
+ def lbl_mouseReleaseEvent(self, event):
+ """마우스 클릭이 떼질 때 발생하는 이벤트, QLabel method overriding"""
+ if self.isDrawing:
+ if self.cam_flag:
+ if 0 < self.upper_left[0] <= self.video_width * 0.25:
+ self.azimuth.append('SW')
+ self.current_azi = 'SW'
+ elif self.video_width * 0.25 < self.upper_left[0] <= self.video_width * 0.5:
+ self.azimuth.append('WS')
+ self.current_azi = 'WS'
+ elif self.video_width * 0.5 < self.upper_left[0] <= self.video_width * 0.75:
+ self.azimuth.append('WN')
+ self.current_azi = 'WN'
+ elif self.video_width * 0.75 < self.upper_left[0] <= self.video_width:
+ self.azimuth.append('NW')
+ self.current_azi = 'NW'
+
+ elif self.cam_flag is False:
+ if 0 < self.upper_left[0] <= self.video_width * 0.25:
+ self.azimuth.append('NE')
+ self.current_azi = 'NE'
+ elif self.video_width * 0.25 < self.upper_left[0] <= self.video_width * 0.5:
+ self.azimuth.append('EN')
+ self.current_azi = 'EN'
+ elif self.video_width * 0.5 < self.upper_left[0] <= self.video_width * 0.75:
+ self.azimuth.append('ES')
+ self.current_azi = 'ES'
+ elif self.video_width * 0.75 < self.upper_left[0] <= self.video_width:
+ self.azimuth.append('SE')
+ self.current_azi = 'SE'
+
+ # self.end = event.globalPosition().toPoint()
+ self.end = event.pos()
+ self.image_label.update()
+ self.lower_right = (int((self.end.x() / self.image_label.width()) * self.video_width),
+ int((self.end.y() / self.image_label.height()) * self.video_height))
+
+ # text, ok = QInputDialog.getText(self, '거리 입력', '거리(km)')
+
+ from input_target import InputTarget
+ getText = InputTarget(self.current_azi)
+ if getText.exec():
+ dist, azi = getText.getInputs()
+
+ self.left_range.append(self.upper_left)
+ self.right_range.append(self.lower_right)
+ self.distance.append(dist)
+ self.target_name.append(len(self.left_range))
+
+ self.end_drawing = True
+
+ else:
+ del self.azimuth[-1]
+
+ self.isDrawing = False
+ self.show_target_table()
+
+
+if __name__ == '__main__':
+ import sys
+ from PySide6.QtWidgets import QApplication
+
+ app = QApplication(sys.argv)
+ ui = JS08AdminSettingWidget()
+ ui.show()
+ sys.exit(app.exec())
diff --git a/src/visibility_view.py b/src/visibility_view.py
new file mode 100644
index 0000000..04fa90a
--- /dev/null
+++ b/src/visibility_view.py
@@ -0,0 +1,181 @@
+#!/usr/bin/env python3
+#
+# Copyright 2021-2022 Sijung Co., Ltd.
+#
+# Authors:
+# cotjdals5450@gmail.com (Seong Min Chae)
+# 5jx2oh@gmail.com (Jongjin Oh)
+
+import os
+import sys
+import time
+import collections
+
+import pandas as pd
+from typing import List
+
+from PySide6.QtGui import QPainter, QBrush, QColor
+from PySide6.QtWidgets import QWidget
+from PySide6.QtCore import (Slot, QPointF, QDateTime,
+ QPoint, QTime)
+from PySide6.QtCharts import (QChartView, QLineSeries, QValueAxis,
+ QChart, QDateTimeAxis, QAreaSeries, QSplineSeries)
+
+from model import JS08Settings
+
+
+class VisibilityView(QChartView):
+
+ def __init__(self, parent: QWidget, maxlen: int):
+ super().__init__(parent)
+ self.setRenderHint(QPainter.Antialiasing)
+ self.setMinimumSize(200, 200)
+ self.setMaximumSize(600, 400)
+
+ self.maxlen = maxlen
+ self.i = 0
+
+ # self.chart().hoverEnterEvent(self.hover)
+
+ now = QDateTime.currentSecsSinceEpoch()
+ str_now = str(now)
+ sequence = '0'
+ indicies = (10, 10)
+ now = int(sequence.join([str_now[:indicies[0] - 1], str_now[indicies[1]:]]))
+ self.now = now
+
+ current_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(now))
+ year = current_time[:4]
+ md = current_time[5:7] + current_time[8:10]
+
+ self.setMouseTracking(True)
+
+ chart = QChart()
+ chart.legend().setVisible(False)
+
+ self.setChart(chart)
+ self.chart().setTheme(QChart.ChartThemeDark)
+ self.chart().setBackgroundBrush(QBrush(QColor('#16202a')))
+
+ self.series = QLineSeries(name='Prevailing Visibility')
+ # self.series = QSplineSeries(name='Prevailing Visibility')
+ chart.addSeries(self.series)
+
+ axis_x = QDateTimeAxis()
+ axis_x.setFormat('MM/dd hh:mm')
+ axis_x.setTitleText('Time')
+
+ save_path = os.path.join(f'{JS08Settings.get("data_csv_path")}/Prevailing_Visibility/{year}')
+ file = f'{save_path}/{md}.csv'
+
+ if os.path.isfile(f'{file}') is False:
+ print('NOT FOUND data csv file')
+ zeros = [(t * 1000.0, -1) for t in range(now - maxlen * 60, now, 60)]
+ self.data = collections.deque(zeros, maxlen=maxlen)
+
+ left = QDateTime.fromMSecsSinceEpoch(int(self.data[0][0]))
+ right = QDateTime.fromMSecsSinceEpoch(int(self.data[-1][0]))
+ axis_x.setRange(left, right)
+ chart.setAxisX(axis_x, self.series)
+ else:
+ path = os.path.join(f'{JS08Settings.get("data_csv_path")}/Prevailing_Visibility/{year}')
+ mtime = lambda f: os.stat(os.path.join(path, f)).st_mtime
+ res = list(sorted(os.listdir(path), key=mtime))
+
+ # if len(res) >= 2:
+ # JS08Settings.set('first_step', False)
+
+ result_today = pd.read_csv(file)
+
+ epoch_today = result_today['epoch'].tolist()
+ vis_list_today = result_today['prev'].tolist()
+
+ data = []
+
+ if JS08Settings.get('first_step') is False and len(res) > 1:
+ if md == '0101':
+ save_path = os.path.join(f'{JS08Settings.get("data_csv_path")}/'
+ f'Prevailing_Visibility/{int(year) - 1}')
+
+ yesterday_file = f'{save_path}/{res[-2]}'
+ result_yesterday = pd.read_csv(yesterday_file)
+
+ epoch_yesterday = result_yesterday['epoch'].tolist()
+ vis_list_yesterday = result_yesterday['prev'].tolist()
+
+ for i in range(len(epoch_yesterday)):
+ data.append((epoch_yesterday[i], vis_list_yesterday[i]))
+
+ for i in range(len(epoch_today)):
+ data.append((epoch_today[i], vis_list_today[i]))
+
+ self.data = collections.deque(data, maxlen=180)
+
+ left = QDateTime.fromMSecsSinceEpoch(int(self.data[0][0]))
+ right = QDateTime.fromMSecsSinceEpoch(int(self.data[-1][0]))
+ axis_x.setRange(left, right)
+ chart.setAxisX(axis_x, self.series)
+
+ axis_y = QValueAxis()
+ axis_y.setRange(0, 20)
+ axis_y.setLabelFormat('%d km')
+ axis_y.setTitleText('Distance (km)')
+ chart.setAxisY(axis_y, self.series)
+
+ data_point = [QPointF(t, v) for t, v in self.data]
+ self.series.append(data_point)
+
+ @Slot(float, list)
+ def refresh_stats(self, epoch: float, vis_list: list):
+ if len(vis_list) == 0:
+ vis_list = [0]
+ prev_vis = self.prevailing_visibility(vis_list)
+ self.data.append((epoch, prev_vis))
+
+ left = QDateTime.fromMSecsSinceEpoch(int(self.data[0][0]))
+ right = QDateTime.fromMSecsSinceEpoch(int(self.data[-1][0]))
+
+ self.chart().axisX().setRange(left, right)
+
+ data_point = [QPointF(t, v) for t, v in self.data]
+ self.series.replace(data_point)
+
+ def prevailing_visibility(self, vis: list) -> float:
+ if None in vis:
+ return 0
+
+ sorted_vis = sorted(vis, reverse=True)
+ prevailing = sorted_vis[(len(sorted_vis) - 1) // 2]
+
+ return prevailing
+
+ def wheelEvent(self, event):
+ self.i += 1
+ # print(self.i)
+ self.maxlen += event.angleDelta().y()
+ if self.maxlen <= 0:
+ self.maxlen = 0
+
+ zeros = [(t * 1000.0, -1) for t in range(self.now - self.maxlen * 60, self.now, 60)]
+ self.data = collections.deque(zeros, self.maxlen)
+
+ left = QDateTime.fromMSecsSinceEpoch(int(self.data[0][0]))
+ right = QDateTime.fromMSecsSinceEpoch(int(self.data[-1][0]))
+ # axis_x.setRange(left, right)
+
+ def hover(self, event):
+ print('hi')
+
+
+if __name__ == '__main__':
+ import sys
+ from PySide6.QtWidgets import QApplication, QMainWindow
+
+ app = QApplication(sys.argv)
+ window = QMainWindow()
+ window.resize(600, 400)
+ visibility_view = VisibilityView(window, 180)
+ # visibility_view.refresh_stats(visibility)
+ window.setCentralWidget(visibility_view)
+ window.show()
+ sys.exit(app.exec())
\ No newline at end of file