Pythonでいろいろやってみる

Pythonを使った画像処理や機械学習などの簡単なプログラムを載せています。

充填ジュリア集合を描画する

充填ジュリア集合は漸化式
f:id:T_A_T:20201226205341p:plain
で定義される複素数列で、n→∞の極限において無限大に発散しないという条件を満たす複素数z0の集合を指します。

フリー百科事典『ウィキペディア(Wikipedia)』>>充填ジュリア集合

マンデルブロ集合と同じ漸化式による定義ですが、マンデルブロ集合がz0を固定しcを複素平面上で変えた場合の集合なのに対して、ジュリア集合はcを固定しz0を複素平面上で変えた場合の集合となります。cを適切な値に設定することで美しい図形を描画できます。
充填ジュリア集合を求めるプログラムは複素平面において、各点cに対する漸化式を計算し発散するか収束するかで判定します。あらかじめ設定した回数まで漸化式を計算しznがある閾値を越える場合には発散と判定、閾値を越えない場合には収束(充填ジュリア集合)と判定します。

関連記事

マンデルブロ集合を描画する

環境
  • windows10 home
  • Anaconda 3/ jupyter notebook 5.6.0
  • Python 3.7.0
  • OpenCV 4.0.0
コード

画像サイズを800x600とし、幅x・高さyの二重ループ内で対応する複素数が収束するか発散するかを調べています。
このように画像の各画素に複素平面上の複素数z0を対応させ、それぞれのz0が発散するか収束するかを判定します。
whileループで漸化式をn30まで計算し、計算が完了されれば(ループ終了後のnが30となれば)収束、znが100000000000000以上となりn=30となる前にwhileループを抜けた場合は発散と判定します。
収束部の輝度を0、発散部の赤の輝度を165+n*3として充填ジュリア集合を図にします。

import numpy as np
import cv2

height, width = 600, 800
# ジュリア集合描画用ndarray
julia = np.zeros((height, width, 3), np.uint8)  
div = 200

for y in range(height):
    for x in range(width):
        z0 = complex((x-0.5*width)/div, (y-0.5*height)/div)          
        c = complex(-0.8, 0.156)  

        # z0の絶対値が100000000000000を超えるかループが30回になったらwhileループを抜ける
        n = 0
        while abs(z0) < 100000000000000 and n < 30:  
            z0 = z0**2 + c  # 漸化式
            n += 1  # ループ回数+1
        if n == 30:  # 漸化式が収束した場合
            julia[y, x, :] = 0
        else:  # 漸化式が発散した場合
            julia[y, x, 2] = 165+n*3 
# ジュリア集合画像の保存    
cv2.imwrite('julia.jpg', julia)
実行結果

充填ジュリア集合(収束部)が黒、それ以外が赤で描画された図形が保存されます。
f:id:T_A_T:20210102094934j:plain


z0の範囲を変えます。
divの値を200→300に変え、描画位置をずらし、充填ジュリア集合を部分的に拡大します。

コード
#拡大
import numpy as np
import cv2

height, width = 600, 600
# ジュリア集合描画用ndarray
julia = np.zeros((height, width, 3), np.uint8)  
div = 300

for y in range(height):
    for x in range(width):
        z0 = complex((x-0.2*width)/div, (y-0.5*height)/div)          
        c = complex(-0.8, 0.156) 

        # z0の絶対値が100000000000000を超えるかループが30回になったらwhileループを抜ける
        n = 0
        while abs(z0) < 100000000000000 and n < 30:  
            z0 = z0**2 + c  # 漸化式
            n += 1  # ループ回数+1
        if n == 30:  # 漸化式が収束した場合
            julia[y, x, :] = 0
        else:  # 漸化式が発散した場合
            julia[y, x, 2] = 165+n*3
            
# ジュリア集合画像の保存    
cv2.imwrite('julia.jpg', julia)
実行結果

f:id:T_A_T:20210102095301j:plain

ブログランキングに参加しています

にほんブログ村 IT技術ブログへ
にほんブログ村