gpt4 book ai didi

python - 替换OpenCV中多个RGB值的所有像素

转载 作者:行者123 更新时间:2023-12-05 04:52:00 29 4
gpt4 key购买 nike

我对图像处理和 python 还很陌生,所以请多多包涵

我正在尝试拍摄一张大图片 (5632x2048),它基本上是一张带有省份的世界地图(从钢铁雄心 4 中提取),每个省份都用不同的 RGB 值着色,并用一组颜色颜色,每种颜色对应一个特定的国家。我目前正在使用此代码

import numpy as np
import cv2
import sqlite3

dbPath = 'PATH TO DB'
dirPath = 'PATH TO IMAGE'

con = sqlite3.connect(dbPath)
cur = con.cursor()

im = cv2.imread(dirPath)

cur.execute('SELECT * FROM Provinces ORDER BY id')
provinceTable = cur.fetchall()

for line in provinceTable:
input_rgb = [line[1], line[2], line[3]]
if line[7] == None:
output_rgb = [255,255,255]
else:
output_rgb = line[7].replace('[', '').replace(']','').split(',')
im[np.all(im == (int(input_rgb[0]), int(input_rgb[1]), int(input_rgb[2])), axis=-1)] = (int(output_rgb[0]), int(output_rgb[1]), int(output_rgb[2]))

cv2.imwrite('result.png',im)

我遇到的问题是它非常慢(50 分钟后还没有完成),因为我肯定是错误地使用了 numpy 循环而不是矢量化(我的一个概念'我还是新手,不知道该怎么做)。 Google 也不是很有帮助。

执行此操作的最佳方法是什么?

编辑:忘记提及我要替换的值的数量相当大(~15000)

最佳答案

正如我在评论中提到的,我认为您需要使用 np.take(yourImage, LUT),其中 LUT 是一个查找表。

因此,如果您制作一个与您的形状相同的虚拟图像:

import numpy as np

# Make a dummy image of 5632x2048 RGB values
im = np.random.randint(0,256,(5632,2048,3), np.uint8)

那将是 34MB。现在将其 reshape 为 RGB 值的 tall 向量:

# Make image into a tall vector, as tall as necessary and 3 RGB values wide
v = im.reshape((-1,3))

形状为 (11534336, 3) 然后使用 np.dot() 将其展平为 24 位值而不是三个 8 位值/p>

# Make into tall vector of shape 11534336x1 rather than 11534336x3
v24 = np.dot(v.astype(np.uint32),[1,256,65536])

您现在将拥有形状为 (11534336,) 的 24 位像素值的一维向量

现在创建您的 RGB 查找表(我在这里制作所有 2^24 RGB 条目,您可能需要更少):

RGBLUT = np.zeros((2**24,3),np.uint8)

并设置LUT。因此,假设您要将原始图像中的所有颜色映射到输出图像中的中灰 (128):

RGBLUT[:] = 128

现在做 np.dot() 的事情就像我们对图像做的一样所以我们得到一个形状为 (224,1) 而不是形状 (224,3):

LUT24 = np.dot(RGBLUT.astype(np.uint32), [1,256,65536])

然后在表中进行实际查找:

result = np.take(LUT24, v24)

在我的 Mac 上,5632x2048 图像需要 334 毫秒。


然后通过移位和与操作 reshape 并转换回三个 8 位值,以撤消 np.dot() 的效果。

我目前无法测试重新组装,但它看起来很像:

BlueChannel   = result & 0xff         # Blue channel is bottom 8 bits
GreenChannel = (result>>8) &0 xff # Green channel is middle 8 bits
RedChannel = (result>>16) &0 xff # Red channel is top 8 bits

现在将这三个单 channel 组合成一个 3 channel 图像:

RGB = np.dstack(RedChannel, GreenChannel, BlueChannel))

然后从 tall 向量重新整形为原始图像的尺寸:

RGB = RGB.reshape(im.shape)

关于设置 LUT,对于比中灰更有趣的东西,如果你想映射橙色,即 rgb(255,128,0) 到洋红色,即 rgb(255,0,255) 你会做一些事情行:

LUT[np.dot([255,128,0],[1,256,65536])] = [255,0,255]  # map orange to magenta
LUT[np.dot([255,255,255],[1,256,65536])] = [0,0,0] # map white to black
LUT[np.dot([0,0,0],[1,256,65536])] = [255,255,255] # map black to white

关键词:Python、图像处理、LUT、RGB LUT 24位LUT、查找表。

关于python - 替换OpenCV中多个RGB值的所有像素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66616437/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com