Теперь Кью работает в режиме чтения

Мы сохранили весь контент, но добавить что-то новое уже нельзя

Обработка больших массивов. Есть спецы?

Есть задача. Преобразовать двумерный массив цветов в массив яркостей.
Когда речи о картинке 200*200 все ок. Но когда дело выходит на базовые 2к на 4к, базовый алгоритм перебора, виснет на минуты.
Тем не менее Image.convert исполняет это за несколько секунд.
Преобразовал двумерный массив в np-массив, преобразовал последний в линейный. Попробовал обрабатывать такой. Результат рунтайм ошибка, счётчик словил превышение.
Начал курить исходники библиотеки pil. Пока тщетно.
Может кто то знает, как реализован алгоритм в ПИЛ, он тоже вроде как на пайтоне писан. Или знает другую, быструю реализацию алгоритма.
ПрограммированиеPython+3
Крехта Виталий
  ·   · 563
Пишу код и т.п.  · 13 сент 2022  · itustinov.ru
Добрый день. В Pillow действительно уже есть метод convert(). Можно им пользоваться, если не требуется какая-то особая формула. Дальше можно превратить в двумерный Numpy-массив.
import numpy as np
from PIL import Image

def open_grayscale(fp):
    with Image.open(fp) as im:
        return np.array(im.convert('L'), dtype=np.uint8)
Вообще, главное при работе с большими массивами в Python — не обрабатывать элементы по отдельности. В Numpy, если у массивов одинаковые размеры, их можно воспринимать как скаляры. В примере ниже, rgba разбирается на три массивоподобных двумерных представления (по сути, прокси-объекты, обеспечивающие доступ к значениям оригинального массива по другим индексам; это еще называют slicing — нарезание на ломтики). При умножении на скаляр, Numpy умножает весь массив или представление, а не один элемент. Дальше сложение происходит поэлементно.
def open_rgba(fp):
    with Image.open(fp) as im:
        return np.array(im.convert('RGBA'), dtype=np.float32)

rgba = open_rgba(fn)
grayscale = \
    rgba[:, :, 0] * 0.299 + \
    rgba[:, :, 1] * 0.587 + \
    rgba[:, :, 2] * 0.114

print(rgba.shape)
print(grayscale.shape)

Image.fromarray(np.uint8(grayscale), 'L').show()
Время конвертации методом convert():
(5457, 3603)

real    0m0.271s
user    0m0.222s
sys     0m0.049s
Вторым способом:
(5457, 3603, 4)
(5457, 3603)

real    0m0.405s
user    0m0.288s
sys     0m0.116s
Были бы плюсы, ещё бы добавил :)
Спасибо...