Возникла проблема при использовании цикла for в python для применения skimage.filters.threshold_otsu () к списку сегментов в изображении / массиве - PullRequest
1 голос
/ 13 апреля 2019

Моя проблема четко объяснена ниже:

import numpy as np
from skimage.util.shape import view_as_blocks
from skimage.filters import threshold_otsu

Я прочитал серое изображение в виде массива "arr", форма которого:

>>arr.shape

(10000, 15200)

Я сегментировал это изображение на 25 * 38 блоков.где каждый блок имеет 400 * 400 пикселей, используя:

>>img= view_as_blocks(arr, block_shape=(400,400))
>>img.shape
(25, 38, 400, 400)

Теперь, когда я использую threshold_otsu (), чтобы найти пороговое значение для каждого сегмента в отдельности, я получаю следующие значения:

print(threshold_otsu(img[11,6],16))
-14.606459

print(threshold_otsu(img[11,7],16))
-15.792943

print(threshold_otsu(img[11,11],16))
-15.547393

print(threshold_otsu(img[12,16],16))
-16.170353

Но когда я использую для цикла , чтобы получить все пороговые значения одновременно, я получаю разные значения.

>>crdf
array([[11,  6],
       [11,  7],
       [11, 11],
       [12, 16],
       [10,  9],
       [21, 26],
       [15, 15],
       [12, 17],
       [12, 12],
       [14, 10],
       [20, 26]], dtype=int64) 

>>for i in range(0,4):
    >>print(threshold_otsu(img[crdf[i]],16))

-14.187654
-14.187654
-14.187654
-13.238304

Я допустил какую-либо ошибку в цикле for?Если нет, то почему я получаю разные пороговые значения, когда я делаю это индивидуально для каждого сегмента и когда я использую цикл for для итерации для тех же соответствующих сегментов.

1 Ответ

2 голосов
/ 13 апреля 2019

Когда вы используете массив Numpy для индексирования в другой массив Numpy, вы запускаете расширенное индексирование , которое работает не так, как базовое индексирование, и, следовательно, дает результат, которого вы не ожидали.

Чтобы использовать базовое индексирование, вам необходимо обеспечить индексирование целыми числами через запятую или стандартными кортежами Python.

Поэтому быстрое решение заключается в преобразовании ваших индексов в кортеж:

img[tuple(crdf[i])]

Но, вероятно, лучше не использовать массив Numpy для списка индексов.Если вы не выполняете математических операций с вашими индексами оптом или у вас короткий список индексов, вы ничего не выиграете в производительности, сделав его массивом, и, возможно, даже потеряете некоторые из-за накладных расходов, связанных с созданием исходного массива и преобразованием его обратно в кортеж.позже.

Попробуйте простой список пар индексов, где сами пары являются кортежами:

crdf = [
    (11,  6),
    (11,  7),
    (11, 11),
    (12, 16),
    (10,  9),
    (21, 26),
    (15, 15),
    (12, 17),
    (12, 12),
    (14, 10),
    (20, 26)
]

# then you can iterate and index directly, without conversion:

for i in range(0, 4):
    print(threshold_otsu(img[crdf[i]], 16))

# or even like this, which is usually more idiomatic and easier to read:

for pair in crdf[:4]:
    print(threshold_otsu(img[pair], 16))

Если вы получили crdf в результате какой-то другой обработки, и это уже быломассив Numpy, вы также можете преобразовать его в список кортежей за один шаг:

crdf = [tuple(pair) for pair in crdf]
...