簡體   English   中英

如何從顏色字典快速更改圖像中的像素?

[英]How can I quickly change pixels in a image from a color dictionary?

我有一個圖像,我想從顏色圖中更改圖像中的所有顏色,例如。 {(10,20,212):(60,40,112)...}

目前,我正在讀取圖像 OpenCV,然后遍歷圖像數組並更改每個像素,但這非常慢。

有什么辦法可以更快地做到這一點嗎?

我對這個問題提供兩個答案。 這個答案更基於 PIL/Pillow ,另一個更基於OpenCV 結合我的其他答案閱讀此答案,並可能混合搭配。

您可以使用調色板來完成。 如果您不熟悉調色圖像,而不是在每個像素位置都有一個 RGB 值,您可以在多達 256 種顏色的調色板中使用一個簡單的 8 位索引。

因此,我們可以做的是將您的圖像加載為 PIL 圖像,並將其量化為您擁有的一組輸入顏色。 然后每個像素將具有地圖中顏色的索引。 然后只需用您要映射到的顏色替換調色板。

#!/usr/bin/env python3

import numpy as np
from PIL import Image

def QuantizeToGivenPalette(im, palette):
    """Quantize image to a given palette.

    The input image is expected to be a PIL Image.
    The palette is expected to be a list of no more than 256 R,G,B values."""

    e = len(palette)
    assert e>0,    "Palette unexpectedly short"
    assert e<=768, "Palette unexpectedly long"
    assert e%3==0, "Palette not multiple of 3, so not RGB"

    # Make tiny, 1x1 new palette image
    p = Image.new("P", (1,1))

    # Zero-pad the palette to 256 RGB colours, i.e. 768 values and apply to image
    palette += (768-e)*[0]
    p.putpalette(palette)

    # Now quantize input image to the same palette as our little image
    return im.convert("RGB").quantize(palette=p)

# Open input image and palettise to "inPalette" so each pixel is replaced by palette index
# ... so all black pixels become 0, all red pixels become 1, all green pixels become 2...
im = Image.open('image.png').convert('RGB')

inPalette = [
    0,0,0,    # black
    255,0,0,  # red
    0,255,0,  # green
    0,0,255,  # blue
    255,255,255 # white
    ]
r = QuantizeToGivenPalette(im,inPalette)

# Now simply replace the palette leaving the indices unchanged
newPalette = [
    255,255,255,  # white
    0,255,255,    # cyan
    255,0,255,    # magenta
    255,255,0,    # yellow
    0,0,0         # black
    ]

# Zero-pad the palette to 256 RGB colours, i.e. 768 values
newPalette += (768-len(newPalette))*[0]

# And finally replace the palette with the new one
r.putpalette(newPalette)

# Save result
r.save('result.png')

輸入圖像

在此處輸入圖片說明

輸出圖像

在此處輸入圖片說明

所以,具體是什么,你問與舊的顏色值映射到新的字典做,你會想初始化oldPalette你的詞典的按鍵newPalette到您的字典的

關鍵詞:Python、PIL、枕頭、圖像、圖像處理、量化、量化、特定調色板、給定調色板、指定調色板、已知調色板、重新映射、重新映射、顏色映射、映射。

這里這里有一些關於調色圖像的有用的詞。

我對這個問題提供兩個答案。 這個答案更基於OpenCV ,另一個更基於 PIL/Pillow。 結合我的其他答案閱讀此答案,並可能混合搭配。

您可以使用 Numpy 的linalg.norm()來查找顏色之間的距離,然后使用linalg.norm() argmin()來選擇最近的。 然后,您可以使用 LUT “查找表”根據圖像中的現有值查找新值。

#!/usr/bin/env python3

import numpy as np
import cv2

def QuantizeToGivenPalette(im, palette):
    """Quantize image to a given palette.

    The input image is expected to be a Numpy array.
    The palette is expected to be a list of R,G,B values."""

    # Calculate the distance to each palette entry from each pixel
    distance = np.linalg.norm(im[:,:,None] - palette[None,None,:], axis=3)

    # Now choose whichever one of the palette colours is nearest for each pixel
    palettised = np.argmin(distance, axis=2).astype(np.uint8)

    return palettised

# Open input image and palettise to "inPalette" so each pixel is replaced by palette index
# ... so all black pixels become 0, all red pixels become 1, all green pixels become 2...
im=cv2.imread("image.png",cv2.IMREAD_COLOR)

inPalette = np.array([
   [0,0,0],             # black
   [0,0,255],           # red
   [0,255,0],           # green
   [255,0,0],           # blue
   [255,255,255]],      # white
   dtype=np.uint8)

r = QuantizeToGivenPalette(im,inPalette)

# Now make LUT (Look Up Table) with the 5 new colours
LUT = np.zeros((5,3),dtype=np.uint8)
LUT[0]=[255,255,255]  # white
LUT[1]=[255,255,0]    # cyan
LUT[2]=[255,0,255]    # magenta
LUT[3]=[0,255,255]    # yellow
LUT[4]=[0,0,0]        # black

# Look up each pixel in the LUT
result = LUT[r]

# Save result
cv2.imwrite('result.png', result)

輸入圖像

在此處輸入圖片說明

輸出圖像

在此處輸入圖片說明

關鍵詞:Python、PIL、枕頭、圖像、圖像處理、量化、量化、特定調色板、給定調色板、指定調色板、已知調色板、重新映射、重新映射、顏色圖、映射、LUT、linalg.norm。

我認為您可能會發現使用 opencv 的內置 LUT 功能很有幫助,如此處所述

該函數已經有一個 python 綁定,它將原始矩陣和一個 LUT 作為輸入,並將新矩陣作為輸出返回。

沒有在 python 中使用它的教程,但是有一個在 C++ 中使用它的教程,我認為它會很有用,可以在這里找到。 該教程將此方法列為解決此類問題的最快方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM