Python - эффективное представление пикселей и связанных значений - PullRequest
6 голосов
/ 05 февраля 2011

Я использую 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

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

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

Ответы [ 3 ]

4 голосов
/ 06 февраля 2011

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

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

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

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

2 голосов
/ 06 февраля 2011

Я бы сказал, да, это путь. Определенно над созданием чего-то из словарей! При построении массива vector, затем используйте структурированный массив, то есть определите свой собственный тип 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, они существуют просто как удобный способ заполнения разреженной матрицы. Вы должны преобразовать их в другой (разреженный) тип матрицы перед выполнением обновлений. Документация

0 голосов
/ 05 февраля 2011

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

...