用步长值创建(X,Y)递增元组列表的最快方法?

2024-05-16 06:17:45 发布

您现在位置:Python中文网/ 问答频道 /正文

我需要一种快速的方法来创建表示图像像素坐标的元组列表XY

其中,X是从0sizeY是从0size

步长值1会导致XY值(0,1,2,3…)过多的元组。使用大于1的步长值将减少处理时间。例如,如果步长值为2,则值将为(0、2、4、6…)。如果步长值为4,则值为(0、4、8、12…)

在纯python中,可以使用range命令。但是,默认情况下,NumPy安装在我的Linux发行版中。在NumPy中,可能会使用arrange命令,但我很难理解NumPy数组语法

PS:创建元组列表后,它将被随机洗牌,然后在循环中读取


编辑1

使用下面的this answer

fade in answer 1.gif

它不是在图像中淡入淡出,而是从左到右进行某种奇怪的擦拭。使用答案中的代码,稍作修改:

        step = 4
        size = self.play_rotated_art.size[0] - step

        self.xy_list = [
            (x, y)
            for x in range(0, size - step, step)
            for y in range(0, size - step, step)
        ]

错误更新

我的代码中有一个错误,现在工作正常:

fade in answer 1 fix.gif

更新后的代码为:

        self.step = 4
        size = self.play_rotated_art.size[0] - self.step

        self.xy_list = [
            (x, y)
            for x in range(0, size - self.step, self.step)
            for y in range(0, size - self.step, self.step)
        ]

        shuffle(self.xy_list)
        # Convert numpy array into python list & calculate chunk size
        self.current_chunk = 0
        self.chunk_size = int(len(self.xy_list) / 100)

    # Where we stop copying pixels for current 1% chunck
    end = self.current_chunk + self.chunk_size
    if end > len(self.xy_list) - 1:
       end = len(self.xy_list) - 1

    while self.current_chunk < end:
        x0, y0 = self.xy_list[self.current_chunk]
        x1 = x0 + self.step
        y1 = y0 + self.step
        box = (x0, y0, x1, y1)
        region = self.play_rotated_art.crop(box)
        self.fade.paste(region, box)
        self.current_chunk += 1

    self.play_artfade_count += 1
    return self.fade

TL;博士

我已经有了步骤值为1的代码,但是这段代码过于复杂,请求修改效率低下。上述一般性问题如果得到回答,将对其他人有更大帮助,对我也有帮助

步骤值为1的现有代码:

def play_artfade2(self):
    ''' PILLOW VERSION:
        Fade in artwork in 100 chunks leaving loop after chunk and
        reentering after Tkinter updates screen and pauses.
    '''
    if self.play_artfade_count == 100:
        # We'have completed a full cycle. Force graphical effects exit
        self.play_artfade_count = 0         # Reset art fade count
        self.play_rotated_value = -361      # Force Spin Art
        return None

    # Initialize numpy arrays first time through
    if self.play_artfade_count == 0:

        # Create black image to fade into
        self.fade = Image.new('RGBA', self.play_rotated_art.size, \
                              color='black')

        # Generate a randomly shuffled array of the coordinates
        im = np.array(self.play_rotated_art)
        X,Y = np.where(im[...,0]>=0)
        coords = np.column_stack((X,Y))
        np.random.shuffle(coords)

        # Convert numpy array into python list & calculate chunk size
        self.xy_list = list(coords)
        self.current_chunk = 0
        self.chunk_size = int(len(self.xy_list) / 100)

    # Where we stop copying pixels for current 1% chunck
    end = self.current_chunk + self.chunk_size
    if end > len(self.xy_list) - 1:
       end = len(self.xy_list) - 1

    while self.current_chunk < end:
        x0, y0 = self.xy_list[self.current_chunk]
        x1 = x0 + 1
        y1 = y0 + 1
        box = (x0, y0, x1, y1)
        region = self.play_rotated_art.crop(box)
        self.fade.paste(region, box)
        self.current_chunk += 1

    self.play_artfade_count += 1
    return self.fade

使用Pillow的Image.crop()Image.paste()对于单个像素来说是过分的,但是最初的工作设计在图像从200x200调整到333x333到512x512等时,未来的重点是利用“超级像素”,框大小为2x2、3x3、5x5等


Tags: 代码inselfforplaysizestepcurrent
2条回答

I need fast way to create a list of tuples representing image pixel coordinates (X, Y).

Where X is from 0 to size and Y is from 0 to size

使用range进行列表理解将有效:

xsize = 10
ysize = 10
coords = [(x, y) for x in range(xsize) for y in range(ysize)]

# this verifies the shape is correct
assert len(coords) == xsize * ysize

如果需要除1以外的步骤,请设置步骤参数:

coords = [(x, y) for x in range(0, xsize, 2) for y in range(0, ysize, 2)]

可以使用生成器表达式:

size = 16
step = 4

coords = (
    (x, y)
    for x in range(0, size, step)
    for y in range(0, size, step)
)

然后您可以像使用list一样对其进行迭代

for coord in coords:
    print(coord)

使用生成器而不是列表或元组具有内存效率更高的优点

相关问题 更多 >