我已经打开了我的图像,可以访问各个像素的RGB值,但我现在要做的是将一个函数分别应用于每个像素的RGB值。也就是说,我不想以相同的方式在整个图像中的所有像素上应用它;我想以不同的方式应用它,具体取决于是否为每个像素,蓝色值是>红色>绿色(而不是绿色>红色>蓝色等等)。
所以我的问题是,如何访问每个像素中的单个RGB元素(而不是一次访问整个图像中的所有红色,绿色和蓝色值)?最终我的问题是“最快的方法是什么?”因为显然需要一段时间才能在每个像素上单独应用一个功能,但是现在我很高兴只需要任何解决方案。
感谢您的任何建议。
编辑清晰度/更具特异性:
我实际上是根据127.5 - abs(127.5 - 红色/绿色/蓝色)的顺序尝试应用不同的指令集,而不仅仅是红色>绿色>蓝色的顺序(如上所述, bc我试图简化)。一旦针对给定像素确定了该排序,则应用适当的指令集。同样,这是逐像素的 - 我没有根据图像中的所有红色值来订购东西,只是单个像素的rgbs。所以我想要做的就是这样(这里我只是玩了六个可能的命令中的一个;为了简洁,我省略了其他五种可能性):
def rgb_manip(red,green,blue):
r_max = int(127.5 - abs(127.5 - red))
g_max = int(127.5 - abs(127.5 - green))
b_max = int(127.5 - abs(127.5 - blue))
if r_max >= g_max >= b_max:
if r_max >= g_max + b_max:
new_red = red + g_max + b_max
new_green = green - g_max
new_blue = blue - b_max
else:
new_red = red + r_max
new_green = green - r_max + b_max
new_blue = blue - b_max
# elif... And so on, with a different set of instructions for each of the 6 possibilities depending on the order of the r_max, g_max, b_max values (e.g., r_max >= b_max >= g_max or g_max >= r_max >= b_max, etc, etc)
答案 0 :(得分:2)
如果将图像转换为数组,则可以访问一个像素的RGB值,或所有像素的R,G或B值之一:
from __future__ import division
import numpy as np
from PIL import Image
im = Image.open(imfile)
arr = np.asarray(im)
arr[..., 0] # All Red values
arr[..., 1] # All Green values
arr[..., 2] # All Blue values
arr[0, 0] # RGB for first corner pixel
arr[m, n] # RGB for pixel at [m, n]
arr[m, n, 0] # R value for pixel [m, n]
arr[m, n, c] # value for color c at pixel [m, n]
您可以使用argsort
获取每个像素的排名,如:
def transform(a, c=255/2):
return c - np.abs(c - a)
ranking = transform(arr).argsort(axis=-1)
将标准值从最后(颜色)轴的最小值到最大值进行排序。所以这给出了一个新的数组,其中每个'颜色'数组而不是RGB值是转换后的R,B和G值的排序(称为“R',B',G'”),所以如果角落像素为G' > B' > R'
,然后ranking[0, 0]
为[0, 2, 1]
,因为R'(0
)最小,接着是B'(2
),最后是最大的是G'(1
)。
执行上述操作的优点是您有一个数组,说明在哪个像素上使用哪种方法。它最多可以有六个变换通道的排序。我建议为每个排序定义一个单独的函数。然后,必须在函数内做出一个决定(第二个嵌套if / else在你的例子中),并且它可以用np.where
完成,它将一个东西应用于满足条件的数组部分,并且其他的事情。这仅适用于两个选项,但如果有多个选项(if / elif / else),其他技术也可以同样有效。
def bgr(a):
""" for when B' < G' < R'
"""
t = transform(a)
red, green, blue = a.transpose([2,0,1])
# same as: red, green, blue = a[..., 0], a[..., 1], a[..., 2]
r_max, g_max, b_max = t.transpose([2,0,1])
assert np.all((b_max <= g_max) & (g_max <= r_max)), "doesn't match rank"
condition = r_max >= g_max + b_max
new_red = np.where(condition, red + g_max + b_max, red + r_max)
new_green = np.where(condition, green - g_max, green - r_max + b_max)
new_blue = blue - b_max
return np.dstack([new_red, new_green, new_blue])
此功能仅适用于您的第一个if
。我会为这六件事中的每一件做一个新的功能,并将它们填入一个像这样的字典:
functions = {
(0, 1, 2) : rgb, # for R'<G'<B'
(0, 2, 1) : rbg, # for R'<B'<G'
#etc...
}
如果您的输出也具有RGB值:
out = np.empty_like(arr)
然后遍历所有六个排名/功能:
for rank, func in functions.items():
mask = np.all(transform(arr).argsort(-1) == rank, -1)
out[mask] = func(arr[mask])