python - 优化 numpy 数组中的元素修改操作
问题描述
所以我的代码做了一种非常基本的图像处理形式,并将字符串存储到图像中。
它主要通过将 image 转换为 numpy 数组(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 图片矩阵)。再加上我的代码的下部循环与上部循环相比非常快。
那么有没有办法使用一些 numpy 魔法来优化我的上循环?
解决方案
您可以使用按位算术。使所有像素为奇数可以在一行中完成:
arr |= 1
嵌入你的位串:
arr.ravel()[:len(long_array)] += np.array(long_array, arr.dtype)
顺便说一句,添加一个会因为溢出而产生明显的像素变化。例如鲜红色 (255, 1, 1) 将变为黑色 (0, 2, 2)。您可以通过减去一个来避免这种情况。
推荐阅读
- c - 在C中正确使用不等于?
- java - Java 在 Ubuntu 服务器上使用 selenium 运行 Chromedriver
- electron - 为什么 setMenu(null) 在 Windows 上有效,但在 Linux 上无效?
- types - Clojure 中的向量与具有不可变数据的列表
- php - PHP从数据库显示名称到页面
- ruby-on-rails - ActionCable-5.2.2 not working in nginx and puma broken pipe error using JRUBY 9.2.0
- python - Tkinter 函数“root.after()”不运行指定的函数
- excel - 将命名范围从表转置到另一个命名范围
- javascript - 检测点击外部组件反应钩子
- r - 如何绘制具有变量给定半径的散点图?