Как сопоставить функцию со значениями RGB в изображении opencv - PullRequest
2 голосов
/ 04 мая 2019

Я читаю изображение, снятое через opencv, и хочу сопоставить функцию каждому значению пикселя в изображении. Выходными данными является массив массивов m x n x 3, где m и n - координаты длины и ширины изображения, а три значения - соответствующие значения синего, зеленого и красного для каждого пикселя.

Сначала я подумал запустить вложенный цикл for для каждого значения в изображении. Однако запуск занимает много времени, поэтому я ищу более эффективный способ быстрого зацикливания изображения.

Вот вложенный цикл:

a = list()
for row in img:
    for col in row:
        a.append(np.sqrt(np.prod(col[1:])))

adjusted = np.asarray(a).reshape((img.shape[0], img.shape[1]))

Этот код работает, но я бы хотел, чтобы он работал быстрее. Я знаю, что векторизация может быть вариантом, но я не знаю, как применить ее только к части массива, а не ко всему массиву. Для этого, я думаю, я мог бы изменить его на img.reshape((np.prod(img.shape[:2]),3)), а затем перебрать каждый набор из трех значений, но я не знаю правильную функцию / итератор для использования.

Кроме того, если opencv / numpy / scipy имеет другую функцию, которая делает именно это, это было бы очень полезно. Я также открыт для других вариантов, но я хотел бы поделиться некоторыми своими идеями.

В конце я хочу взять входные данные и вычислить среднее геометрическое значений красного и зеленого и создать массив геометрических средних n x m. Любая помощь будет оценена!

1 Ответ

2 голосов
/ 04 мая 2019

Это может быть векторизовано с использованием параметра axis в np.prod().Установка axis=-1 приведет к тому, что продукт будет снят только на последней оси.

Чтобы выполнить этот продукт только на двух последних каналах, индексируйте массив, чтобы извлечь только те каналы, используя img[..., 1:]

. Вы можете заменить свой код следующей строкой:

adjusted = np.sqrt(np.prod(img[..., 1:], axis=-1))

Ради интереса, давайте профилируем эти две функции, используя некоторые смоделированные данные:

import numpy as np
img = np.random.random((100,100,3))

def original_function(img):
  a = []
  for row in img:
      for col in row:
          a.append(np.sqrt(np.prod(col[1:])))
  adjusted = np.asarray(a).reshape((img.shape[0], img.shape[1]))

  return adjusted

def improved_function(img):
  return np.sqrt(np.prod(img[:,:,1:], axis=-1))

>>> %timeit -n 100 original_function(img)
100 loops, best of 3: 55.5 ms per loop

>>> %timeit -n 100 improved_function(img)
100 loops, best of 3: 115 µs per loop

Увеличение скорости в 500 раз!Прелесть обалденной векторизации:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...