分形(Fractal)
分形是指在不同尺度上都具有自相似特性的几何结构,通常由简单的递归规则生成。数学上,分形的一个重要特征是非整数维数,这与传统欧几里得几何(点是 0 维,线是 1 维,面是 2 维,体是 3 维)不同。
分形的关键特性:自相似性、非整数维数、递归、无穷细节
分形维数
相似维数(适用于严格自相似的分形)
其中,N 是将图形缩小 r 倍后所需的子结构数量。
一些举例分形和分形维数的举例:
- 科赫雪花(Koch Snowflake)
该曲线具有无穷长的边界但有限的面积。
- 谢尔宾斯基三角形(Sierpiński Triangle)
曼德勃罗集(Mandelbrot Set):由复数迭代方程
生成。
迭代函数系统(IFS)
1988年,Barnsley首次提出迭代函数系统(Iterated Function System, IFS)的概念,并认识到IFS可以很好地应用于图像压缩领域。他的学生Jacquin在随后的工作中进一步完善了基于IFS的图像压缩思想。
对图像压缩而言,分形主要是利用自相似的特点,通过迭代函数系统IFS来实现压缩。所谓自相似性就是指无论几何尺寸如何变化,物体的任何一小部分的形状都与较大部分的形状极其相似。与DCT编码不同,分形编码利用自相似性,不是临近样本的相关性,而是大范围的相似性,即图像块的相似性。
分形压缩理论基础是迭代函数系统定理和拼贴(Collage)定理。IFS是由一完备空间和一组有限的压缩变换
(
)组成,并记作
。每个迭代函数系统都有一个吸引子,该吸引子可表示成一幅图像。
拼贴定理指出:设$(X, d)$是完备度量空间,,数
,如能选到一个IFS
的压缩率为
,且满足
- 则
式中,A为该IFS的吸引子;h为Hausdorff度量;H(X)为完备度量空间(X, d)的一个子集。
一般分形图像压缩过程如下:
- 将整个图像分割成n个互不搭接的排列块和m个可搭接块
- 从Domain块中,对每个Range块寻找适当的Domain块,使得Domain块通过某种收缩变换W后近似于Range块,即W(D) = R。
- 确定每个Range块的最佳匹配Domain块,记录Domain块和Range块的位置,依次完成整个图像的编码。
- 从一幅图像开始进行解码,对选定的每个Domain块都用相应的W进行一次变换,称为一次迭代。趋于迭代函数系统的吸引子时,即得到解码图像。
基本分形压缩算法主要是对图像分割后Range块和Domain块进行搜索匹配的过程。这种算法的特点是压缩率高,运算速度与提高图像分辨率的关系不大,但由此带来的问题是压缩时的计算量大,编码压缩时间很长。
分形与小波变换的结合
1. 基于分形和小波的图像压缩
公式与原理
-
小波变换:
-
小波变换将图像分解为多个尺度的子带(低频和高频)。
-
公式:
W(a,b)=∫−∞∞f(t)⋅ψa,b(t) dtW(a,b)=∫−∞∞f(t)⋅ψa,b(t)dt其中,ψa,b(t)ψa,b(t) 是小波基函数,aa 是尺度参数,bb 是平移参数。
-
-
分形压缩:
-
分形压缩利用图像的自相似性,通过迭代函数系统(IFS)实现压缩。
-
公式:
xn+1=T(xn)xn+1=T(xn)其中,TT 是仿射变换,xnxn 是图像的像素值。
-
结合方法
结合方法
-
对图像进行小波变换,得到多个子带(低频和高频)。
-
对每个子带应用分形压缩方法,利用子带内的自相似性进一步压缩。
-
将压缩后的子带进行小波逆变换,重构图像。
import numpy as np import pywt from skimage import data, img_as_float from skimage.transform import resize # 读取图像 image = img_as_float(data.camera()) image = resize(image, (128, 128)) # 缩小图像以加快计算 # 小波变换 coeffs = pywt.wavedec2(image, 'haar', level=2) # 使用Haar小波,分解2层 # 分形压缩(简化示例:对每个子带进行阈值处理) def fractal_compress(coeff, threshold=0.1): return np.where(np.abs(coeff) < threshold, 0, coeff) compressed_coeffs = [fractal_compress(c) for c in coeffs] # 小波逆变换 reconstructed_image = pywt.waverec2(compressed_coeffs, 'haar') # 显示结果 import matplotlib.pyplot as plt plt.figure(figsize=(10, 5)) plt.subplot(1, 2, 1) plt.title("Original Image") plt.imshow(image, cmap='gray') plt.subplot(1, 2, 2) plt.title("Compressed Image") plt.imshow(reconstructed_image, cmap='gray') plt.show()
2. 分形与小波的多尺度分析
公式与原理
-
小波变换:
-
同上,将信号分解为多个尺度的分量。
-
-
分形维数计算:
-
使用盒计数法计算分形维数:
D=limϵ→0logN(ϵ)log(1/ϵ)D=ϵ→0limlog(1/ϵ)logN(ϵ)其中,N(ϵ)N(ϵ) 是用大小为 ϵϵ 的盒子覆盖分形所需的盒子数。
-
-
对信号进行小波变换,得到多个尺度的分量。
-
对每个尺度的小波系数计算分形维数,分析其自相似性。
import numpy as np import pywt from scipy.stats import linregress # 生成分形信号(例如:Weierstrass函数) def weierstrass(x, n=100): return np.sum([np.sin(2**k * x) / 2**k for k in range(n)], axis=0) x = np.linspace(0, 2 * np.pi, 1000) signal = weierstrass(x) # 小波变换 coeffs = pywt.wavedec(signal, 'db1', level=4) # 使用Daubechies小波,分解4层 # 计算分形维数(盒计数法) def fractal_dimension(z, threshold=0.1): z = np.where(np.abs(z) < threshold, 0, 1) n = [] for size in [2**i for i in range(1, 8)]: n.append(np.sum(z[:size * (len(z)//size)].reshape(-1, size).any(axis=1))) n = np.array(n) sizes = np.array([2**i for i in range(1, 8)]) slope, _, _, _, _ = linregress(np.log(1/sizes), np.log(n)) return slope # 计算每个尺度的分形维数 for i, coeff in enumerate(coeffs): print(f"Level {i} Fractal Dimension: {fractal_dimension(coeff)}")