我继续编写代码(当前版本将在介绍之后发布),并设置了一个算法,根据特定的模式编辑图像。代码与我之前的文章有关:
How can a specific row of (RGB) values in numpy be sought for, in order to replace said row with a different set of (RGB) values?
所述模式(可以在代码的“if”部分中找到:
- 在对数组的RGB(行)值进行计数并且计数的数量等于偶数之后,然后编辑具有该值的每行,包括具有该值的最后一行。
- 在对数组的RGB(行)值进行计数后,并且计数的数量等于非偶数,然后编辑具有该值的每行,不包括具有该值的最后一行。
当前的代码确实需要高效,目前对于一个1366x768.PNG的图像,它需要~Month<来计算。当计算完成时,则应该保存所得到的图像。
我相信“偶数”的条件已经生效,我不相信“非偶数”的条件已经生效。
如何有效地对这种模式进行编码?我怎样才能使代码更高效,这样如果代码运行,它就能在同一天完成计算?
在此声明之后,当前代码将被发布,注解存在于所述代码中,感谢您的每一条评论和每一个答案。
from PIL import Image
import numpy as np
path = "insert_path_here" #PATH OF IMAGE THAT IS TO BE EDITED
A = np.array(Image.open(path).convert('RGB')) #NUMPY ARRAY FROM PATH INTO RGB VALUE
R = 1; G = 1; B = 1
for R in range(1, 254):
for G in range(1, 254):
for B in range(1, 254):
C = (((A == [R, G, B]).all(axis=2)).sum()) #COUNT HOW OFTEN RGB IS PRESENT (IN ROW)
CE = C[C % 2 == 0]; #CONDITION "IF COUNT IS EVEN AMOUNT"
CO = C[C % 2 != 0]; #CONDITION "IF COUNT IS NOT EVEN AMOUNT"
#print(C, CE, CO); #PRINT COUNT VALUES IF NEEDED
print(R, G, B) #PRINT "CURRENT RGB" VALUES (IN TERMINAL)
if CE.size != 0: #IF ROW NOT EMPTY (!NEEDED TO RUN!)
#print("EVEN",C-0) #PRINT HOW MANY ROWS ARE TO BE PROCESSED (IF EVEN)
A[(A == [R, G, B]).all(axis=2)] = [1, 1, 1] #HAS TO READ EVERY ROW
#print(A)
if CO.size != 0: #IF ROW NOT EMPTY (!NEEDED TO RUN!
#print("ODD",C-1) #PRINT HOW MANY ROWS ARE TO BE PROCESSED (IF ODD)
A[(A == [R, G, B]).all(axis=2)] = [255, 255, 255] #HOW TO EXCLUDE LAST ROW OF SAID VALUE?
#print(A)
Image.fromarray(A).save('NEWIMG.PNG')
字符串
当A[(A == [R, G, B]).all(axis=2)]
搜索行时,if CO.size != 0:
应用的部分是使RGB值应用的最后一行保持先前状态的部分。(不改)
2条答案
按热度按时间wxclj1h51#
您似乎将RGB作为一个集合来处理,而不是单独读/写每个通道。
在这种情况下,将RGB打包为单个值可以大大提高性能并简化实现。
例如,您可以使用下列公式:
字符串
例如,
(50, 100, 200)
可以打包为50100200
。你可以这样计算自己,但还有一个更有效的方法。将图像转换为RGBA,即8位x 4个通道,然后只把它当作一个32位整数的数组。
型
这与以下计算相同(在little-endian环境中):
型
请注意,我给出的这个公式是为了让你知道,但你不会自己做这个计算。例如,如果您想要特定颜色的压缩值,可以执行下列动作:
型
一旦您有了压缩值图像,就不再需要使用花哨的方法来处理颜色。
A[A == color] = new_color
的值。np.count_nonzero(A == color)
的值。np.unique(A, return_counts=True)
的值。为了排除最后一行,
np.unique
具有返回每种颜色第一次出现的索引的功能。因此,通过将图像上下翻转,可以检索最后一次出现的索引。“这允许我们只比较每种颜色的最后一行。下面是完整的代码:
型
此函数扫描一行中的每种唯一颜色,因此执行速度在很大程度上取决于图像中显示的颜色数。对于随机生成的1366 x 768的图像,它需要5秒多的时间,但对于颜色较少的图像,如照片,它会比这快得多。
of1yzvn42#
我将首先关注速度要求。在纯python中,长度为256^3的
for
循环将非常慢。如果可能,您应该尝试使用向量化的numpy操作以提高效率。开始,我们只需要考虑图像中实际存在的颜色:
字符串
即使有了这个大大减少的颜色子集,在纯python中迭代它们仍然非常慢。对于偶数颜色计数,我们可以使用
np.isin
重写代码,以完全消除for
循环:型
然后,我们可以处理更小的剩余情况下,颜色计数是奇数。我使用了
for
循环,因为我找不到一种方法来矢量化它。我们忽略一种颜色只出现一次的情况,因为在这种情况下,我们不会修改它唯一出现的行,因为该行也是最后一行型
把它们放在一起:
型
上面的代码在网上找到的随机1200x600图像上运行了大约2分钟。