Здравствуйте уважаемые читатели, в этой статье я расскажу Вам как делать ASCII-арты при помощи языка python.
Примерно такие картинки мы научимся делать, когда дочитаем статью
Для начала необходимо установить библиотеку компьютерного зрения OpenCV, для этого в консоль прописываем данную строчку (заранее убедившись, что в системе уже есть pip, иначе устанавливаем его):
pip install opencv-python
После установки библиотеки можно приступить к написанию кода! Я не буду разбивать код на строчки и попутно объяснять их, а сначала расскажу о том, как работает весь алгоритм и только после этого приложу код.
И так, сначала разберемся с тем, как нам надо обрабатывать картинку и преобразовывать ее в символы ASCII. Логичнее всего делать это по яркости, но как нам определить яркость пикселя, если у нас картинка в формате RGB? Эту проблему я решил очень простым способом: я преобразовал из формата BGR (да-да именно BGR, потому что в библиотеке OpenCV цвета идут наоборот) в серую палитру, ну и тут уже понятно, обращаемся к пикселю как к элементу массива, указывая его координаты через запятую. И теперь, когда у нас уже есть картинка, в которой каждый ее элемент имеет определенную яркость от 0 до 255, то уже становится понятно, как именно сделать пиксель символом ASCII:
Нам нужен отфильтрованный по яркости элементов список символов ASCII (его можно либо составить на глаз, либо взять из интернета, благо люди уже давно придумали ASCII-арты и составили программы, которые выставили все символы по возрастающей)
Нам нужно создать особый коэффициент, на который мы будем делить яркость пикселя картинки и определять индекс строки ASCII символов
Чтобы сделать перевод можно использовать 2 цикла (способ идентичный перебору двумерного массива), перевести каждый пиксель в ASCII символ и вывести все элементы, но не все так просто, чтобы Вы поняли проблему я приложу картинку:
По символу видно, что его ширина не равна высоте и картинка будет становиться растянутой, чтобы это пофиксить можно либо сжать картинку функцией из библиотеки OpenCV, либо пропускать одну строчку, когда мы переводим серую картинку в символы, что будет смотреться органичнее всего. Второй способ не особо портит качество получаемого изображения, да и даже приближает его к искусству ASCII-артов, при которых должны четко различаться аски символы, именно по этому я в своем коде пропускаю еще и символы в столбцах, используя отношение 8 к 4.
Когда картинка обработана и готова к выводу, можно задуматься о том, как это сделать, потому что просто принтить каждую строчку в консоль - это плохая идея, потому что в том же пайчарме она не позволяет масштабировать себя удерживая ctrl и вращая колесиком мыши, что в свою очередь может делать блокнот, значит с ним и надо работать.
Еще я столкнулся с проблемой ошибок, которые вылетали во время обработки разных картинок, ее я решил использованием конструкции try-except.
И теперь, когда Вы все уже прочитали алгоритм моего кода, я готов показать его:
import cv2
string = " `.,-':<>;+!*/?%&98#"
coef = 255 / (len(string) - 1)
image = cv2.imread('img/img_18.png')
height, width, channels = image.shape
gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# gray_image = cv2.resize(gray_image, (30, 12))
with open("output\ASCII_Art.txt", "w") as file:
for x in range(0, width - 1, 8):
s = ""
for y in range(0, height - 1, 4):
try:
s += string[len(string) - int(gray_image[x, y] / coef) - 1]
continue
except IndexError:
pass
if len(s) != 0:
file.write(s + "\n")
Ну вот и все, теперь можно обрабатывать картинки и получать подобные результаты:
Большое спасибо, что прочитали мою статью, буду рад любым комментариям)
(Еще я хочу написать статью о том, как я повторил легендарный клип Bad apple используя ASCII-арты, если будет интересно, то ставьте лайки)