PythonのPillowのImage.effect_mandelbrotの使い方: マンデルブロ集合を描く
- 作成日: 2020-09-30
- 更新日: 2023-12-24
- カテゴリ: Python
Image.effect_mandelbrotの使い方
Pythonの画像処理ライブラリであるPillow
には画像を処理するImage
モジュールがあります。
Image
モジュールはマンデルブロ集合の画像を生成する関数effect_mandelbrot()
を持っています。
この関数を使うと簡単にマンデルブロ集合を描くことが出来ます。
マンデルブロ集合とは?
数学(特に複素力学系)で提唱された集合のことです。
数学者ブノワ・マンデルブロにちなんでこの名が付けられました。
高解像度のマンデルブロ集合の描写は、マシンパワーを必要とすることから、パソコンのベンチマークでも使われることがあるそうです。
Image.effect_mandelbrotの構造
Image.effect_mandelbrot()
は↓のような構造を持っています。
PIL.Image.effect_mandelbrot(size, extent, quality)
size
第1引数のsize
は生成する画像のサイズのタプルです。
タプルの第1要素は横幅、第2要素は高さを指定します。
たとえば(width, height)
のようにです。
extent
マンデルブロ集合を生成する範囲をタプルで指定します。
言い換えるとマンデルブロ集合のキャンバス上の大きさです。
タプルは第1要素が第1のx
座標、第2要素が第1のy
座標、第3要素が第2のx
座標、第4要素が第2のy
座標になります。
これは(x0, y0, x1, y1)
と表すことが出来ます。
ここに指定する値はいわゆるピクセルではありません。ですので、size
と似たような値を指定してもうまく画像が生成されないので注意が必要です。
quality
生成するマンデルブロ集合のクオリティです。
2
~100
の範囲で指定します。
値が低いほど抽象的なマンデルブロ集合が生成されます。
値が100
に近ければいわゆるネット上でよく見る高解像度なマンデルブロ集合が生成されます。
戻り値
戻り値はImage
オブジェクトです。
高クオリティなマンデルブロ集合を描く
クオリティ100
のマンデルブロ集合を描いてみます。
画像のサイズは横幅512px
, 高さ512px
です。
from PIL import Image
# マンデルブロ集合のパラメーター
size = (512, 512) # (width, height)
extent = (-3, -2, 2, 2) # (x1, y1, x2, y2)
quality = 100 # 2 ~ 100
# マンデルブロ集合を生成
im = Image.effect_mandelbrot(size, extent, quality)
# 画像を保存
im.save('dst/out0.png')
出力結果。
いわゆるよく見かけるマンデルブロ集合が生成されました。
🦝 < 簡単だな~
高クオリティなマンデルブロ集合を拡大する
extent
の値を工夫するとマンデルブロ集合を拡大することができます。
↓のようにextent
に(-1, -1, 0.0001, 0.0001)
を指定します。
その他の値は変わりません。
from PIL import Image
# マンデルブロ集合のパラメーター
size = (512, 512) # (width, height)
extent = (-1, -1, 0.0001, 0.0001) # (x1, y1, x2, y2)
quality = 100 # 2 ~ 100
# マンデルブロ集合を生成
im = Image.effect_mandelbrot(size, extent, quality)
# 画像を保存
im.save('dst/out1.png')
出力結果。
低クオリティなマンデルブロ集合を描く
quality
の値を低くすると、描かれるマンデルブロ集合が抽象的になっていきます。
たとえばquality
を20
にすると、↓のような出力になります。
quality
を8
まで下げるともはや原型をとどめません。
イラストとマンデルブロ集合を合成する
このイラストとマンデルブロ集合を合成してみたいと思います。
from PIL import Image
# イラストを読み込む
illust = Image.open('img/a.png').convert('RGB')
ir, ig, ib = illust.split() # バンドを抽出
# マンデルブロ集合のパラメーター
size = (500, 500) # (width, height)
extent = (-1, -1, 0.0001, 0.0001) # (x1, y1, x2, y2)
quality = 20 # 2 ~ 100
# マンデルブロ集合を生成
mandebrot = Image.effect_mandelbrot(size, extent, quality)
mandebrot = mandebrot.convert('RGB')
mr, mg, mb = mandebrot.split() # バンドを抽出
# イラストとマンデルブロ集合のバンドを合成する
im = Image.merge('RGB', (ir, mg, mb))
# 画像を保存
im.save('dst/out4.png')
出力結果。
マンデルブロ集合の規則的な描写は人工物よりは自然物の方が合成したときに合うかもしれないですね。
🦝 < まぁ好みによる
ソースコードの分析
Pillowのマンデルブロ集合を描く関数は最終的にC言語で描かれたモジュールに辿り着きます。
速度を確保するためにPythonのモジュールをCで書くというのはよくあることです。
関数を見てみると非常にシンプルなものだというのがわかります。
自力でマンデルブロ集合を描いてみたい方は参考にされてみてはどうでしょうか。
問題
Q1: マンデルブロ集合は何の分野の集合か答えよ
Q1: 哲学
Q2: 数学
Q3: 物理学
Q2: Image.effect_mandelbrot()
の第1引数の説明として適当なものを答えよ
Q1: 画像のモード
Q2: 画像のサイズ
Q3: マンデルブロ集合のサイズ
Q3: Image.effect_mandelbrot()
の戻り値として適当なものを答えよ
Q1: Image
Q2: int
Q3: dict
正解はこちら↓
Q1: 2
Q2: 2
Q3: 1