Analiza kodu źródłowego
Kluczowe komponenty
ASCII_CHARS = "@%#*+=-:. "
Zestaw znaków ASCII uporządkowany od najciemniejszych do najjaśniejszych dla precyzyjnej konwersji jasności
frame = cv2.flip(frame, 1)
Korekcja efektu lustra - odwrócenie obrazu w poziomie dla naturalnego widoku
ratio = height / width / 0.55
Współczynnik korekcji proporcji - kompensuje różnicę proporcji znaków ASCII vs pikseli
pool = mp.Pool(self.split)
Tworzenie puli procesów - kluczowy element optymalizacji wydajności przez wykorzystanie wielu rdzeni CPU
+---------------------+
| Kamera web |
+----------+----------+
|
v
+---------------------+
| Przechwycenie klatki|
| (OpenCV) |
+----------+----------+
|
v
+---------------------+
| Podział na fragmenty|
| (wielowątkowość) |
+----------+----------+
|
v
+---------------------+
| Konwersja na ASCII |
| (przetwarzanie GPU) |
+----------+----------+
|
v
+---------------------+
| Renderowanie |
| w terminalu |
+---------------------+
Schemat architektury przetwarzania
Optymalizacje
- Pool procesów - dynamiczne dopasowanie liczby rdzeni do mocy obliczeniowej
- Buforowanie klatek - minimalizacja opóźnień poprzez asynchroniczne przetwarzanie
- Tryb konturowy - redukcja obliczeń o 60% dla szybszego renderowania
- Kompresja kolorów - optymalizacja palety ANSI dla różnych terminali
Omówienie kodu — krok po kroku
- Importy i inicjalizacja: moduły (OpenCV, NumPy, multiprocessing, colorama) są ładowane; `colorama.init()` włącza kolorowanie konsoli. Na Windows opcjonalnie używany jest `msvcrt` do nieblokującego odczytu klawiszy.
- Zestawy znaków ASCII: słownik `ASCII_SETS` / stała `ASCII_CHARS` definiuje znaki od najciemniejszych do najjaśniejszych — to mapa jasności → znak.
- frame_to_ascii(): główna funkcja konwersji jednej klatki:
- flip obrazu (usuwa efekt lustra),
- dostosowanie jasności/kontrastu i opcjonalne wyostrzanie,
- skalowanie do zadanej szerokości z korekcją proporcji (współczynnik ~0.55),
- konwersja do skali szarości,
- mapowanie wartości pikseli na znaki ASCII oraz (opcjonalnie) wstawienie kodów kolorów ANSI lub trybu konturowego.
- render_chunk(): wrapper używany przez pulę procesów — przyjmuje fragment obrazu i parametry, wywołuje `frame_to_ascii()` i zwraca tekst ASCII.
- Klasa `ASCIICam`: zarządza ustawieniami i interfejsem tekstowym:
- `main_menu()` — prosty menu CLI (start, ustawienia, wyjście),
- `settings_menu()` — zmiana parametrów: szerokość, zestaw znaków, kolor, kontur, jasność, kontrast, wyostrzanie, liczba rdzeni, FPS, indeks kamery, itp.,
- `start_camera()` — otwiera strumień kamery, tworzy pulę procesów `mp.Pool(self.split)` i w pętli:
- czyta klatkę z kamery,
- dzieli ją na `self.split` fragmentów (np. wiersze) przy użyciu `np.array_split`,
- wywołuje `pool.map(render_chunk, args)` — równoległe przetwarzanie fragmentów,
- skleja wyniki w całość, oblicza i opcjonalnie dopisuje FPS,
- steruje tempem za pomocą `time.sleep()` aby osiągnąć `target_fps`,
- czyści terminal i wypisuje wynik,
- obsługuje zatrzymanie przez klawisz `q` (msvcrt lub select/termios) oraz `cv2.waitKey` fallback.
- Obsługa błędów i zamykanie: w blokach try/except logowane są błędy, w `finally` zasoby (kamera, pula) są zamykane, a ustawienia terminala przywracane dla Unix.
- Uruchomienie: w `if __name__ == "__main__"` wyświetlane jest ostrzeżenie o trybie kolorowym, tworzony jest obiekt `ASCIICam()` i uruchamiane `main_menu()`.
To omówienie obejmuje zarówno stabilne wydanie (main_ver1.0.py), jak i wersję preview. Różnice: nowsza wersja rozszerza parametry (jasność, kontrast, wyostrzanie, wybór zestawu znaków) oraz dodaje lepsze zarządzanie wielowątkowością i obsługę FPS.