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; - - - true - - - - 0 - 0 - 1087 - 21 - - - - - 9 - 50 - false - false - - - - false - - - background-color:rgb(27,49,70); -color:#ffffff; - - - false - - - - &File - - - - - - - - - Help - - - - - - &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