0

私の現在の Python コード (以下) は、画像をn 個のスライスにスライスし、各スライスの座標を行/列ごとに返します。

xMin/yMin 1/1 から始めて一度に 1 行ずつ完成させるのではなく、画像の真ん中から始めて螺旋状に外に出て、最終的にすべてのスライスを完成させたいと思います。これはどのように達成できますか?

import math


slices = 11
imageWidth = 1024
imageHeight = 576
totalPixels = imageWidth * imageHeight
print 'Slices: ' + str(slices)

# Re-calculate slices
slices = int(slices/2)*2
print 'Re-calculated slices: ' + str(slices)
print 'Total pixels in image: ' + str(totalPixels)
print 'Maximum slices allowed: ' + str(totalPixels/4)

factor = math.sqrt( slices )
print 'Factor: ' + str(factor)

if (slices > totalPixels/4):
    print 'You cannot use more than ' + int(totalPixels/4) + ' slices!'
else:

    regionWidth = int(math.ceil(imageWidth / factor))
    regionHeight = int(math.ceil(imageHeight / factor))
    print 'Region size: ' + str(int(regionWidth)) + 'x' + str(int(regionHeight))
    print 'Region width: '  + str(regionWidth)
    print 'Region height: ' + str(regionHeight)

    imageWidthRounded = int( math.ceil(factor) * math.ceil( imageWidth / factor ) )
    restWidth = imageWidthRounded - imageWidth
    imageHeightRounded = int( math.ceil(factor) * math.ceil( imageHeight / factor ) )
    restHeight = imageHeightRounded - imageHeight
    print 'Rest width: ' + str(restWidth)
    print 'Rest height: ' + str(restHeight)

    factorRounded = int(math.ceil(factor))
    print 'Factor rounded: ' + str(factorRounded)


    xMin = 0
    xMax = 0
    yMin = 0
    yMax = 0


    rows = factorRounded
    columns = factorRounded
    print 'Total rows: ' + str(rows)
    print 'Total columns: ' + str(columns)


    for column in range(1, columns+1):
        xMin = 0
        xMax = 0
        if column == columns:
            print 'Col '+ str(column) + ' (last column) '
            yMin = (column*regionHeight + 1) - regionHeight
            yMax += (regionHeight - restHeight)

        else:
            print 'Col '+ str(column)
            yMin = (column*regionHeight + 1) - regionHeight
            yMax += regionHeight


        for row in range(1, rows+1):
            if row == rows:
                xMin = (row*regionWidth + 1) - regionWidth
                xMax += (regionWidth-restWidth)

                print 'Row ' + str(row) + ':  xMin=' +str(xMin) + '\t xMax=' + str(xMax) + '\t yMin=' + str(yMin) + '\t yMax=' + str(yMax) + ' (last row)'
            else:
                xMin = (row*regionWidth + 1) - regionWidth
                xMax += regionWidth

                print 'Row ' + str(row) + ':  xMin=' +str(xMin) + '\t xMax=' + str(xMax) + '\t yMin=' + str(yMin) + '\t yMax=' + str(yMax)
4

1 に答える 1

1

まず、いくつかのケースを列挙してみてください。

ケース 1:

o

中心値を返します。

ケース 2:

o o
o o

左上から時計回りに値を返します。

ケース 3:

o o o
o o o
o o o

中央を返し、左上から時計回りに値を返します。

...

一般に、グリッドの次元が奇数の場合、最初に中央の値を返す必要があることがわかります。この後、現在のスライスの境界コーナーを追跡し、これらのコーナーを次のレベルに繰り返し拡張して、すべてのスライスを処理できます。グリッドの次元によって、スライス (および反復) の総数を決定できます。

generatorとして実装された関数は次のとおりです。

def spiral(m):
    length = len(m[0])
    last = length - 1
    mid = length // 2
    spirals_remaining = mid

    if length % 2 == 1:
        yield m[mid][mid]
        box = [(mid-1, mid-1), (mid-1, mid+1), (mid+1, mid+1), (mid+1, mid-1)]
    else:
        box = [(mid-1, mid-1), (mid-1, mid), (mid, mid), (mid, mid-1)]

    while spirals_remaining > 0:
        # yield spiral values clockwise from top left corner
        top = m[box[0][0]][slice(box[0][1], box[1][1])]
        for x in top:
            yield x
        right = [m[i][box[1][1]] for i in range(box[1][0], box[2][0])]
        for x in right:
            yield x
        bottom = m[box[2][0]][slice(box[2][1], box[3][1], -1)]
        for x in bottom:
            yield x
        left = [m[i][box[3][1]] for i in range(box[3][0], box[0][0], -1)]
        for x in left:
            yield x

        # update bounding box for next spiral
        box[0] = box[0][0] - 1, box[0][1] - 1
        box[1] = box[1][0] - 1, box[1][1] + 1
        box[2] = box[2][0] + 1, box[2][1] + 1
        box[3] = box[3][0] + 1, box[3][1] - 1
        spirals_remaining -= 1

出力例:

>>> m = [[1, 2, 3, 4], 
...      [5, 6, 7, 8], 
...      [9, 10, 11, 12], 
...      [13, 14, 15, 16]]
>>> list(spiral(m))
[6, 7, 11, 10, 1, 2, 3, 4, 8, 12, 16, 15, 14, 13, 9, 5]
于 2014-02-21T07:55:43.663 に答える