23
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

PythonとOpenCVで画像をアスキーアート化するプログラムを作った

Last updated at Posted at 2020-06-07

はじめに

先日、ASCII Cameraという面白いサイトを見つけました。
picture_pc_3c309a4cbd82ecc52c545a04da630a0b.png
こんな風に、ブラウザからカメラ映像を取得してASCII文字列に変換してくれます。

このぐらいだったらもしかして自分で作れるんじゃないかと思ったので、画像をアスキーアートに変換するプログラムを作ってみることにしました。

仕組み

仕組みとしては、以下のようになります。

  1. 画像をグレースケールに変換する
  2. 各ピクセルの色の濃さを取得し、それに応じて文字を決定する
  3. 列ごとに改行する

PythonとOpenCVを使えばこれらの処理をかなり簡単に行えます。

グレースケールに変換

読み込む画像のパスはinputで取得するようにします。
これでグレースケールに変換され、grayには各ピクセルの濃度(0~255)が格納されます。

import cv2

imgpath = input("Path: ")
img = cv2.imread(imgpath)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

ASCII文字を決定する

各ピクセルの濃度(0~255)ごとにASCII文字を決定する必要がありますが、実際に使えるASCII文字は256個もありません。
仕方がないので、使う文字を64個に厳選し、濃度を4ごとに区切って文字を選ぶことにしました。
例えば濃度が0~3なら「M」、252~255なら「 (空白)」、といった具合です。

以下が「濃度が高い」順番に並べた64個の文字です。

MWN$@%#&B89EGA6mK5HRkbYT43V0JL7gpaseyxznocv?jIftr1li*=-~^`':;,. 

この順番を決めるのがけっこう大変でした。
順番は見た目で決めただけなので、超適当です。

変換処理はこんな感じになりました。


colorset = "MWN$@%#&B89EGA6mK5HRkbYT43V0JL7gpaseyxznocv?jIftr1li*=-~^`':;,. "

for gray2 in gray:
    output += "\n"
    for dark in gray2:
        output += colorset[dark // 4] * 2

濃度を4で割って切り捨てることで、ちょうどよくcolorsetのインデックスを取得できます。
ASCII文字の縦横比は2:1なので、書き込む文字を2倍にしています。

完成

完成したプログラムはこんな感じです。
結果はファイルに出力する形式にしました。

import cv2

colorset = "MWN$@%#&B89EGA6mK5HRkbYT43V0JL7gpaseyxznocv?jIftr1li*=-~^`':;,. "

imgpath = input("Path:")
img = cv2.imread(imgpath)

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
output = ""

for gray2 in gray:
    output += "\n"
    for dark in gray2:
        output += colorset[dark // 4] * 2

with open("output.txt", mode="w") as f:
    f.write(output)

試しに私のアイコン(これ↓)を変換してみます。
nico.png
結果は...

スクリーンショット (148).png

こんな感じ。
意外とちゃんと変換できていてびっくりしました。

次に、ぱくたそ様から頂いたイギリス北部の自然風景のフリー画像を、300×200pxに変換したもので試してみます。
elly20160701265118_TP_V.jpg
結果は...

スクリーンショット (146).png
うん...まあいい線いってるんじゃないですかね。

最後に、This person does not existという、AIが顔写真を自動生成してくれるサイトで入手した、
image.jpg
この画像を250×250pxに変換して実行してみます。

結果は...

スクリーンショット (147).png
かなりいい感じですね!
これは良い...頑張った甲斐があった...

おわりに

という訳で、たった12行のコードで実現できてしまいました。
今回初めてOpenCVに触れたのですが、こんなに便利だとは思いませんでした。
これと同じことを256文字のUnicodeでやってみるのも面白いかもしれません。

参考文献

23
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
23
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?