merge gitignore
This commit is contained in:
commit
fccdf56188
@ -1,232 +1,220 @@
|
||||
# import scipy.ndimage as nd
|
||||
# import imageio.v3 as iio
|
||||
# import numpy as np
|
||||
import logging
|
||||
import math
|
||||
import os
|
||||
|
||||
from PIL import Image
|
||||
import pygame as pg
|
||||
|
||||
import filters
|
||||
|
||||
FORMAT = "%(levelname)s %(filename)s - %(message)s"
|
||||
logging.basicConfig(level=logging.DEBUG, format=FORMAT)
|
||||
|
||||
IMAGE_PATH = 'sample-images/engine.PNG'
|
||||
FONT_PATH = 'fonts/scientifica.ttf'
|
||||
|
||||
|
||||
WHITE = (255,255,255)
|
||||
|
||||
TEXT_WIDTH = 6 # on font size 12 monocraft medium
|
||||
TEXT_HEIGHT = 11
|
||||
|
||||
SCALE_FACTOR = 2
|
||||
RESIZE_FACTOR = 2
|
||||
|
||||
SCALED_WIDTH = TEXT_WIDTH // SCALE_FACTOR
|
||||
SCALED_HEIGHT = TEXT_HEIGHT // SCALE_FACTOR
|
||||
|
||||
DEBUG = True
|
||||
|
||||
if not os.path.exists('./debug/') and DEBUG:
|
||||
os.makedirs('./debug')
|
||||
|
||||
# '█@?OPoci. '
|
||||
CHARS = list(reversed([
|
||||
u'█',
|
||||
'@',
|
||||
'?',
|
||||
'O',
|
||||
'P',
|
||||
'o',
|
||||
'c',
|
||||
'i',
|
||||
'.',
|
||||
' '
|
||||
]))
|
||||
|
||||
def main():
|
||||
|
||||
image = Image.open(IMAGE_PATH)
|
||||
image = image.resize((image.width * RESIZE_FACTOR, image.height * RESIZE_FACTOR))
|
||||
logging.debug(f'Image Size: {image.size}')
|
||||
|
||||
L_image = image.convert('L')
|
||||
logging.debug(f'L_image Size: {L_image.size}')
|
||||
|
||||
dog = filters.difference_of_gaussians(image)
|
||||
logging.debug(f'Dog Size: {dog.size}')
|
||||
|
||||
dog.save('dog.png')
|
||||
|
||||
sb, gradient = filters.sobel(dog)
|
||||
|
||||
w, h = sb.size
|
||||
|
||||
sb.save('sobel.png')
|
||||
|
||||
text_grid_width = w / SCALED_WIDTH
|
||||
text_grind_height = h / SCALED_HEIGHT
|
||||
|
||||
pg.init()
|
||||
font = pg.font.Font(FONT_PATH, 12)
|
||||
window = pg.display.set_mode((text_grid_width * TEXT_WIDTH, text_grind_height * TEXT_HEIGHT))
|
||||
|
||||
y_offset = 0
|
||||
|
||||
for y in range(math.floor(h / SCALED_HEIGHT)):
|
||||
x_offset = 0
|
||||
|
||||
for x in range(math.floor(w / SCALED_WIDTH)):
|
||||
histogram = {}
|
||||
|
||||
# Collect the most common char for a group of pixels
|
||||
colors = []
|
||||
|
||||
for y2 in range(SCALED_HEIGHT):
|
||||
for x2 in range(SCALED_WIDTH):
|
||||
|
||||
real_x = x2 + x_offset
|
||||
real_y = y2 + y_offset
|
||||
|
||||
gradient_v = gradient[real_y * w + real_x]
|
||||
|
||||
char = ' '
|
||||
|
||||
if gradient_v:
|
||||
char = match_gradient(gradient_v)
|
||||
else:
|
||||
char = CHARS[round(L_image.getpixel((real_x, real_y))/(255/len(CHARS))) - 1]
|
||||
|
||||
if char in histogram:
|
||||
histogram[char] += 1
|
||||
else:
|
||||
histogram[char] = 1
|
||||
|
||||
colors.append(image.getpixel((real_x, real_y)))
|
||||
|
||||
color_avg = average_colors(colors)
|
||||
|
||||
# get most common
|
||||
most_common = None
|
||||
score = float('-inf')
|
||||
for char in histogram:
|
||||
if histogram[char] > score:
|
||||
score = histogram[char]
|
||||
most_common = char
|
||||
|
||||
rendered_char = font.render(str(most_common), True, color_avg)
|
||||
window.blit(rendered_char, (x * TEXT_WIDTH, y * TEXT_HEIGHT))
|
||||
|
||||
x_offset += SCALED_WIDTH
|
||||
|
||||
y_offset += SCALED_HEIGHT
|
||||
|
||||
pg.display.update()
|
||||
pg.image.save(window, "render.png")
|
||||
pg.quit()
|
||||
|
||||
if DEBUG:
|
||||
sb.save('debug/sobel-dog.png')
|
||||
dog.save('debug/dog.png')
|
||||
|
||||
# Draw only the ASCII edges
|
||||
pg.init()
|
||||
font = pg.font.Font(FONT_PATH, 12)
|
||||
window = pg.display.set_mode((text_grid_width * TEXT_WIDTH, text_grind_height * TEXT_HEIGHT))
|
||||
|
||||
y_offset = 0
|
||||
|
||||
for y in range(math.floor(h / SCALED_HEIGHT)):
|
||||
x_offset = 0
|
||||
|
||||
for x in range(math.floor(w / SCALED_WIDTH)):
|
||||
histogram = {}
|
||||
|
||||
# Collect the most common char for a group of pixels
|
||||
colors = []
|
||||
|
||||
for y2 in range(SCALED_HEIGHT):
|
||||
for x2 in range(SCALED_WIDTH):
|
||||
|
||||
real_x = x2 + x_offset
|
||||
real_y = y2 + y_offset
|
||||
|
||||
gradient_v = gradient[real_y * w + real_x]
|
||||
|
||||
char = ' '
|
||||
|
||||
if gradient_v:
|
||||
char = match_gradient(gradient_v)
|
||||
else:
|
||||
char = ' '
|
||||
|
||||
if char in histogram:
|
||||
histogram[char] += 1
|
||||
else:
|
||||
histogram[char] = 1
|
||||
|
||||
colors.append(image.getpixel((real_x, real_y)))
|
||||
|
||||
color_avg = average_colors(colors)
|
||||
|
||||
# get most common
|
||||
most_common = None
|
||||
score = float('-inf')
|
||||
for char in histogram:
|
||||
if histogram[char] > score:
|
||||
score = histogram[char]
|
||||
most_common = char
|
||||
|
||||
rendered_char = font.render(most_common, True, color_avg)
|
||||
window.blit(rendered_char, (x * TEXT_WIDTH, y * TEXT_HEIGHT))
|
||||
|
||||
x_offset += SCALED_WIDTH
|
||||
|
||||
y_offset += SCALED_HEIGHT
|
||||
|
||||
pg.display.update()
|
||||
pg.image.save(window, "debug/edges-render.png")
|
||||
pg.quit()
|
||||
|
||||
# TODO @0x01FE : refactor plz increment by 30 & 60
|
||||
def match_gradient(n: float) -> str:
|
||||
|
||||
n = abs(n)
|
||||
|
||||
if n < math.radians(30):
|
||||
return '|'
|
||||
elif n < math.radians(60):
|
||||
return '/'
|
||||
elif n < math.radians(120):
|
||||
return '-'
|
||||
elif n < math.radians(150):
|
||||
return '\\'
|
||||
elif n < math.radians(210):
|
||||
return '|'
|
||||
elif n < math.radians(240):
|
||||
return '/'
|
||||
elif n < math.radians(300):
|
||||
return '-'
|
||||
elif n < math.radians(330):
|
||||
return '\\'
|
||||
else:
|
||||
return '|'
|
||||
|
||||
def average_colors(colors: list):
|
||||
avg = [0 for x in range(len(colors[0]))]
|
||||
|
||||
for color in colors:
|
||||
for i, num in enumerate(color):
|
||||
avg[i] += num
|
||||
|
||||
for i, n in enumerate(avg):
|
||||
avg[i] /= len(colors)
|
||||
|
||||
return avg
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
import logging
|
||||
import math
|
||||
import os
|
||||
|
||||
from PIL import Image
|
||||
import pygame as pg
|
||||
|
||||
import filters
|
||||
|
||||
logging.getLogger(__name__)
|
||||
|
||||
FONT_PATH = 'fonts/scientifica.ttf'
|
||||
|
||||
TEXT_WIDTH = 6 # on font size 12 monocraft medium
|
||||
TEXT_HEIGHT = 11
|
||||
|
||||
SCALE_FACTOR = 2
|
||||
RESIZE_FACTOR = 2
|
||||
|
||||
SCALED_WIDTH = TEXT_WIDTH // SCALE_FACTOR
|
||||
SCALED_HEIGHT = TEXT_HEIGHT // SCALE_FACTOR
|
||||
|
||||
DEBUG = True
|
||||
|
||||
if not os.path.exists('./debug/') and DEBUG:
|
||||
os.makedirs('./debug')
|
||||
|
||||
# '█@?OPoci. '
|
||||
CHARS = list(reversed([
|
||||
u'█',
|
||||
'@',
|
||||
'?',
|
||||
'O',
|
||||
'P',
|
||||
'o',
|
||||
'c',
|
||||
'i',
|
||||
'.',
|
||||
' '
|
||||
]))
|
||||
|
||||
|
||||
def asciify(image: Image.Image) -> str:
|
||||
|
||||
image = image.resize((image.width * RESIZE_FACTOR, image.height * RESIZE_FACTOR))
|
||||
logging.debug(f'Image Size: {image.size}')
|
||||
|
||||
L_image = image.convert('L')
|
||||
logging.debug(f'L_image Size: {L_image.size}')
|
||||
|
||||
dog = filters.difference_of_gaussians(image)
|
||||
logging.debug(f'Dog Size: {dog.size}')
|
||||
|
||||
dog.save('dog.png')
|
||||
|
||||
sb, gradient = filters.sobel(dog)
|
||||
|
||||
w, h = sb.size
|
||||
|
||||
sb.save('sobel.png')
|
||||
|
||||
text_grid_width = w / SCALED_WIDTH
|
||||
text_grind_height = h / SCALED_HEIGHT
|
||||
|
||||
pg.init()
|
||||
font = pg.font.Font(FONT_PATH, 12)
|
||||
window = pg.display.set_mode((text_grid_width * TEXT_WIDTH, text_grind_height * TEXT_HEIGHT))
|
||||
|
||||
y_offset = 0
|
||||
|
||||
for y in range(math.floor(h / SCALED_HEIGHT)):
|
||||
x_offset = 0
|
||||
|
||||
for x in range(math.floor(w / SCALED_WIDTH)):
|
||||
histogram = {}
|
||||
|
||||
# Collect the most common char for a group of pixels
|
||||
colors = []
|
||||
|
||||
for y2 in range(SCALED_HEIGHT):
|
||||
for x2 in range(SCALED_WIDTH):
|
||||
|
||||
real_x = x2 + x_offset
|
||||
real_y = y2 + y_offset
|
||||
|
||||
gradient_v = gradient[real_y * w + real_x]
|
||||
|
||||
char = ' '
|
||||
|
||||
if gradient_v:
|
||||
char = match_gradient(gradient_v)
|
||||
else:
|
||||
char = CHARS[round(L_image.getpixel((real_x, real_y))/(255/len(CHARS))) - 1]
|
||||
|
||||
if char in histogram:
|
||||
histogram[char] += 1
|
||||
else:
|
||||
histogram[char] = 1
|
||||
|
||||
colors.append(image.getpixel((real_x, real_y)))
|
||||
|
||||
color_avg = average_colors(colors)
|
||||
|
||||
# get most common
|
||||
most_common = None
|
||||
score = float('-inf')
|
||||
for char in histogram:
|
||||
if histogram[char] > score:
|
||||
score = histogram[char]
|
||||
most_common = char
|
||||
|
||||
rendered_char = font.render(str(most_common), True, color_avg)
|
||||
window.blit(rendered_char, (x * TEXT_WIDTH, y * TEXT_HEIGHT))
|
||||
|
||||
x_offset += SCALED_WIDTH
|
||||
|
||||
y_offset += SCALED_HEIGHT
|
||||
|
||||
pg.display.update()
|
||||
pg.image.save(window, "render.png")
|
||||
pg.quit()
|
||||
|
||||
if DEBUG:
|
||||
sb.save('debug/sobel-dog.png')
|
||||
dog.save('debug/dog.png')
|
||||
|
||||
# Draw only the ASCII edges
|
||||
pg.init()
|
||||
font = pg.font.Font(FONT_PATH, 12)
|
||||
window = pg.display.set_mode((text_grid_width * TEXT_WIDTH, text_grind_height * TEXT_HEIGHT))
|
||||
|
||||
y_offset = 0
|
||||
|
||||
for y in range(math.floor(h / SCALED_HEIGHT)):
|
||||
x_offset = 0
|
||||
|
||||
for x in range(math.floor(w / SCALED_WIDTH)):
|
||||
histogram = {}
|
||||
|
||||
# Collect the most common char for a group of pixels
|
||||
colors = []
|
||||
|
||||
for y2 in range(SCALED_HEIGHT):
|
||||
for x2 in range(SCALED_WIDTH):
|
||||
|
||||
real_x = x2 + x_offset
|
||||
real_y = y2 + y_offset
|
||||
|
||||
gradient_v = gradient[real_y * w + real_x]
|
||||
|
||||
char = ' '
|
||||
|
||||
if gradient_v:
|
||||
char = match_gradient(gradient_v)
|
||||
else:
|
||||
char = ' '
|
||||
|
||||
if char in histogram:
|
||||
histogram[char] += 1
|
||||
else:
|
||||
histogram[char] = 1
|
||||
|
||||
colors.append(image.getpixel((real_x, real_y)))
|
||||
|
||||
color_avg = average_colors(colors)
|
||||
|
||||
# get most common
|
||||
most_common = None
|
||||
score = float('-inf')
|
||||
for char in histogram:
|
||||
if histogram[char] > score:
|
||||
score = histogram[char]
|
||||
most_common = char
|
||||
|
||||
rendered_char = font.render(most_common, True, color_avg)
|
||||
window.blit(rendered_char, (x * TEXT_WIDTH, y * TEXT_HEIGHT))
|
||||
|
||||
x_offset += SCALED_WIDTH
|
||||
|
||||
y_offset += SCALED_HEIGHT
|
||||
|
||||
pg.display.update()
|
||||
pg.image.save(window, "debug/edges-render.png")
|
||||
pg.quit()
|
||||
|
||||
# TODO @0x01FE : refactor plz increment by 30 & 60
|
||||
def match_gradient(n: float) -> str:
|
||||
|
||||
n = abs(n)
|
||||
|
||||
if n < math.radians(30):
|
||||
return '|'
|
||||
elif n < math.radians(60):
|
||||
return '/'
|
||||
elif n < math.radians(120):
|
||||
return '-'
|
||||
elif n < math.radians(150):
|
||||
return '\\'
|
||||
elif n < math.radians(210):
|
||||
return '|'
|
||||
elif n < math.radians(240):
|
||||
return '/'
|
||||
elif n < math.radians(300):
|
||||
return '-'
|
||||
elif n < math.radians(330):
|
||||
return '\\'
|
||||
else:
|
||||
return '|'
|
||||
|
||||
def average_colors(colors: list):
|
||||
avg = [0 for x in range(len(colors[0]))]
|
||||
|
||||
for color in colors:
|
||||
for i, num in enumerate(color):
|
||||
avg[i] += num
|
||||
|
||||
for i, n in enumerate(avg):
|
||||
avg[i] /= len(colors)
|
||||
|
||||
return avg
|
||||
165
ctif.py
Normal file
165
ctif.py
Normal file
@ -0,0 +1,165 @@
|
||||
import logging
|
||||
import math
|
||||
import os
|
||||
|
||||
from PIL import Image
|
||||
import pygame as pg
|
||||
|
||||
import filters
|
||||
|
||||
logging.getLogger(__name__)
|
||||
|
||||
FONT_PATH = 'fonts/scientifica.ttf'
|
||||
|
||||
TEXT_WIDTH = 6 # on font size 12 monocraft medium
|
||||
TEXT_HEIGHT = 11
|
||||
|
||||
SCALE_FACTOR = 2
|
||||
RESIZE_FACTOR = 2
|
||||
|
||||
SCALED_WIDTH = TEXT_WIDTH // SCALE_FACTOR
|
||||
SCALED_HEIGHT = TEXT_HEIGHT // SCALE_FACTOR
|
||||
|
||||
DEBUG = True
|
||||
|
||||
if not os.path.exists('./debug/') and DEBUG:
|
||||
os.makedirs('./debug')
|
||||
|
||||
# '█@?OPoci. '
|
||||
CHARS = list(reversed([
|
||||
u'█',
|
||||
'@',
|
||||
'?',
|
||||
'O',
|
||||
'P',
|
||||
'o',
|
||||
'c',
|
||||
'i',
|
||||
'.',
|
||||
' '
|
||||
]))
|
||||
|
||||
# Character Text Image Format
|
||||
class CTIF:
|
||||
data: list
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def convert(self, image: Image.Image) -> None:
|
||||
|
||||
image = image.resize((image.width * RESIZE_FACTOR, image.height * RESIZE_FACTOR))
|
||||
logging.debug(f'Image Size: {image.size}')
|
||||
|
||||
L_image = image.convert('L')
|
||||
logging.debug(f'L_image Size: {L_image.size}')
|
||||
|
||||
dog = filters.difference_of_gaussians(image)
|
||||
logging.debug(f'Dog Size: {dog.size}')
|
||||
|
||||
dog.save('debug/dog.png')
|
||||
|
||||
sb, gradient = filters.sobel(dog)
|
||||
|
||||
w, h = sb.size
|
||||
|
||||
sb.save('debug/sobel.png')
|
||||
|
||||
text_grid_width = w / SCALED_WIDTH
|
||||
text_grind_height = h / SCALED_HEIGHT
|
||||
|
||||
pg.init()
|
||||
font = pg.font.Font(FONT_PATH, 12)
|
||||
window = pg.display.set_mode((text_grid_width * TEXT_WIDTH, text_grind_height * TEXT_HEIGHT))
|
||||
|
||||
y_offset = 0
|
||||
|
||||
for y in range(math.floor(h / SCALED_HEIGHT)):
|
||||
x_offset = 0
|
||||
|
||||
for x in range(math.floor(w / SCALED_WIDTH)):
|
||||
histogram = {}
|
||||
|
||||
# Collect the most common char for a group of pixels
|
||||
colors = []
|
||||
|
||||
for y2 in range(SCALED_HEIGHT):
|
||||
for x2 in range(SCALED_WIDTH):
|
||||
|
||||
real_x = x2 + x_offset
|
||||
real_y = y2 + y_offset
|
||||
|
||||
gradient_v = gradient[real_y * w + real_x]
|
||||
|
||||
char = ' '
|
||||
|
||||
if gradient_v:
|
||||
char = self._match_gradient(gradient_v)
|
||||
else:
|
||||
char = CHARS[round(L_image.getpixel((real_x, real_y))/(255/len(CHARS))) - 1]
|
||||
|
||||
if char in histogram:
|
||||
histogram[char] += 1
|
||||
else:
|
||||
histogram[char] = 1
|
||||
|
||||
colors.append(image.getpixel((real_x, real_y)))
|
||||
|
||||
color_avg = self._average_colors(colors)
|
||||
|
||||
# get most common
|
||||
most_common = None
|
||||
score = float('-inf')
|
||||
for char in histogram:
|
||||
if histogram[char] > score:
|
||||
score = histogram[char]
|
||||
most_common = char
|
||||
|
||||
rendered_char = font.render(str(most_common), True, color_avg)
|
||||
window.blit(rendered_char, (x * TEXT_WIDTH, y * TEXT_HEIGHT))
|
||||
|
||||
x_offset += SCALED_WIDTH
|
||||
|
||||
y_offset += SCALED_HEIGHT
|
||||
|
||||
pg.display.update()
|
||||
pg.image.save(window, "render.png")
|
||||
pg.quit()
|
||||
|
||||
|
||||
# TODO @0x01FE : refactor plz increment by 30 & 60
|
||||
def _match_gradient(self, n: float) -> str:
|
||||
|
||||
n = abs(n)
|
||||
|
||||
if n < math.radians(30):
|
||||
return '|'
|
||||
elif n < math.radians(60):
|
||||
return '/'
|
||||
elif n < math.radians(120):
|
||||
return '-'
|
||||
elif n < math.radians(150):
|
||||
return '\\'
|
||||
elif n < math.radians(210):
|
||||
return '|'
|
||||
elif n < math.radians(240):
|
||||
return '/'
|
||||
elif n < math.radians(300):
|
||||
return '-'
|
||||
elif n < math.radians(330):
|
||||
return '\\'
|
||||
else:
|
||||
return '|'
|
||||
|
||||
def _average_colors(self, colors: list):
|
||||
avg = [0 for x in range(len(colors[0]))]
|
||||
|
||||
for color in colors:
|
||||
for i, num in enumerate(color):
|
||||
avg[i] += num
|
||||
|
||||
for i, n in enumerate(avg):
|
||||
avg[i] /= len(colors)
|
||||
|
||||
return avg
|
||||
|
||||
18
main.py
Normal file
18
main.py
Normal file
@ -0,0 +1,18 @@
|
||||
import logging
|
||||
|
||||
from PIL import Image
|
||||
import asciify
|
||||
|
||||
FORMAT = "%(levelname)s %(filename)s - %(message)s"
|
||||
logging.basicConfig(level=logging.DEBUG, format=FORMAT)
|
||||
|
||||
IMAGE_PATH = 'sample-images/engine.PNG'
|
||||
|
||||
def main():
|
||||
|
||||
image = Image.open(IMAGE_PATH)
|
||||
asciify.asciify(image)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user