我已经用Python编写了一个Hilbert-Peano空间填充曲线的实现(来自Matlab)以展平我的2D图像:
def hilbert_peano(n):
if n<=0:
x=0
y=0
else:
[x0, y0] = hilbert_peano(n-1)
x = (1/2) * np.array([-0.5+y0, -0.5+x0, 0.5+x0, 0.5-y0])
y = (1/2) * np.array([-0.5+x0, 0.5+y0, 0.5+y0, -0.5-y0])
return x,y
然而,经典的Hilbert-Peano曲线仅适用于形状为2的幂的多维数组(例如:在2D数组(图像)的情况下为256 * 256或512 * 512)。
有人知道如何将其扩展为任意大小的数组吗?
答案 0 :(得分:2)
我遇到了同样的问题,并编写了一种算法,可以为2D和3D中任意大小的矩形生成类似希尔伯特的曲线。 55x31的示例:curve55x31
这个想法是递归地应用类似希尔伯特的模板,但是在将域尺寸减半时避免奇数大小。如果尺寸恰好是2的幂,则将生成经典的希尔伯特曲线。
def gilbert2d(x, y, ax, ay, bx, by):
"""
Generalized Hilbert ('gilbert') space-filling curve for arbitrary-sized
2D rectangular grids.
"""
w = abs(ax + ay)
h = abs(bx + by)
(dax, day) = (sgn(ax), sgn(ay)) # unit major direction
(dbx, dby) = (sgn(bx), sgn(by)) # unit orthogonal direction
if h == 1:
# trivial row fill
for i in range(0, w):
print x, y
(x, y) = (x + dax, y + day)
return
if w == 1:
# trivial column fill
for i in range(0, h):
print x, y
(x, y) = (x + dbx, y + dby)
return
(ax2, ay2) = (ax/2, ay/2)
(bx2, by2) = (bx/2, by/2)
w2 = abs(ax2 + ay2)
h2 = abs(bx2 + by2)
if 2*w > 3*h:
if (w2 % 2) and (w > 2):
# prefer even steps
(ax2, ay2) = (ax2 + dax, ay2 + day)
# long case: split in two parts only
gilbert2d(x, y, ax2, ay2, bx, by)
gilbert2d(x+ax2, y+ay2, ax-ax2, ay-ay2, bx, by)
else:
if (h2 % 2) and (h > 2):
# prefer even steps
(bx2, by2) = (bx2 + dbx, by2 + dby)
# standard case: one step up, one long horizontal, one step down
gilbert2d(x, y, bx2, by2, ax2, ay2)
gilbert2d(x+bx2, y+by2, ax, ay, bx-bx2, by-by2)
gilbert2d(x+(ax-dax)+(bx2-dbx), y+(ay-day)+(by2-dby),
-bx2, -by2, -(ax-ax2), -(ay-ay2))
def main():
width = int(sys.argv[1])
height = int(sys.argv[2])
if width >= height:
gilbert2d(0, 0, width, 0, 0, height)
else:
gilbert2d(0, 0, 0, height, width, 0)
可在https://github.com/jakubcerveny/gilbert上获得3D版本和更多文档
答案 1 :(得分:1)
我在Lutz Tautenhahn找到了这个页面:
&#34;绘制任意大小的空间填充曲线&#34; (http://lutanho.net/pic2html/draw_sfc.html)
该算法没有名称,他没有引用任何其他人,草图表明他自己想出了它。
我想知道这对于z阶曲线是否可行以及如何?
答案 2 :(得分:0)
我最终选择,正如Betterdev所建议的那样,自适应曲线不是那么直接[1],计算更大的曲线,然后摆脱我的图像形状之外的坐标:
# compute the needed order
order = np.max(np.ceil([np.log2(M), np.log2(N)]))
# Hilbert curve to scan a 2^order * 2^order image
x, y = hilbert_peano(order)
mat = np.zeros((2**order, 2**order))
# curve as a 2D array
mat[x, y] = np.arange(0, x.size, dtype=np.uint)
# clip the curve to the image shape
mat = mat[:M, :N]
# compute new indices (from 0 to M*N)
I = np.argsort(mat.flat)
x_new, y_new = np.meshgrid(np.arange(0, N, dtype=np.uint), np.arange(0, M, dtype=np.uint))
# apply the new order to the grid
x_new = x_new.flat[I]
y_new = y_new.flat[I]
[1] Zhang J.,Kamata S.和Ueshige Y.,&#34;用于任意大小的矩形区域的伪希尔伯特扫描算法&#34;