У меня есть массив Numpy 3d, который представляет собой просто список серых изображений:
images = np.zeros((xlen, height, width), dtype=int)
for i in range (5):
images[i] = cv2.imread(filename[i], cv2.IMREAD_GRAYSCALE)
Все изображения очень похожи, но все они имеют случайные шумовые пиксели. Моя идея заключается в том, что пиксель шума - это максимальное или минимальное значение по сравнению с теми же пикселями на других изображениях.
Итак, мне нужно:
- Найдите минимальное и максимальное значения для каждого пикселя
- Рассчитайте среднее значение для каждого пикселя между всеми изображениями без этих максимальных и минимальных значений.
- Заменить все минимальные и максимальные значения расчетным средним
Я реализовал это наивным способом, используя стандартные функции Python, но это слишком медленно:
#remove highest and lowest values for each pixel
for el in range (height):
for em in range (width):
mylist = []
for j in range (0, xlen):
mylist.append(images[j][el][em])
indmin = mylist.index(min(mylist))
indmax = mylist.index(max(mylist))
temp_counterx=0
temp_sum = 0
for j in range (0, xlen):
if (j!=indmin) and (j!=indmax):
temp_counterx +=1
temp_sum += mylist[j]
temp_val = int(temp_sum/temp_counterx)
images[indmin][el][em]=temp_val
images[indmax][el][em]=temp_val
Можно ли ускорить это с помощью Numpy?
UPD: Принято решение, предложенное faultr, с небольшими изменениями:
mins = np.min(images, axis=0)
maxs = np.max(images, axis=0)
sums = np.sum(images, axis=0)
# compute the mean without the extremes
mean_without_extremes = (sums - mins - maxs) / (xlen - 2)
mean_without_extremes = mean_without_extremes.astype(int)
# replace maxima with the mean
images = np.where((mins==images), images, mean_without_extremes)
images = np.where((maxs==images), images, mean_without_extremes)
...и получили 30-кратное увеличение скорости! Кажется, что numpy предоставляет действительно быстрый и мощный вычислительный движок, просто его использование иногда может быть сложным из-за сложной структуры данных, с которой он работает.