Paullux

Untitled

Jun 21st, 2023
48
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 29.14 KB | None | 0 0
  1. import os
  2. import platform
  3. import queue
  4. import random
  5. import sys
  6. import time
  7. import cv2
  8. import re
  9. import numpy as np
  10. import pyvirtualcam
  11. import threading
  12. from PIL import Image, ImageDraw, ImageFont
  13. from PyQt6.QtCore import Qt, QObject, pyqtSignal, QTimer, QThread
  14. from PyQt6 import QtCore
  15. from PyQt6.QtGui import QCloseEvent, QIcon, QImage, QKeyEvent, QPixmap, QColor, QPainter, QFont, QFontDatabase
  16. from PyQt6.QtWidgets import QApplication, QMainWindow, QLabel, QVBoxLayout, QWidget, QComboBox, QPushButton, QFrame
  17.  
  18. class CameraApp(QMainWindow):
  19. def __init__(self, matrix):
  20. self.matrix = matrix
  21. super().__init__()
  22. self.init_ui()
  23.  
  24. if getattr(sys, 'frozen', False):
  25. import pyi_splash
  26.  
  27. # Fermeture du splash screen
  28. pyi_splash.update_text('UI Loaded ...')
  29. pyi_splash.close()
  30.  
  31. print("entre dans la init de CameraApp")
  32. self.cap = None
  33. self.timer = QTimer()
  34.  
  35. def init_ui(self):
  36. print("entre dans init_ui()")
  37. self.setWindowTitle("CameraSelector")
  38. self.setWindowFlags(self.windowFlags() & ~Qt.WindowType.FramelessWindowHint)
  39. self.wd = sys._MEIPASS if getattr(sys, 'frozen', False) else ''
  40. self.setWindowIcon(QIcon(os.path.join(self.wd, "icon-32.png")))
  41. self.layout = QVBoxLayout()
  42. self.central_widget = QWidget()
  43. self.camera_selector = QComboBox()
  44. self.camera_selector.addItem("Caméra non choisie")
  45. self.populate_camera_selector()
  46.  
  47. self.label = QLabel("Sélectionnez une caméra pour commencer")
  48.  
  49. # Créez le bouton et connectez-le à la méthode open_matrix_window
  50. self.open_matrix_button = QPushButton("Ouvrir Matrix")
  51. self.open_matrix_button.clicked.connect(self.camera_chosen)
  52.  
  53. # Ajoutez le bouton à votre interface utilisateur
  54. self.layout.addWidget(self.camera_selector)
  55. self.layout.addWidget(self.label)
  56. self.layout.addWidget(self.open_matrix_button)
  57. self.central_widget.setLayout(self.layout)
  58. self.setCentralWidget(self.central_widget)
  59.  
  60.  
  61. def camera_chosen(self):
  62. index = self.camera_selector.currentIndex()
  63. if index == 0:
  64. self.label.setText("Veuillez choisir une caméra.") # Utilise setText pour mettre à jour le texte du QLabel
  65. return
  66. if self.cap is not None:
  67. self.cap.release()
  68. camera_names, camera_indices = self.get_available_cameras()
  69. camera_name = camera_names[index - 1]
  70. index = camera_indices[index - 1]
  71. self.label.setText(f"Matrix Launched with {camera_name}") # Utilise setText pour mettre à jour le texte du QLabel
  72. self.matrix = matrix
  73. self.matrix.setCameraIndex(index)
  74. #self.matrix.cameraSelected.emit(index) # Émettre le signal avec l'index de la caméra sélectionnée
  75. self.matrix.show() # Affichage de la fenêtre Matrix
  76. print("Matrix Launched")
  77. self.close()
  78.  
  79. def populate_camera_selector(self):
  80. print("entre dans populate_camera_selector()")
  81. camera_names, camera_indices = self.get_available_cameras()
  82. for name, index in zip(camera_names, camera_indices):
  83. self.camera_selector.addItem(f"{name} (Index: {index})", index)
  84. pass
  85.  
  86. def get_available_cameras(self):
  87. print("entre dans get_available_cameras()")
  88. if sys.platform.startswith("linux"):
  89. camera_names, camera_indices = self.get_cameras_linux()
  90. elif sys.platform.startswith("win32"):
  91. camera_names, camera_indices = self.get_cameras_windows()
  92. elif sys.platform.startswith("darwin"): #macOS
  93. camera_names, camera_indices = self.get_cameras_mac()
  94. else:
  95. print("Plateforme non prise en charge")
  96. camera_names, camera_indices = [], []
  97.  
  98. return camera_names, camera_indices
  99.  
  100.  
  101. def get_cameras_mac(self):
  102. print("entre dans get_cameras_mac()")
  103. try:
  104. import Quartz
  105. except ImportError:
  106. print("Installez pyobjc avec 'pip install pyobjc'")
  107. return {}
  108.  
  109. camera_indices = []
  110. camera_names = []
  111.  
  112. for index, device in enumerate(Quartz.IORegistryIteratorCreateForMatchingService(Quartz.kIOMasterPortDefault, Quartz.CFDictionaryCreate(None, (Quartz.kIOUSBDeviceClassName,), (True,), 1))):
  113. camera_name = Quartz.IORegistryEntryGetName(device)
  114. if "infrared" in camera_name.lower() or "ir" in camera_name.lower():
  115. continue # Ignore the infrared camera
  116. camera_names.append(camera_name)
  117. camera_indices.append(index)
  118. return camera_names, camera_indices
  119.  
  120. def get_cameras_windows(self):
  121. print("entre dans get_cameras_windows()")
  122. try:
  123. from pygrabber.dshow_graph import FilterGraph
  124.  
  125. except ImportError:
  126. print("Installez pygrabber avec 'pip install pygrabber'")
  127. return {}
  128.  
  129. camera_indices = []
  130. camera_names = []
  131.  
  132. # Get a list of all connected HID devices
  133. devices = FilterGraph().get_input_devices()
  134.  
  135. camera_names, camera_indices = [], []
  136.  
  137. for device_index, device_name in enumerate(devices):
  138. camera_names.append(device_name)
  139. camera_indices.append(device_index)
  140.  
  141. return camera_names, camera_indices
  142.  
  143.  
  144. def get_cameras_linux(self):
  145. try:
  146. from v4l2py import Device
  147. except ImportError:
  148. print("Installez v4l2py avec 'pip install v4l2py'")
  149. return {}
  150.  
  151. devices = []
  152. camera_names = []
  153. camera_indices = []
  154. index = 0
  155.  
  156. while True:
  157. try:
  158. cap = cv2.VideoCapture(index)
  159. if cap.isOpened():
  160. devices.append(index)
  161. cap.release()
  162. else:
  163. print(f"Avertissement: Impossible d'ouvrir la caméra {index}")
  164. time.sleep(0.1)
  165. index += 1
  166. if index > 9:
  167. break
  168. except Exception as e:
  169. print(f"Erreur lors de l'ouverture des caméras: {e}")
  170. break
  171.  
  172. for index in devices:
  173. print(f"Récupération des informations de la caméra {index}")
  174. try:
  175. with Device.from_id(index) as cam:
  176. cam.open()
  177. camera_name = cam.info.card
  178. if camera_name not in camera_names:
  179. camera_names.append(camera_name)
  180. camera_indices.append(index)
  181. cam.close()
  182. except Exception as e:
  183. print(f"Erreur lors de l'accès à la caméra {index}: {e}")
  184.  
  185. return camera_names, camera_indices
  186.  
  187.  
  188. def closeEvent(self, event):
  189. print("entre dans closeEvent()")
  190. if self.timer.isActive():
  191. self.timer.stop()
  192.  
  193.  
  194. class Communicator(QObject):
  195. update_images_signal = pyqtSignal(np.ndarray)
  196. def __init__(self, parent=None):
  197. super().__init__(parent)
  198.  
  199. class VirtualCameraWorker(QThread):
  200. received_frame = pyqtSignal(np.ndarray)
  201. finished = pyqtSignal()
  202. def __init__(self):
  203. super().__init__()
  204. self.running = True
  205. def process_received_frame(self, virtual_frame):
  206. print("entre dans create_virtual_camera()\n")
  207. if sys.platform.startswith("linux"):
  208. while self.running:
  209. try:
  210. with pyvirtualcam.Camera(width=854, height=480, fps=30, device='/dev/video4') as cam:
  211. cam.send(virtual_frame)
  212. cam.sleep_until_next_frame()
  213. except Exception as e:
  214. print(f"Erreur dans create_virtual_camera: {e}")
  215. pass
  216. elif sys.platform.startswith("win32"):
  217. while self.running:
  218. try:
  219. with pyvirtualcam.Camera(width=854, height=480, fps=30) as cam:
  220. cam.send(virtual_frame)
  221. cam.sleep_until_next_frame()
  222. except Exception as e:
  223. print(f"Erreur dans create_virtual_camera: {e}")
  224. pass
  225.  
  226. def stop(self):
  227. self.running = False
  228. self.finished.emit()
  229.  
  230. class Matrix(QMainWindow):
  231. update_images_signal = pyqtSignal(np.ndarray)
  232. received_frame_signal = pyqtSignal(np.ndarray)
  233. def __init__(self):
  234. super().__init__()
  235. self.threads = []
  236. self.wd = sys._MEIPASS if getattr(sys, 'frozen', False) else ''
  237. self.running = True
  238.  
  239. self.font_path = os.path.join(self.wd, '.', 'mtx.ttf')
  240.  
  241. # Créez une file d'attente pour chaque variable partagée
  242. global columns_launched_queue, frame_queue, ascii_image_result_queue, rain_ascii_image_queue, drop_of_water_image_ascii_queue, virtual_frame_queue, running, UIdefine
  243. columns_launched_queue = queue.Queue()
  244. frame_queue = queue.Queue()
  245. ascii_image_result_queue = queue.Queue()
  246. rain_ascii_image_queue = queue.Queue()
  247. drop_of_water_image_ascii_queue = queue.Queue()
  248. virtual_frame_queue = queue.Queue()
  249. self.queues = [columns_launched_queue, frame_queue, ascii_image_result_queue, rain_ascii_image_queue, drop_of_water_image_ascii_queue, virtual_frame_queue]
  250.  
  251. running = True
  252. self.UIdefine = False
  253.  
  254.  
  255. if sys.platform == 'win32':
  256. # import ctypes
  257. import ctypes
  258. winVer = platform.win32_ver(release='')[0]
  259. try:
  260. if int(winVer) >= 10:
  261. ctypes.windll.shcore.SetProcessDpiAwareness(2)
  262. elif int(winVer) == 8:
  263. ctypes.windll.shcore.SetProcessDpiAwareness(1)
  264. else:
  265. ctypes.windll.user32.SetProcessDPIAware()
  266. except (ImportError, AttributeError, OSError):
  267. pass
  268.  
  269. self.counter = 0
  270. self.timer = QTimer(self)
  271. self.image_label = QLabel()
  272. self.timer.timeout.connect(self.update_counter)
  273. self.timer.start(1000)
  274.  
  275. # Définition des caractères à utiliser pour l'ASCII art
  276. #characters = ' ú.ù,:öøýü×Öų·ÈØÙÍб´¶¹º¼Â²ÇËÒÓ¾Ú'
  277.  
  278. self.rain_intensity = 0.5
  279. self.image_updated = ""
  280.  
  281. width, height = 854, 480
  282.  
  283. self.ascii_font_size_width = 20
  284. self.ascii_font_size_height = self.ascii_font_size_width * 9 / 16
  285.  
  286. self.font_path = os.path.join(self.wd, 'mtx.ttf')
  287. self.canvas_image = Image.new('RGB', (width, height), 'black')
  288. self.draw = ImageDraw.Draw(self.canvas_image)
  289. self.font = ImageFont.truetype(self.font_path, self.ascii_font_size_width)
  290.  
  291. # Variables partagées entre les threads
  292. self.ascii_image = ""
  293. ascii_image_result, rain_ascii_image, rain_ascii_image_result, drop_of_water_image_ascii = "", "","", ""
  294. # initialisation des ascii art
  295. for line in range(0, 106):
  296. for column in range(0, 106):
  297. ascii_image_result += ' '
  298. rain_ascii_image += ' '
  299. rain_ascii_image_result += ' '
  300. drop_of_water_image_ascii += ' '
  301. ascii_image_result += '\n'
  302. rain_ascii_image += '\n'
  303. rain_ascii_image_result += '\n'
  304. drop_of_water_image_ascii += '\n'
  305.  
  306. self.worker_thread = VirtualCameraWorker()
  307. self.worker_thread.finished.connect(self.on_virtual_camera_finished)
  308. self.worker_thread.received_frame.connect(self.process_received_frame)
  309. self.received_frame_signal.connect(self.worker_thread.process_received_frame)
  310.  
  311. self.update_images_signal.connect(self.update_image_label)
  312.  
  313. self.start_virtual_camera()
  314.  
  315. def start_virtual_camera(self):
  316. self.worker_thread.start()
  317.  
  318. def process_received_frame(self, frame):
  319. # Traitement du frame reçu
  320. self.update_images_signal.emit(frame)
  321.  
  322. def on_virtual_camera_finished(self):
  323. print("Caméra virtuelle terminée")
  324.  
  325.  
  326. @QtCore.pyqtSlot(np.ndarray, result=bool)
  327. def emit_update_images_signal(self, virtual_frame: np.ndarray):
  328. self.update_images_signal.emit(virtual_frame)
  329. self.received_frame_signal.emit(virtual_frame)
  330.  
  331. def update_image_label(self, virtual_frame):
  332. rgb_image = cv2.cvtColor(virtual_frame, cv2.COLOR_BGR2RGB)
  333. h, w, ch = rgb_image.shape
  334. bytes_per_line = ch * w
  335. qimage = QImage(rgb_image.data, w, h, bytes_per_line, QImage.Format.Format_RGB888)
  336. self.image_label.setPixmap(QPixmap.fromImage(qimage))
  337.  
  338. def update_counter(self):
  339. print("entre dans update_counter()\n")
  340. self.counter += 1
  341. self.counter_string = str(self.counter)
  342.  
  343. if random.randint(0, 9) % 2 == 0:
  344. self.counter_string = self.counter_string.replace("0", "¦")
  345. if random.randint(0, 9) % 2 == 0:
  346. self.counter_string = self.counter_string.replace("1","§")
  347. if random.randint(0, 9) % 2 == 0:
  348. self.counter_string = self.counter_string.replace("2", "¨")
  349. if random.randint(0, 9) % 2 == 0:
  350. self.counter_string = self.counter_string.replace("3", "©")
  351. if random.randint(0, 9) % 2 == 0:
  352. self.counter_string = self.counter_string.replace("4", "ª")
  353. if random.randint(0, 9) % 2 == 0:
  354. self.counter_string = self.counter_string.replace("5", "«")
  355. if random.randint(0, 9) % 2 == 0:
  356. self.counter_string = self.counter_string.replace("6", "¬")
  357. if random.randint(0, 9) % 2 == 0:
  358. self.counter_string = self.counter_string.replace("8", "®")
  359. if random.randint(0, 9) % 2 == 0:
  360. self.counter_string = self.counter_string.replace("9", "¯")
  361.  
  362.  
  363. pixmap = QPixmap(854, 480) # Créez un QPixmap de la taille souhaitée
  364. pixmap.fill(QColor(0,0,0)) # Remplissez-le avec une couleur transparente
  365.  
  366. painter = QPainter(pixmap)
  367.  
  368. font_id = QFontDatabase.addApplicationFont(self.font_path)
  369. if font_id < 0: print("Error")
  370. families = QFontDatabase.applicationFontFamilies(font_id)
  371. painter.setFont(QFont(families[0], 40))
  372. painter.setPen(QColor("#008800"))
  373.  
  374. self.counter_txt = "C O M P T E U R : "
  375.  
  376. if random.randint(0, 9) % 2 == 0:
  377. self.counter_txt = self.counter_txt.replace("C", "Ý")
  378. if random.randint(0, 9) % 2 == 0:
  379. self.counter_txt = self.counter_txt.replace("M", "ç")
  380. if random.randint(0, 9) % 2 == 0:
  381. self.counter_txt = self.counter_txt.replace("P", "ê")
  382. if random.randint(0, 9) % 2 == 0:
  383. self.counter_txt = self.counter_txt.replace("T", "î")
  384. if random.randint(0, 9) % 2 == 0:
  385. self.counter_txt = self.counter_txt.replace("E", "ß")
  386. if random.randint(0, 9) % 2 == 0:
  387. self.counter_txt = self.counter_txt.replace("U", "ï")
  388. if random.randint(0, 9) % 2 == 0:
  389. self.counter_txt = self.counter_txt.replace("R", "ì")
  390.  
  391.  
  392. print(self.counter_txt + self.counter_string)
  393.  
  394. painter.drawText(pixmap.rect(), Qt.AlignmentFlag.AlignCenter, self.counter_txt + self.counter_string)
  395.  
  396. painter.end()
  397. if random.randint(0, 9) % 3 == 0:
  398. pass #self.image_label.setPixmap(pixmap)
  399.  
  400. def launch_threads(self):
  401. print("entre dans launch_multithread()\n")
  402. self.methods = [
  403. self.capture_frame,
  404. self.update_ascii_image,
  405. self.create_rain_drops,
  406. self.send_to_virtual_camera
  407. ]
  408.  
  409. # Lancement des threads
  410. count = 1
  411. for method in self.methods:
  412. thread = threading.Thread(target=method)
  413. thread.start()
  414. print(f"{method.__name__} dans le thread {count}\n")
  415. self.threads.append(thread)
  416. count += 1
  417.  
  418.  
  419. def setCameraIndex(self, index):
  420. global cap
  421. print("entre dans setCameraIndex()\n")
  422. print(f"Caméra sélectionnée : {index}")
  423. self.camera_index = index
  424. print(f"Setting camera with index {self.camera_index}")
  425.  
  426. # Create a new instance of cv2.VideoCapture with the selected camera index
  427. # Open the camera
  428. if platform.system() == 'Windows':
  429. self.cap = cv2.VideoCapture(self.camera_index, cv2.CAP_DSHOW)
  430. else:
  431. self.cap = cv2.VideoCapture(self.camera_index)
  432.  
  433. self.cap.set(cv2.CAP_PROP_FRAME_WIDTH, 854)
  434. self.cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)
  435. self.capture_fps = 30
  436. cap = self.cap
  437. time.sleep(1)
  438. self.initUI()
  439.  
  440. def stop(self):
  441. print("entre dans stop()\n")
  442. global running
  443. running = False
  444. self.worker_thread = VirtualCameraWorker()
  445. self.worker_thread.stop()
  446. for queue in self.queues:
  447. for _ in range(3):
  448. queue.put(None)
  449. queue.queue.clear()
  450. #print("Toutes les Files d'Attentes ont étées vidées\n")
  451. for thread in self.threads:
  452. thread.join(timeout=.25)
  453. time.sleep(.251)
  454. #print("Tous les Multiples Threads ont étés arrêtées\n")
  455. sys.exit(0)
  456.  
  457. def closeEvent(self, event: QCloseEvent):
  458. global running
  459. print("entre dans closeEvent()\n")
  460. running = False
  461. self.worker_thread = VirtualCameraWorker()
  462. self.worker_thread.stop()
  463. for queue in self.queues:
  464. for _ in range(3):
  465. queue.put(None)
  466. queue.queue.clear()
  467. #print("Toutes les Files d'Attentes ont étées vidées\n")
  468. for thread in self.threads:
  469. thread.join(timeout=.25)
  470. time.sleep(.251)
  471. #print("Tous les Multiples Threads ont étés arrêtées\n")
  472. sys.exit(0)
  473.  
  474. def keyPressEvent(self, event: QKeyEvent):
  475. global running
  476. print("entre dans keyPressEvent()\n")
  477. self.worker_thread = VirtualCameraWorker()
  478. self.worker_thread.stop()
  479. if event.key() == Qt.Key.Key_Escape:
  480. running = False
  481. self.stop()
  482. self.closeEvent()
  483. else:
  484. super(Matrix, self).keyPressEvent(event)
  485.  
  486.  
  487. def initUI(self):
  488. print("entre dans initUI()\n")
  489. self.setWindowFlags(self.windowFlags() & ~Qt.WindowType.FramelessWindowHint)
  490.  
  491. frame = QFrame(self)
  492. frame.setFrameStyle(QFrame.Shape.NoFrame)
  493.  
  494. # Appliquez le layout au widget central
  495. self.window_icon = QIcon(os.path.join(self.wd, "icon-32.png"))
  496. self.setWindowIcon(self.window_icon)
  497. self.setWindowTitle("Matrix")
  498. self.setGeometry(300, 300, 854, 480)
  499. self.setStyleSheet("background-color: black;")
  500.  
  501. # Créez une instance de QWidget
  502. self.central_widget = QWidget()
  503. # Définissez le widget central
  504. self.setCentralWidget(self.central_widget)
  505.  
  506. self.central_widget.setStyleSheet("background-color: black;")
  507.  
  508. # Utilisez le QWidget central comme parent pour le QVBoxLayout
  509. self.layout = QVBoxLayout(self.central_widget)
  510.  
  511. # Instanciez QLabel et assignez-le à self.image_label
  512. self.image_label = QLabel()
  513. self.image_label.setStyleSheet("background-color: black;")
  514.  
  515. # Créez une QPixmap vide de taille 854x480
  516. pixmap = QPixmap(854, 480)
  517. pixmap.fill(QColor(0, 0, 0))
  518.  
  519. # Attribuez la QPixmap au QLabel
  520. self.image_label.setPixmap(pixmap)
  521.  
  522. # Ajoutez le QLabel image_label au layout
  523. self.layout.addWidget(self.image_label)
  524.  
  525. # self.setLayout(self.layout)
  526.  
  527. #self.launch_multithread()
  528. self.show()
  529. self.camera_app = CameraApp(self)
  530. self.camera_app.close()
  531.  
  532. #global UIdefine
  533. self.UIdefine = True
  534.  
  535. # Fonction pour convertir une intensité en caractère ASCII
  536. def get_character(self, intensity):
  537. characters = ' ú.ù,:öøýü×Öų·ÈØÙÍб´¶¹º¼Â²ÇËÒÓ¾Ú'
  538. num_levels = len(characters)
  539. level = intensity * (num_levels - 1) // 255
  540. return characters[level]
  541.  
  542. # Fonction pour convertir une image en ASCII artq
  543. def image_to_ascii(self, image):
  544. ascii_font_size_width = 8
  545. ascii_font_size_height = ascii_font_size_width * 9 / 16
  546. ratio = 1.725
  547. try:
  548. if len(image.shape) > 2 and image.shape[2] == 3:
  549. gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
  550. else:
  551. gray_image = image
  552. resized_image = cv2.resize(gray_image, (int(gray_image.shape[1] / (ratio * ascii_font_size_height)), int(gray_image.shape[0] / (ratio * ascii_font_size_width))))
  553. ascii_image = ""
  554. for i in range(resized_image.shape[0]):
  555. for j in range(resized_image.shape[1]):
  556. intensity = resized_image[i][j]
  557. ascii_image += self.get_character(intensity)
  558. ascii_image += "\n"
  559. return ascii_image
  560. except Exception as e:
  561. print(f"Erreur dans image_to_ascii: {e}")
  562.  
  563. # créer l'effets de pluie
  564. def create_rain_drops(self):
  565. global rain_ascii_image_queue, drop_of_water_image_ascii_queue, running
  566. print("on rentre dans rain_drops()")
  567. drop_positions = np.zeros(854, dtype=int)
  568. drop_of_water_image = np.zeros((480, 854), dtype=np.uint8)
  569. blank_image = np.zeros((480, 854), dtype=np.uint8)
  570. drop_columns = []
  571. try:
  572. while running:
  573. if len(drop_columns) < 80:
  574. column = random.randint(0, blank_image.shape[1] - 1)
  575. drop_columns.append(column)
  576. drop_positions[column] = 0
  577. for column in drop_columns:
  578. row = drop_positions[column]
  579. if row >= blank_image.shape[0] - 1:
  580. drop_columns.remove(column)
  581. for row_to_erase in range(0, row):
  582. if row_to_erase < 480:
  583. blank_image[row_to_erase][column] = 0
  584. else:
  585. row += 1
  586. drop_positions[column] = row
  587. for row_line in range(0, row):
  588. blank_image[row_line][column] = 255
  589. row_drop = row + 2
  590. if row_drop < 480:
  591. for row_erase in range(0, row_drop):
  592. drop_of_water_image[row_erase][column] = 0
  593. for row_create in range(row_drop-2, row_drop + 5):
  594. if row_create < 480:
  595. drop_of_water_image[row_create][column] = 255
  596.  
  597. rain_ascii_image = self.image_to_ascii(blank_image)
  598. drop_of_water_image_ascii = self.image_to_ascii(drop_of_water_image)
  599.  
  600. drop_of_water_image_ascii_queue.put(drop_of_water_image_ascii)
  601. rain_ascii_image_queue.put(rain_ascii_image)
  602.  
  603. except Exception as e:
  604. print(f"Erreur dans create_rain_drops: {e}")
  605.  
  606. # Fonction pour mettre à jour l'image capturée
  607. def capture_frame(self):
  608. global frame_queue, cap, running
  609. print("entre dans capture_frame()\n" + str(running))
  610. wd = sys._MEIPASS if getattr(sys, 'frozen', False) else ''
  611. width, height = 854, 480
  612. logo = cv2.imread(os.path.join(wd, 'MatrixLogo.png'))
  613. size1, size2 = 854, 150
  614. logo = cv2.resize(logo, (size1, size2))
  615. message = True
  616. get_camera = False
  617. while running:
  618. try:
  619. if not (cap is None):
  620. capture = cap
  621. if not get_camera:
  622. print(f"Dans capture_frame: La camera est définit")
  623. get_camera = True
  624. ret, frame = capture.read()
  625. f = frame
  626. if ret:
  627. # Redimensionner l'image capturée pour qu'elle s'adapte aux dimensions du canevas
  628. resized_frame = cv2.resize(f, (width, height))
  629. # Créer un canevas vide
  630. canvas = np.zeros((height, width, 3), dtype=np.uint8)
  631. # Calculer les coordonnées pour placer le logo au centre du canevas
  632. logo_x = int((width - size1) / 2)
  633. logo_y = 0
  634. # Dessiner le logo sur le canevas
  635. canvas[logo_y:logo_y+size2, logo_x:logo_x+size1] = logo
  636. # Combiner le canevas avec l'image capturée redimensionnée
  637. combined_frame = cv2.addWeighted(resized_frame, .5, canvas, 1, 0)
  638.  
  639. frame = combined_frame
  640. frame_queue.put(frame)
  641.  
  642. except Exception as e:
  643. if message:
  644. print(f"Erreur dans capture_frame: {e}")
  645. message = False
  646.  
  647. # Fonction pour mettre à jour l'image ASCII
  648. def update_ascii_image(self):
  649. global frame_queue, ascii_image_result_queue, running
  650. frame = None
  651. try:
  652. print("entre dans update_ascii_image()\n" + str(running))
  653. while running:
  654. if not frame_queue.empty():
  655. while not frame_queue.empty():
  656. frame = frame_queue.get()
  657. else:
  658. pass
  659. f = frame
  660. if f is not None:
  661. y_image = self.image_to_ascii(f)
  662. ascii_image_result = y_image
  663. ascii_image_result_queue.put(ascii_image_result)
  664. time.sleep(0.001)
  665. except Exception as e:
  666. print(f"Erreur dans update_ascii_image: {e}")
  667.  
  668. def send_to_virtual_camera(self):
  669. global ascii_image_result_queue, rain_ascii_image_queue, drop_of_water_image_ascii_queue, virtual_frame_queue, running
  670. width, height = 854, 480
  671. ascii_font_size_width = 16
  672. wd = sys._MEIPASS if getattr(sys, 'frozen', False) else ''
  673. font_path = os.path.join(wd, '.', 'mtx.ttf')
  674.  
  675. # Initialisez les variables avec des valeurs par défaut
  676. ascii_image_result = ""
  677. rain_ascii_image = ""
  678. drop_of_water_image_ascii = ""
  679. first = True
  680. while running:
  681. try:
  682. print("entre dans send_to_virtual_camera()\n" + str(running))
  683.  
  684. if not ascii_image_result_queue.empty():
  685. while not ascii_image_result_queue.empty():
  686. ascii_image_result = ascii_image_result_queue.get()
  687. else:
  688. pass
  689.  
  690. if not drop_of_water_image_ascii_queue.empty():
  691. drop_of_water_image_ascii = drop_of_water_image_ascii_queue.get()
  692. else:
  693. pass
  694.  
  695. if not rain_ascii_image_queue.empty():
  696. rain_ascii_image = rain_ascii_image_queue.get()
  697. else:
  698. pass
  699.  
  700. canvas_image = Image.new('RGB', (width, height), 'black')
  701. draw = ImageDraw.Draw(canvas_image)
  702. font = ImageFont.truetype(font_path, ascii_font_size_width)
  703. draw.text((0, 0), ascii_image_result, fill='#006600', font=font)
  704. draw.text((0, 0), rain_ascii_image, fill='#00ff00', font=font)
  705. draw.text((0, 0), drop_of_water_image_ascii, fill='white', font=font)
  706. virtual_frame = cv2.cvtColor(np.array(canvas_image), cv2.COLOR_RGB2BGR)
  707.  
  708. if self.UIdefine:
  709. QtCore.QMetaObject.invokeMethod(self, 'emit_update_images_signal', Qt.ConnectionType.QueuedConnection, QtCore.Q_ARG(np.ndarray, virtual_frame))
  710.  
  711. virtual_frame_queue.put(virtual_frame)
  712.  
  713. except Exception as e:
  714. print(f"Erreur dans send_to_virtual_camera: {e}")
  715.  
  716. if __name__ == "__main__":
  717. app = QApplication([])
  718. matrix = Matrix()
  719. camera_app = CameraApp(matrix)
  720. matrix.hide()
  721. camera_app.show()
  722. matrix.launch_threads() # Appel de la méthode de lancement des threads
  723. app.exec()
Advertisement
Add Comment
Please, Sign In to add comment