2019-10-23 20:10:03 +00:00
|
|
|
import cv2
|
2019-08-15 13:19:23 +00:00
|
|
|
from PIL import Image
|
|
|
|
import numpy as np
|
2019-10-23 20:10:03 +00:00
|
|
|
import PySimpleGUI as sg
|
2019-08-15 13:19:23 +00:00
|
|
|
|
|
|
|
"""
|
|
|
|
Interesting program that shows your webcam's image as ASCII text. Runs in realtime, producing a stream of
|
|
|
|
images so that it is actually animated ASCII text. Wild stuff that came about from a post on Reddit of all
|
|
|
|
places. The software bits that turn the image into ASCII text were shamelessly taken from this gist:
|
|
|
|
https://gist.github.com/cdiener/10491632
|
|
|
|
Brilliant work to have pulled off so much with so little Numpy
|
|
|
|
What's remarkable about this program is that the animation is created by updating individual Text Elements going
|
|
|
|
down the window, one line at a time, every time through the loop. That's 48 lines of text every time. Rough
|
|
|
|
timing shows an animation of more than 10 fps when running any of the PySimpleGUI ports.
|
2019-08-15 23:36:32 +00:00
|
|
|
Also added onto this are a spinner and a slider. They do essentially the same thing, enable a pair of parameters
|
|
|
|
to be modified on the fly.
|
2019-08-16 02:18:51 +00:00
|
|
|
|
|
|
|
You need PySimpleGUI installed as well as OpenCV. Both are easily installed via pip:
|
|
|
|
pip install PySimpleGUI
|
|
|
|
pip install opencv-python
|
|
|
|
|
|
|
|
On Linux / Mac use pip3 instead of pip
|
2022-06-22 19:45:52 +00:00
|
|
|
|
|
|
|
Copyright 2022, PySimpleGUI
|
2019-08-15 13:19:23 +00:00
|
|
|
"""
|
|
|
|
|
|
|
|
# The magic bits that make the ASCII stuff work shamelessly taken from https://gist.github.com/cdiener/10491632
|
|
|
|
chars = np.asarray(list(' .,:;irsXA253hMHGS#9B&@'))
|
|
|
|
SC, GCF, WCF = .1, 1, 7/4
|
|
|
|
|
2022-06-22 19:45:52 +00:00
|
|
|
sg.theme('Black') # make it look cool with white chars on black background
|
|
|
|
font_size = 6
|
2019-08-15 13:19:23 +00:00
|
|
|
|
|
|
|
# define the window layout
|
2019-10-23 20:10:03 +00:00
|
|
|
# number of lines of text elements. Depends on cameras image size and the variable SC (scaller)
|
|
|
|
NUM_LINES = 48
|
2019-08-16 15:51:49 +00:00
|
|
|
|
2022-06-22 19:45:52 +00:00
|
|
|
layout = [[[sg.Text(i, font=('Courier', font_size), pad=(0, 0), key=('-OUT-', i))] for i in range(NUM_LINES)],
|
|
|
|
[sg.Text('GCF', s=9, justification='r'), sg.Slider((0.1, 20), resolution=.05, default_value=1, orientation='h', key='-SPIN-GCF-', size=(15, 15))],
|
|
|
|
[sg.Text('Font Size', s=9, justification='r'), sg.Slider((4, 20), resolution=1, default_value=font_size, orientation='h', key='-FONT SIZE-', size=(15, 15)),
|
|
|
|
sg.Push(), sg.Button('Exit')]]
|
2019-08-15 13:19:23 +00:00
|
|
|
|
|
|
|
# create the window and show it without the plot
|
2022-06-22 19:45:52 +00:00
|
|
|
window = sg.Window('Demo Application - OpenCV - ASCII Chars Output', layout, font='Any 18', resizable=True)
|
2019-08-15 13:19:23 +00:00
|
|
|
|
|
|
|
# ---===--- Event LOOP Read and display frames, operate the GUI --- #
|
2019-10-23 20:10:03 +00:00
|
|
|
# Setup the OpenCV capture device (webcam)
|
2022-06-22 19:45:52 +00:00
|
|
|
|
2019-10-23 20:10:03 +00:00
|
|
|
cap = cv2.VideoCapture(0)
|
2022-06-22 19:45:52 +00:00
|
|
|
|
2019-08-15 13:19:23 +00:00
|
|
|
while True:
|
2019-10-23 20:10:03 +00:00
|
|
|
|
|
|
|
event, values = window.read(timeout=0)
|
2020-05-07 10:22:59 +00:00
|
|
|
if event in ('Exit', sg.WIN_CLOSED):
|
2019-08-15 13:19:23 +00:00
|
|
|
break
|
2019-10-23 20:10:03 +00:00
|
|
|
# Read image from capture device (camera)
|
|
|
|
ret, frame = cap.read()
|
2019-08-15 13:19:23 +00:00
|
|
|
|
|
|
|
img = Image.fromarray(frame) # create PIL image from frame
|
2019-10-23 20:10:03 +00:00
|
|
|
GCF = float(values['-SPIN-GCF-'])
|
2022-06-22 19:45:52 +00:00
|
|
|
WCF = 1.75
|
2019-08-15 13:19:23 +00:00
|
|
|
# More magic that coverts the image to ascii
|
|
|
|
S = (round(img.size[0] * SC * WCF), round(img.size[1] * SC))
|
|
|
|
img = np.sum(np.asarray(img.resize(S)), axis=2)
|
|
|
|
img -= img.min()
|
|
|
|
img = (1.0 - img / img.max()) ** GCF * (chars.size - 1)
|
|
|
|
|
|
|
|
# "Draw" the image in the window, one line of text at a time!
|
2022-06-22 19:45:52 +00:00
|
|
|
font_size = int(values['-FONT SIZE-'])
|
2019-08-15 13:19:23 +00:00
|
|
|
for i, r in enumerate(chars[img.astype(int)]):
|
2022-06-22 19:45:52 +00:00
|
|
|
window[('-OUT-', i)].update("".join(r), font=('Courier', font_size))
|
2019-10-23 20:10:03 +00:00
|
|
|
|
|
|
|
window.close()
|