【问题标题】:Trying to plot Mandelbrot set - no matter what, always get plain black image试图绘制 Mandelbrot 集 - 无论如何,总是得到纯黑色图像
【发布时间】:2016-09-19 05:34:37
【问题描述】:

首先,这是我的代码:

from PIL import Image as im
import numpy as np 

def mandelbrot_iteration(c): 
    iters = 0
    while abs(c)<2 and iters<200:
        c=c**2+c
        iters+=1
    return iters

HEIGHT = 400
WIDTH = 500

diag = im.new('L',(WIDTH, HEIGHT))
pix = diag.load()

x_pts = np.arange(-2,2,4/WIDTH)  
y_pts = np.arange(-2,2,4/HEIGHT)

for x in x_pts:
    for y in y_pts:
        pix[x+2,y+2]=mandelbrot_iteration(complex(x,y))

diag.save("Fractal.png")

我认为这很简单。我看到复数网格上的每个点需要多少次交互才能超过绝对值。值 2 并将这些值绘制为每个点的颜色(假设序列不发散,截止值为 200)。在指定的范围内,肯定会发生一些不平凡的事情,但无论我尝试什么,制作的图像都是纯黑色的。

此外,这种生成图像的方法几乎为零文档。我已经搜索了很多,这是:

im.load()

为图像分配存储空间并从文件(或从 源,用于惰性操作)。在正常情况下,您不需要 调用这个方法,因为 Image 类会自动加载一个打开的 首次访问时的图像。

(1.1.6 中新增)在 1.1.6 及更高版本中,load 返回一个像素访问对象 可用于读取和修改像素。访问对象的行为 像一个二维数组,所以你可以这样做:

pix = im.load() print pix[x, y] pix[x, y] = value

通过这个对象访问比getpixel和putpixel快很多

是我能找到的关于它的所有(也没有例子),这非常令人沮丧。我想 pix[x+2,y+2] 线有问题。 '+2' 用于阻止“超出范围”错误,但是,在尝试了一些示例后,我不知道它对输入数字的作用是什么来生成颜色。我确实发现创建图像时的“L”应该制作灰度图像,但不知道 pix[x,y] 期望的范围或任何东西。一切都变黑了......

【问题讨论】:

  • @RadLexus 在某处我发现 im.new() 中的“L”应该是 8 位像素,介于黑白之间。所以灰度。我期待更快发散的像素的颜色更浅。我期待在会聚点出现黑色。
  • 啊,你是对的。文档对“L”说“8 位灰度。0 表示黑色,255 表示白色。” - 那么你的范围应该至少是 0..199。通过打印出mandelbrot 函数的返回值进行测试。如果全为零,则错误就在那里。否则,它在图像生成中。
  • mandelbrot 迭代应该是 z=0,而 abs(z)
  • 确实如此。我按照我建议的方式对其进行了测试,并且由于数字出现还可以,我进一步查看了:) 但是正如@hcs 指出的那样,您的例程中存在实现错误。幸运的是,修复很简单。
  • 这个问题实际上是其他问题的重复,例如stackoverflow.com/questions/26447915/…。有关有效的代码,请参阅我的答案,并附上关于居中的评论。只需使用pix[x,y] 而不是img.put(x,y)。您应该遍历精确的整数像素坐标以进行绘图并将它们转换为世界坐标以进行 mandelbrot 迭代。

标签: python python-imaging-library


【解决方案1】:

直接的问题是您的 scale 已关闭。

在这条pix[x+2,y+2]=... 行中,加上x 和y 的范围,正在绘制的唯一像素是0..4。由于最后绘制的几个像素是黑色的,所以整个左上角的 4x4 正方形都是黑色的(其余部分是 0 - 也是黑色 - 默认情况下,用于新图像)。

可以这样解决:

from PIL import Image as im
import numpy as np 

def mandelbrot_iteration(c): 
    iters = 0
    while abs(c)<2 and iters<200:
        c=c**2+c
        iters+=1
    return iters

HEIGHT = 400
WIDTH = 500

diag = im.new('L',(WIDTH, HEIGHT))
pix = diag.load()

x_pts = np.arange(-2,2,4.0/WIDTH)  
y_pts = np.arange(-2,2,4.0/HEIGHT)

for x in x_pts:
    for y in y_pts:
        pix[WIDTH*(x+2)/4.0,HEIGHT*(y+2)/4.0]=mandelbrot_iteration(complex(x,y))

diag.show()

虽然结果还不是很好的曼德布罗……

使用 hcs 的注释“mandelbrot 迭代应该是 z=0,而 abs(z)

from PIL import Image as im
import numpy as np 

def mandelbrot_iteration(c): 
    iters = 0
    z = 0
    while abs(z)<2 and iters<200:
        z=z**2+c
        iters+=1
    return iters

HEIGHT = 400
WIDTH = 500

diag = im.new('L',(WIDTH, HEIGHT))
pix = diag.load()

x_pts = np.arange(-2,2,4.0/WIDTH)  
y_pts = np.arange(-2,2,4.0/HEIGHT)

for x in x_pts:
    for y in y_pts:
        pix[WIDTH*(x+2)/4.0,HEIGHT*(y+2)/4.0]=mandelbrot_iteration(complex(x,y))

# diag.show()
diag.save("Fractal.png")

你瞧,一个真正的 Mandelbrot 出现了:

【讨论】:

  • 好吧,那就这样排序!非常感谢您(和@hcs)的帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-05
  • 1970-01-01
  • 1970-01-01
  • 2013-01-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多