Маскировка с использованием статистики пикселей - PullRequest
1 голос
/ 19 марта 2020

Я пытаюсь замаскировать плохие пиксели в наборе данных, взятом из детектора. В моей попытке придумать общий способ сделать это, чтобы я мог запускать один и тот же код для разных изображений, я попробовал несколько разных методов, но ни один из них не сработал. Я довольно новичок в области кодирования и анализа данных в Python, поэтому я мог бы использовать руку в терминах, понятных компьютеру.

В качестве примера рассмотрим матрицу

A = np.array([[3,5,50],[30,2,6],[25,1,1]])

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

Я знаю, что эта техника маскирования работает, но я попытался расширить следующий код для работы со стандартным отклонением:

mask = np.ones(np.shape(A))
mask.flat[A.flat > 20] = 0

Я пытался:

mask = np.ones(np.shape(A))
for i,j in A:
    mask.flat[A[i,j] - 2*np.std(A) < np.mean(A) < A[i,j] + 2*np.std(A)] = 0

Что приводит к ошибке:

ValueError: слишком много значений для распаковки (ожидается 2)


Если у кого-то есть лучшая техника для статистического удаления плохих пикселей в образ, я все уши. Спасибо за помощь!

==========

РЕДАКТИРОВАТЬ

После некоторых проб и ошибок я попал в место, которое могло бы помочь уточнить мои вопрос. Новый код:

for i in A:
    for j in i:
        mask.flat[ j - 2*np.std(A) < np.mean(A) < j + 2*np.std(A)] = 0

При этом выдается сообщение об ошибке «неподдерживаемый индекс итератора». Я хотел бы, чтобы for l oop итерировал по каждому элементу в массиве, проверял, меньше ли оно / больше 2 стандартных отклонений от среднего значения, и устанавливает его на ноль.

Ответы [ 2 ]

1 голос
/ 19 марта 2020

Вот подход, который будет немного быстрее на больших изображениях:

import numpy as np
import matplotlib.pyplot as plt

# generate dummy image
a = np.random.randint(1,5, (5,5))
# generate dummy outliers
a[4,4] = 20
a[2,3] = -6

# initialise mask
mask = np.ones_like(a)

# subtract mean and normalise to standard deviation.
# then any pixel in the resulting array that has an absolute value > 2 
# is more than two standard deviations away from the mean
cond = (a-np.mean(a))/np.std(a)

# find those pixels and set them to zero.
mask[abs(cond) > 2] = 0

Проверка:

a
array([[ 1,  1,  3,  4,  2],
       [ 1,  2,  4,  1,  2],
       [ 1,  4,  3, -6,  1],
       [ 2,  2,  1,  3,  2],
       [ 4,  1,  3,  2, 20]])

np.round(cond, 2)
array([[-0.39, -0.39,  0.11,  0.36, -0.14],
       [-0.39, -0.14,  0.36, -0.39, -0.14],
       [-0.39,  0.36,  0.11, -2.12, -0.39],
       [-0.14, -0.14, -0.39,  0.11, -0.14],
       [ 0.36, -0.39,  0.11, -0.14,  4.32]])

mask 
array([[1, 1, 1, 1, 1],
       [1, 1, 1, 1, 1],
       [1, 1, 1, 0, 1],
       [1, 1, 1, 1, 1],
       [1, 1, 1, 1, 0]])
0 голосов
/ 19 марта 2020

You A является трехмерным, поэтому вам нужно распаковать, используя три переменные, как показано ниже.

A = np.array([[3,5,50],[30,2,6],[25,1,1]])
for i in A:
    for j in i:
        print(j)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...