Python-эффективное представление пикселей и связанных с ними значений



Я использую python для работы с большими (приблизительно 2000 x 2000) матрицами, где каждая I, J точка в матрице представляет собой один пиксель.

Сами матрицы разрежены (то есть значительная их часть будет иметь нулевые значения), но при их обновлении они, как правило, являются операциями инкремента, для большого числа соседних пикселей в прямоугольном "блоке", а не случайных пикселей здесь или там (свойство, которое я в настоящее время не использую в своих интересах..). Боюсь, немного новенький. матричная арифметика, но я изучил ряд возможных решений, включая различные вкусы scipy разреженных матриц. Пока что наиболее перспективными представляются координатные матрицы (COO). Поэтому, например, когда я хочу увеличить одну форму блока, я должен сделать что-то вроде:
>>> from scipy import sparse
>>> from numpy import array
>>> I = array([0,0,0,0])
>>> J = array([0,1,2,3])
>>> V = array([1,1,1,1])
>>> incr_matrix = sparse.coo_matrix((V,(I,J)),shape=(100,100))
>>> main_matrix += incr_matrix  #where main_matrix was previously defined

В будущем я хотел бы иметь более богатое представление значений пикселей в anycase (кортежи для представления RGB и т. д.), Что-то, что numpy array не поддерживает из коробки (или, возможно, я нужно использовать это ).

В конечном счете у меня будет несколько таких матриц, которые мне понадобятся для выполнения простой арифметики, и мне нужно, чтобы код был максимально эффективным-и распределяемым, поэтому мне нужно будет иметь возможность сохранять и обмениваться этими объектами в малом представлении без существенных штрафов. Мне интересно, является ли это правильным путем, или я должен искать свои собственные структуры, используя dicts и т. д.?

123   3  

3 ответов:

Общее правило состоит в том, чтобы сначала заставить код работать, а затем при необходимости оптимизировать...

В этом случае используйте обычный массив numpy 2000x2000 или 2000x2000x3 для RGB. С этим будет намного проще и быстрее работать, это всего лишь небольшое требование к памяти, и имеет много других преимуществ, например, вы можете использовать стандартные инструменты обработки изображений и т. д.

Затем, если необходимо, "чтобы сохранить и обменять эти объекты", вы можете просто сжать их с помощью gzip, pytables, jpeg или чего-то еще, но нет необходимости ограничивать требования к хранилищу данных, основанные на манипуляциях.

Таким образом, вы получаете как более быструю обработку, так и лучшее сжатие.

Я бы сказал, Да, это правильный путь. Определенно над созданием чего-то из словарей! При построении "векторного" массива используйте структурированный массив, т. е. определите свой собственный dtype:

rgbtype = [('r','uint8'),('g','uint8'),('b','uint8')]

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

main_matrix['r'][blk_slice] += incr_matrix['r']
main_matrix['g'][blk_slice] += incr_matrix['g']
main_matrix['b'][blk_slice] += incr_matrix['b']

Обновление:

Похоже, что вы не можете выполнять матричные операции с coo_matrix, они существуют просто как удобный способ заполнения разреженной матрицы. Вы должны преобразовать их в другое (разреженный) тип матрицы перед выполнением обновлений. документация

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

    Ничего не найдено.

Добавить ответ:
Отменить.