要将一个2D数组切分成多个块,可以考虑使用以下几种方法,具体取决于如何定义块的划分规则和需求。如果你希望将2D数组均匀地切分成固定大小的小块,可以使用简单的循环和切片操作。

如何将一个2D数组切分成多个块_Image

1、问题背景

Python 中, 如果有一个 raw 数据文件,将其读入到字节缓冲区(python 字符串),其中每一个数据值代表一个2d 数组中 8 位像素。已知此图片的宽度和高度,想将图片切分成多个块,并且每一个块的面积必须大于最小块面积(如:1024 字节),小于最大块面积(如:2048 字节)。这些块的高度和宽度是任意的,只要满足面积约束即可,并且块的大小不必相同。此外,输入数据的长度也不一定是2的幂。

2、解决方案

方法一:

为了代码尽量简洁,可以将数据存储为按行存储的行。

import collections
import operator

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

def split_image(data, width, height, MIN_AREA, MAX_AREA):

    tiles = list()
    if width >= MIN_AREA:
        # 每行可以细分为多个块
        tile_width = width / (width / MIN_AREA) # 整数除法
        rows = split_(data, width)
        row_tiles = [split_(row, tile_width) for row in rows]
        tiles = reduce(operator.add, row_tiles)
    elif width < MIN_AREA:
        # 每个块由多行组成
        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
                # 特殊情况,我们需要垂直分割最后三行
                # 如果宽度也是3,那么我们就遇到了问题,但如果我们在这里
                # 那么MIN_AREA为4,MAX_AREA为8,行数大于等于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

    return tiles

方法二:

如果是在处理图片,可以使用 PIL(Python Imaging Library)。

import Image

def split_image(imagefile, MIN_AREA, MAX_AREA):

    i = Image.open(imagefile)

    width, height = i.size
    data = list(i.getdata())

    tiles = list()
    if width >= MIN_AREA:
        tile_width = width / (width / MIN_AREA) # 整数除法
        for y in range(0, height, tile_width):
            for x in range(0, width, tile_width):
                box = (x, y, x + tile_width, y + tile_width)
                region = i.crop(box)
                tiles.append(list(region.getdata()))
    elif width < MIN_AREA:
        min_tile_height = int(MIN_AREA / width) + 1
        tile_height = height / (height / min_tile_height)
        tile_size = tile_height * width
        for y in range(0, height, tile_height):
            for x in range(0, width):
                box = (x, y, x + width, y + tile_height)
                region = i.crop(box)
                tiles.append(list(region.getdata()))

    return tiles

函数 split_image 将图像切成块,并将每个块的数据存储到一个列表中。然后可以对每个块单独处理。

有时候需要根据块的形状或大小来划分数组,这可能需要使用图像处理库或者几何算法来检测并划分块。这些示例展示了如何根据不同的需求将2D数组切分成多个块。具体选择哪种方法取决于我们的应用场景和数据结构。