本章中,我们将把著名的曼德勃罗分形图(Mandelbrot fractal)和图像Lena进行合并。此类分形可以被定义为一个迭代公式,当前的复数值的平方,加上一个常数,就得到下一个复数值。
准备工作
如有必要,请先安装SciPy。
具体步骤
我们将首先初始化数组,接着生成和绘制分形图,最后把分形图并入图像Lena。
- 初始化数组。
用meshgrid
、zeros
和linspace
函数,把图像上各个像素对应的x
、y
和z
数组进行初始化。
x, y = numpy.meshgrid(numpy.linspace
(x_min, x_max, SIZE),
numpy.linspace(y_min, y_max, SIZE))
c = x + 1j * y
z = c.copy()
fractal = numpy.zeros
(z.shape, dtype=numpy.uint8) +
MAX_COLOR
- 生成分形图。
如果z是一个复数,则曼德勃罗分形的迭代公式是:
上式中c是复常数。可以用图形化的方式在复平面中表示曼德勃罗分形,实轴对应z的实部,虚轴对应z的虚部。我们将使用逃逸时间算法绘制分形图。
首先选定一个到原点的距离不超过指定值(2左右)的小区域,该算法将扫描这个区域内的各个点。这个区域中的每个点都被用作一个c值,每个点的颜色由该点逃离这个区域所需要的迭代次数决定。如果这个迭代次数超出某个预先设定的值,则该点的颜色就设定为默认的背景色。更多相关的信息请浏览前面提到的维基百科页面。
for n in range(ITERATIONS):
print n
mask = numpy.abs(z) <= 4
z[mask] = z[mask] ** 2 + c[mask]
fractal[(fractal == MAX_COLOR) &
(-mask)] = (MAX_COLOR - 1) *
n / ITERATIONS
- 绘制分形图。
用Matplotlib绘制分形图。
matplotlib.pyplot.subplot(211)
matplotlib.pyplot.imshow(fractal)
matplotlib.pyplot.title('Mandelbrot')
matplotlib.pyplot.axis('off')
- 把分形图和图像Lena合并。
使用choose
函数,从分形图或图像Lena中选择各点的取值。
matplotlib.pyplot.subplot(212)
matplotlib.pyplot.imshow(numpy.choose
(fractal < lena, [fractal, lena]))
matplotlib.pyplot.axis('off')
matplotlib.pyplot.title
('Mandelbrot + Lena')
最终生成如下的图形。
本攻略的完整代码如下。
import numpy
import matplotlib.pyplot
import sys
import scipy
if(len(sys.argv) != 2):
print "Please input the number of iterations for the fractal"
sys.exit()
ITERATIONS = int(sys.argv[1])
lena = scipy.misc.lena()
SIZE = lena.shape[0]
MAX_COLOR = 255.
x_min, x_max = -2.5, 1
y_min, y_max = -1, 1
# 初始化数组
x, y = numpy.meshgrid(numpy.linspace(x_min, x_max, SIZE),
numpy.linspace(y_min, y_max, SIZE))
c = x + 1j * y
z = c.copy()
fractal = numpy.zeros(z.shape, dtype=numpy.uint8) + MAX_COLOR
# 生成分形图
for n in range(ITERATIONS):
print n
mask = numpy.abs(z) <= 4
z[mask] = z[mask] ** 2 + c[mask]
fractal[(fractal == MAX_COLOR) & (-mask)] = (MAX_COLOR - 1) * n / ITERATIONS
# 显示分形图
matplotlib.pyplot.subplot(211)
matplotlib.pyplot.imshow(fractal)
matplotlib.pyplot.title('Mandelbrot')
matplotlib.pyplot.axis('off')
# 与图像Lena合并
matplotlib.pyplot.subplot(212)
matplotlib.pyplot.imshow(numpy.choose(fractal < lena, [fractal, lena]))
matplotlib.pyplot.axis('off')
matplotlib.pyplot.title('Mandelbrot + Lena')
matplotlib.pyplot.show()
小结
在本攻略中,我们用到了下列函数。
函数 | 功能描述 |
---|---|
linspace |
返回某个范围内的指定间距的数列 |
choose |
根据给定条件从数组中选择数值并创建一个新的数组 |
meshgrid |
输入一个x坐标数组和一个y坐标数组,返回二维坐标数组 |