Оптимизировать операцию модификации элемента в массиве numpy - PullRequest
0 голосов
/ 06 октября 2018

Так что мой код выполняет очень простую форму манипулирования изображением и сохраняет строку в изображении.

Это достигается главным образом путем преобразования изображения в массив с крошечным массивом (x * y * 3), а затем с помощью каждогочисловой элемент сначала нечетный.

Таким образом, массив теперь выглядит так: [ [ [odd_clr_val,odd_clr_val,odd_clr_vlue] ... ] .... ]

Теперь я конвертирую текст, который нужно сохранить, в двоичные данные и изменяю столько массива, сколько необходимок элементам, имеющим нечетную четность для представления нуля и даже для 1.

Теперь я просто читаю его обратно с помощью простой программы.

Код выглядит так:

from PIL import Image
import numpy as np
import time
#if the value of pixel is:
#Odd = 0 , even = 1
#We make every element odd

img = Image.open('Desktop/test.jpg')

arr = np.array(img)
x,y,z  = np.shape(arr)
count = 0
initial = time.time()

#This nested loop makes every element odd but is very slow and in need to be optimized
for i in range(x):
    for j in range(y):
        count += 1
        k = arr[i][j]
        arr[i][j][0] =  k[0] + int(not(k[0]%2)) # adds 1 if k[i] is odd else 0
        arr[i][j][1] =  k[1] + int(not(k[1]%2))
        arr[i][j][2] =  k[2] + int(not(k[2]%2))

print("Time delta: %f"%(time.time() - initial ))
print("The amount of data you can store in this image is: %d kiBs"%((count*3)/1024))
#every element of this image is odd now

z = input("Enter the string:")

long_array = []
for i in z:
    long_array += list(map(int,list(format(ord(i), '#010b')[2:])))


#everything is in binary now

counter = 0
try:
    for i in range(x):
        for j in range(y):
            k = arr[i][j]

            arr[i][j][0] = k[0] if not(long_array[counter]) else k[0]+1
            counter += 1

            arr[i][j][1] = k[1] if not(long_array[counter]) else k[1]+1
            counter += 1

            arr[i][j][2] = k[2] if not(long_array[counter]) else k[2]+1
            counter += 1
except IndexError:
    print("Done")
except:
    print("An unidentified error occured!")

image = Image.fromarray(arr)

image.show()

image.save("secret.png")

Моя проблема заключается в том, что я не могу оптимизировать верхний цикл моего кода, поскольку для его завершения требуется около 16-ти секунд (с матрицей изображения 800x600x3).Кроме того, нижний цикл моего кода очень быстр по сравнению с верхним.

Так есть ли способ оптимизировать мой верхний цикл с помощью какой-нибудь обалденной магии?

1 Ответ

0 голосов
/ 06 октября 2018

Вы можете использовать побитовую арифметику .Сделать все пиксели нечетными можно в одной строке:

arr |= 1

Встраивание вашей битовой строки:

arr.ravel()[:len(long_array)] += np.array(long_array, arr.dtype)

Кстати, добавление одного может создать очевидные изменения пикселей из-за переполнения.Например, ярко-красный (255, 1, 1) станет черным (0, 2, 2).Вы можете избежать этого, вместо этого вычитая один.

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