说我有一个RGB值列表,如下所示:
rgbL = [[20 45 40] [30 45 60] .... [70 50 100]]
然后,我有一个图片,说img = cv.imread("location")
现在,如果图像RGB值在我的RGB值列表(rgbL)中,我想将图像的所有RGB值更改为(255,0,0)。
我可以通过以下代码执行此操作:
for rgb in rgbL :
k = list(filter(None, rgb[1:-1].split(" ")))
r = int(k[0])
g = int(k[1])
b = int(k[2])
img[np.all(img == (r, g, b), axis=-1)] = (255,0,0)
但是上面的代码花费了太长时间,因为我的“ rgbL”列表太长了。
有没有一种方法可以无循环地执行此操作?以麻木的方式实现它的最佳方法是什么?
答案 0 :(得分:1)
将您的rgbL
和img
转换为numpy数组。一种无循环的方法:
sh = img.shape
img = img.reshape(-1, 3)
img[np.where(((rgbL[:,None,:]-img)==0).all(axis=2))[1]]=np.array([255,0,0])
img = img.reshape(sh)
使用rgbL
的每一行获取图像差异,并检查all
的RGB零差异以使用np.where
进行替换。
采样img
并输出:
img:
[[ 20 45 40]
[ 30 45 60]
[ 0 1 2]
[ 70 50 100]
[ 4 5 6]]
rgbL:
[[ 20 45 40]
[ 30 45 60]
[ 70 50 100]]
Output:
[[255 0 0]
[255 0 0]
[ 0 1 2]
[255 0 0]
[ 4 5 6]]
更新 :每个OP关于将字符串dict键转换为numpy数组的评论:
rgbL = np.array([list(map(int,[s.strip() for s in key.strip('[').strip(']').strip(' ').split(' ') if s.strip()])) for key in rgb_dict.keys()])
答案 1 :(得分:0)
上述算法为 O(rgbL的长度*图片大小)
我们可以将其降低到 O(rgbL的长度+图片大小)
set_rgbl = set(rgbL)
height = img.shape[0]
width = img.shape[1]
BLUE_COLOR = (255, 0, 0)
for h in range(0, height):
for w in range(0, width):
if list(img[h, w]) in set_rgbl:
img[h, w] = BLUE_COLOR
这里发生的是我们创建了一组rgbL值。套入是恒定时间操作。查找也一样。因此,当我们为每个像素迭代图像中的每个像素值时,我们花费的时间为 O(1)。这样可以改善我们的时间复杂度。
希望有帮助。