import os import re import shutil import math import textwrap import platform import subprocess import webbrowser from difflib import SequenceMatcher from importlib_metadata import version as get_package_version from typing import Iterator, Tuple try: import psutil except ImportError: psutil = None def format_bold(text): return f"\033[1m{text}\033[0m" def format_color(text, color_code): return f"\033[{color_code}m{text}\033[0m" def gradient_text( text: str, start_color: Tuple[int, int, int] = (0, 0, 255), end_color: Tuple[int, int, int] = (255, 0, 255), frequency: float = 1.0, ) -> str: def color_function(t: float) -> Tuple[int, int, int]: def interpolate(start: float, end: float, t: float) -> float: # Use a sine wave for smooth, periodic interpolation return ( start + (end - start) * (math.sin(math.pi * t * frequency) + 1) / 2 ) return tuple( round(interpolate(s, e, t)) for s, e in zip(start_color, end_color) ) def gradient_gen(length: int) -> Iterator[Tuple[int, int, int]]: return (color_function(i / (length - 1)) for i in range(length)) gradient = gradient_gen(len(text)) return "".join( f"\033[38;2;{r};{g};{b}m{char}\033[0m" for char, (r, g, b) in zip(text, gradient) ) # noqa: E501 def hex_to_rgb(hex_color): hex_color = hex_color.lstrip("#") return tuple(int(hex_color[i : i + 2], 16) for i in (0, 2, 4)) def indent_text(text, indent=4): return textwrap.indent(text, " " * indent) def is_chinese(s="人工智能"): # Is string composed of any Chinese characters? return bool(re.search("[\u4e00-\u9fff]", str(s))) def is_possible_rectangle(points): if len(points) != 4: return False # Check if four points form a rectangle # The points are expected to be in the format: # [[x1, y1], [x2, y2], [x3, y3], [x4, y4]] dists = [square_dist(points[i], points[(i + 1) % 4]) for i in range(4)] dists.sort() # For a rectangle, the two smallest distances # should be equal and the two largest should be equal return dists[0] == dists[1] and dists[2] == dists[3] def square_dist(p, q): # Calculate the square distance between two points return (p[0] - q[0]) ** 2 + (p[1] - q[1]) ** 2 def collect_system_info(): os_info = platform.platform() cpu_info = platform.processor() cpu_count = os.cpu_count() if psutil: gib = 1 << 30 ram = psutil.virtual_memory().total ram_info = f"{ram / gib:.1f} GB" total, used, free = shutil.disk_usage("/") disk_info = f"{(total - free) / gib:.1f}/{total / gib:.1f} GB" else: ram_info = "N/A (psutil not installed)" disk_info = "N/A (psutil not installed)" gpu_info = get_gpu_info() cuda_info = get_cuda_version() python_info = platform.python_version() pyqt5_info = get_installed_package_version("PyQt5") onnx_info = get_installed_package_version("onnx") ort_info = get_installed_package_version("onnxruntime") ort_gpu_info = get_installed_package_version("onnxruntime-gpu") opencv_contrib_info = get_installed_package_version( "opencv-contrib-python-headless" ) system_info = { "Operating System": os_info, "CPU": cpu_info, "CPU Count": cpu_count, "RAM": ram_info, "Disk": disk_info, "GPU": gpu_info, "CUDA": cuda_info, "Python Version": python_info, } pkg_info = { "PyQt5 Version": pyqt5_info, "ONNX Version": onnx_info, "ONNX Runtime Version": ort_info, "ONNX Runtime GPU Version": ort_gpu_info, "OpenCV Contrib Python Headless Version": opencv_contrib_info, } return system_info, pkg_info def find_most_similar_label(text, valid_labels): max_similarity = 0 most_similar_label = valid_labels[0] for label in valid_labels: similarity = SequenceMatcher(None, text, label).ratio() if similarity > max_similarity: max_similarity = similarity most_similar_label = label return most_similar_label def get_installed_package_version(package_name): try: return get_package_version(package_name) except Exception: return None def get_cuda_version(): try: nvcc_output = subprocess.check_output(["nvcc", "--version"]).decode( "utf-8" ) version_line = next( (line for line in nvcc_output.split("\n") if "release" in line), None, ) if version_line: return version_line.split()[-1] except Exception: return None def get_gpu_info(): try: smi_output = subprocess.check_output( [ "nvidia-smi", "--query-gpu=index,name,memory.total", "--format=csv,noheader,nounits", ], encoding="utf-8", ) gpu_info_lines = [] for line in smi_output.strip().split("\n"): parts = line.split(",") if len(parts) == 3: index = parts[0].strip() name = parts[1].strip() memory = parts[2].strip() + "MiB" gpu_info_lines.append(f"CUDA:{index} ({name}, {memory})") return ", ".join(gpu_info_lines) except Exception: return None def open_url(url: str) -> None: """Open URL in browser while suppressing TTY warnings""" try: if platform.system() == "Linux": # Check if running in WSL with open("/proc/version", "r") as f: if "microsoft" in f.read().lower(): # Use powershell.exe for WSL subprocess.run( [ "powershell.exe", "-Command", f'Start-Process "{url}"', ] ) else: # For native Linux, use xdg-open subprocess.run( ["xdg-open", url], stderr=subprocess.DEVNULL ) else: webbrowser.open(url) except Exception: # Fallback to regular webbrowser.open webbrowser.open(url)