0

バイト バッファ (Python 文字列) に読み込む生データ ファイルがあります。各データ値は、画像を表す 2 次元配列の 8 ビット ピクセルを表します。この画像の幅と高さを知っています。

各タイル領域が「最小タイル領域」(例: 1024 バイト) よりも大きく、「最大タイル領域」(例: 2048 バイト) よりも小さくなるように、画像をタイルに分割したいと思います。これらのタイルの高さと幅は、領域の制約が満たされている限り任意であり、すべてのタイルが同じサイズである必要はありません。また、入力データのサイズ/長さが 2 の累乗であるとは限りません。

Pythonでこれを行う最良の方法は何ですか

よろしく

4

2 に答える 2

2

「最高」の意味がわからないので、「コードがすっきりしている」という意味だと思います。

次のデータがあるとします。

from collections import Sequence
import operator

assert(type(MIN_AREA) is int)
assert(type(MAX_AREA) is int)
assert(type(width) is int)
assert(type(height) is int)
assert(instanceof(data, Sequence))
assert(len(data) == width * height)
assert(MAX_AREA >= 2 * MIN_AREA)

(これが機能するには、MINおよびMAX領域の条件が必要です)

たとえば、3x3の画像を4〜8のタイルに分割するなど、どのアルゴリズムでもこれを実行できない場合があります。

データが行ごとに格納されているとします(たとえば、PNM仕様のように)。

def split_(seq, size):
    return [seq[i:i+size] for i in range(0,len(seq),size)]

tiles = list()
if width >= MIN_AREA:
    # each row is subdivided into multiple tiles
    tile_width = width / (width / MIN_AREA) # integral division
    rows = split_(data, width)
    row_tiles = [split_(row, tile_width) for row in rows]
    tiles = reduce(operator.add, row_tiles)
elif width < MIN_AREA:
    # each tile is composed of rows
    min_tile_height = int(MIN_AREA / width) + 1
    tile_height = height / (height / min_tile_height)
    tile_size = tile_height * width
    tiles = split_(data, tile_size)
    if len(tiles[-1]) < MIN_AREA:
        if (tile_height > 2):
            tiles[-2] += tiles[-1]
            del tiles[-1]
        else: # tile_height == 2, the case 1 don't pass here
            # special case, we need to split vertically the last three rows
            # if the width was 3 too we have a problem but then if we are here
            # then MIN_AREA was 4, and MAX_AREA was 8, and the rows are >= 5
            if width > 3:
                last_three_rows = split_(tiles[-2] + tiles[-1], width)
                tiles[-2] = reduce(operator.add,[row[:width/2] for row in last_three_rows])
                tiles[-1] = reduce(operator.add,[row[width/2:] for row in last_three_rows])
            else: # width = 3 and MIN_AREA = 4
                last_five_rows = reduce(operator.add, tiles[-3:])
                three_columns = [last_five_rows[i::3] for i in range(3)]
                tiles[-3:] = three_columns

最後のケースでは、2つまたは3つのタイルが並んでいて、他のすべてのタイルはそれらの上(または行「0」の場所によっては下)に積み重ねられていることを覚えておいてください。

生のピクセルデータ以上のものを保存する必要がある場合は、タイルの作成プロセスを調整するだけです。

于 2010-08-18T10:53:38.620 に答える
1

画像を扱う場合は、PIL (Python Imaging Library) を使用する必要があります。次に、画像をロードします。

import Image
i = Image.open(imagefile)

また、任意のサイズの領域を簡単にトリミングできます。

box = (FirstCornerX, FirstCornerY, SecondCornerX, SecondCornerY)
region = im.crop(box)

あなたはそれを扱うことができます。Image オブジェクトと 2 次元配列の間で変換することもできますが、どのように行われたかはよく覚えていません。画像とnumpy配列の間で双方向に変換する関数がいくつかありました。それらを見つけることができるかどうかを確認します。

また、PIL ハンドブックを参照して、画像を操作するためのドキュメントとレシピを見つけることもできます。

于 2010-08-18T08:47:40.043 に答える