我有一个原始数据文件,我读入一个字节缓冲区(一个python字符串)。每个数据值表示表示图像的2d阵列的8位像素。我知道这张图片的宽度和高度。
我想将图像分割成图块,使得每个图块区域必须大于“最小图块区域”(例如1024字节)并且小于“最大图块区域”(例如2048字节)。只要满足区域约束,这些瓦片的高度和宽度就是无效的,并且瓦片不需要全部具有相同的尺寸。此外,输入数据的大小/长度不保证是2的幂。
什么是在python中执行此操作的最佳方法
此致
答案 0 :(得分: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区域的条件对于此工作是必要的)
在某些情况下,任何算法都无法做到这一点,例如在4到8之间的切片中拆分3x3图像。
假设数据按行存储(例如在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
请记住,在最后一种情况下,您可以并排获得两个或三个瓷砖,而其他所有瓷砖都堆叠在它们上方(或下方,取决于行'0'的位置)。
如果您需要存储多于原始像素数据,只需调整切片创建过程。
答案 1 :(得分:1)
如果您正在使用图像,则应使用PIL(Python Imaging Library)。然后你只需加载图像:
import Image
i = Image.open(imagefile)
您可以轻松裁剪任意大小的区域:
box = (FirstCornerX, FirstCornerY, SecondCornerX, SecondCornerY)
region = im.crop(box)
所以你可以使用它。你也可以在Image对象和2d数组之间进行转换,但我不太清楚它是如何完成的。我有几个函数可以在图像之间转换 numpy 数组,我会看看是否可以找到它们。
此外,您可能需要查看PIL handbook以查找处理图片的文档和配方。