efficently 1に、二値画像内のライン上のすべての値を設定するには?

ルークギブソン:

私は現在[COL]の2次元配列として格納されたバイナリ画像、[行]を有します。画像は線で2分割され、Iは1ライン上の全ての配列の値を設定します。

アレイの列を介して、現在、Iループ、配列[COL] [行]の値が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

前と下の写真の後...

ここでは、画像の説明を入力します。 ここでは、画像の説明を入力します。

norok2:

ここで、2D入力を必要とする方法のいくつ。彼らは正しい側に、正しい次元に取り組んでいるが、核となるアイデアが保持していることを確認するように調整する必要があるかもしれません。

  • 使用np.where()してスライスと1つの薄暗いをループ:
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のアプローチで、あなたは約取得します。Numbaとの大きさのスピードアップの2件の受注は、あなたが約取得コードを加速させました。大きさはスピードアップの3桁。

おすすめ

転載: http://10.200.1.11:23101/article/api/json?id=383366&siteId=1