【问题标题】:Hilbert-Peano curve to scan image of arbitrary sizeHilbert-Peano 曲线扫描任意大小的图像
【发布时间】:2016-11-22 14:52:51
【问题描述】:

我已经用 Python(来自 Matlab 的)编写了 Hilbert-Peano 空间填充曲线的实现来展平我的 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 的幂的多维数组(例如:256*256 或 512*512,如果是二维数组(图像))。

有人知道如何将它扩展到任意大小的数组吗?

【问题讨论】:

    标签: algorithm image-processing rasterizing hilbert-curve space-filling-curve


    【解决方案1】:

    我遇到了同样的问题,并编写了一个算法,可以为 2D 和 3D 中任意大小的矩形生成希尔伯特曲线。 55x31 的示例:curve55x31

    这个想法是递归地应用类似 Hilbert 的模板,但在将域维度减半时避免出现奇怪的大小。如果维度恰好是 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 版本和更多文档

    【讨论】:

      【解决方案2】:

      我找到了 Lutz Tautenhahn 的这个页面:

      “绘制任意大小的空间填充曲线”(http://lutanho.net/pic2html/draw_sfc.html

      该算法没有名称,他没有引用其他任何人,并且草图表明他自己想出了它。

      我想知道这对于 z 阶曲线是否可行以及如何实现?

      [1]Draw A Space-Filling Curve of Arbitrary Size

      【讨论】:

      • 虽然它是真的,但经典的希尔伯特曲线是基于 2 的幂,因为它是一个分形,你也可以不惜代价忽略它。但是要回答你的问题。没有。
      • 你将如何修改原始曲线以摆脱 2 假设的力量?
      • 例如尝试更长的曲线!?
      • 我考虑过这一点,但我将不得不剪切曲线的一部分以适合我的图像,因此我将失去两个空间上接近的像素也会在空间填充曲线上接近的属性。
      【解决方案3】:

      我最终选择,正如 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.,“任意大小矩形区域的伪希尔伯特扫描算法”

      【讨论】:

        猜你喜欢
        • 2011-04-15
        • 2018-07-23
        • 1970-01-01
        • 2018-04-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-05-05
        相关资源
        最近更新 更多