2016-12-15 8 views
1

Возможно ли выполнять обработку небезопасных изображений в Python?Небезопасная обработка изображений в Python, как LockBits в C#

Как и в случае с C#, я столкнулся с жесткой стеной с обработкой пикселей на Python, поскольку метод getPixel из Image просто работает слишком медленно.

Возможно ли получить прямой доступ к изображению в памяти, например LockBits в C#? Это заставит мою программу работать намного быстрее.

Спасибо,

Марк

ответ

2

Там нет ничего "небезопасно" об этом.

Как только вы понимаете, как работает Python, становится патентным, что вызов метода для получения информации на каждом пикселе будет медленным.

Прежде всего, хотя вы не даете никакой информации об этом, я предполагаю, что вы используете «Pillow» - библиотеку изображений Python (PIL), которая является самой известной библиотекой для манипуляции изображениями с использованием Python. Поскольку это пакет сторонних производителей, ничто не обязывает вас использовать это. (PIL действительно есть getpixel метод на изображениях, но не getPixel один)

Один простой способ иметь все данные в манипулируемо образом, чтобы создать ByteArray, объект данных изображения - данное изображение в img переменной, можно сделать:

data = bytearray(img.tobytes()) 

И все, у вас есть линейный доступ ко всем данным на вашем изображении. Чтобы попасть в конкретный пиксель, вам нужно получить ширину, высоту изображения и байты на пиксель. Более поздний из них не является прямым атрибутом изображения в PIL, поэтому вы должны его вычислить с учетом изображения mode. Наиболее распространенные типы изображений RGB, RGBA и L.

Так что, если вы хотите написать прямоугольник на «х, у, ширина, размер» на изображении, вы можете сделать это:

def rectangle(img, x,y, width, height): 
    data = bytearray(img.tobytes()) 
    blank_data = (255,) * witdh * bpp 
    bpp = 3 if data.mode == 'RGB' else 4 if data.mode == 'RGBA' else 1 
    stride = img.width * bpp 
    for i in range(y, y + height): 
     data[i * stride + x * bpp: i * stride + (x + width) * bpp)] = blank_data 
    return Image.frombytes(img.mode, (img.width, img.height), bytes(data)) 

Это мало используется, но для простых манипуляций. Люди, которым необходимо применять фильтры и другие более сложные алгоритмы в изображениях с Python, обычно получают доступ к изображению с помощью высокопроизводительного пакета обработки данных numpy - python, который тесно связан с множеством других пакетов, которые имеют специфические для изображений вещи - обычно устанавливаются как scipy ,

Таким образом, чтобы иметь изображение как ndarray, который уже делает все выше координат -> байт преобразование для вас, вы можете использовать:

import scipy.misc 
data = scipy.misc.imread(<filename>) 

(Проверьте документацию на https://docs.scipy.org/doc/scipy/reference/)

+0

Это может быть вопрос об основах, но я никогда не встречал такого выражения перед данными [i * stride + x * bpp: i * stride + (x + width) * bpp)] Что это такое: «там? Это словарь? Я не могу обвести вокруг себя –

+0

Это простая последовательность с числовым значением с использованием индекса числового среза - выражение просто вычисляет адрес (в байтах) первого пикселя прямоугольника на линии изображения (тот, который находится в line (x, i) и последний пиксель (тот, что у (x + width, i)). Если вы никогда не видели индексы фрагментов Python, вам лучше изучить их: https://docs.python.org/3 /tutorial/introduction.html#lists – jsbueno

+0

О, я вижу, я не был знаком с оператором нарезки Python. Теперь все имеет смысл. Спасибо! –