gpt4 book ai didi

python-3.x - 如何有效地将二进制图像中一行上方的所有值设置为 1?

转载 作者:行者123 更新时间:2023-12-02 16:08:24 25 4
gpt4 key购买 nike

我目前有一个二进制图像,存储为 [col][row] 的二维数组。
图像被一条线分成 2 部分,我想将该线上方的所有数组值设置为 1。

目前,我遍历数组的列,遍历列的行(从下到上)以找到数组 [col][row] 的值为 1 的第一行。然后我中断了遍历行并将我从该列中断的行上方的所有值设置为 1。

不幸的是,对于 1920x1080 的图像,这大约需要 3 秒。如何更有效地实现这一目标?

for x in range(len(image)):
col = image[x]
minY= -1

for y in range(len(col)):
if image[x][-y] != 0:
minY = y
break

if minY != -1:
under = [0] * minY
over = [1] * (len(col) - minY)
newCol = over + under
image[x] = newCol

下面的照片之前和之后......

enter image description here
enter image description here

最佳答案

这里有几种需要二维输入的方法。
可能需要进行调整以确保它们在正确的方面和正确的维度上工作,但核心思想仍然存在。

  • 使用 np.where()并用切片在一个昏暗处循环:
  • import numpy as np


    def side_fill_np(arr, value, flag):
    rows, cols = arr.shape
    idx = np.where(arr == flag)
    for i in range(cols):
    arr[idx[0][i]:, idx[1][i]] = value
    return arr
  • 使用完全显式循环(类似于你的,但不知何故更干净),但加速了 numba
  • import numba as nb


    @nb.jit
    def side_fill_nb(arr, value, flag):
    rows, cols = arr.shape
    for j in range(cols):
    found = False
    for i in range(rows):
    if found:
    arr[i, j] = value
    elif arr[i, j] == flag:
    found = True

    为了测试我们是否得到了正确的结果,我们使用以下方法生成一些输入:
    def gen_data(shape):
    rows, cols = shape
    arr = np.zeros(shape, dtype=bool)
    indexes = (np.random.randint(0, rows - 1, cols), np.arange(cols))
    arr[indexes] = True
    return arr

    测试内容如下:
    np.random.seed(0)  # for reproducible results
    arr = gen_data((10, 20))
    print(arr.astype(int))
    # [[0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
    # [0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0]
    # [0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0]
    # [0 0 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
    # [0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0]
    # [1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1]
    # [0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0]
    # [0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 1 1 0 0 0]
    # [0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 1 0 0]
    # [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]]

    side_fill_np(arr, True, True)
    print(arr.astype(int))
    # [[0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
    # [0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0]
    # [0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 1 0]
    # [0 1 1 1 0 1 0 1 0 0 0 0 0 1 0 0 0 0 1 0]
    # [0 1 1 1 0 1 0 1 1 0 0 0 0 1 0 0 0 0 1 0]
    # [1 1 1 1 0 1 1 1 1 0 0 0 0 1 0 0 0 0 1 1]
    # [1 1 1 1 0 1 1 1 1 0 1 0 0 1 1 0 0 0 1 1]
    # [1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 0 1 1]
    # [1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1]
    # [1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1]]

    现在是大约的时间。您的输入尺寸:
    arr = gen_data((2000, 2000))
    %timeit side_fill(arr, True, True)
    # 1 loop, best of 3: 2.48 s per loop
    %timeit side_fill_np(arr, True, True)
    # 10 loops, best of 3: 52.6 ms per loop
    %timeit side_fill_nb(arr, True, True)
    # 100 loops, best of 3: 6.14 ms per loop

    如您所见,使用 NumPy 方法(这是我能想到的尽可能多的矢量化),您可以获得大约。 2 个数量级的加速,使用 Numba 加速代码,您可以获得大约。 3 个数量级的加速。

    关于python-3.x - 如何有效地将二进制图像中一行上方的所有值设置为 1?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60975098/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com