您的问题和假设有许多问题。
您无法使用np.unique(image)
您无法使用np.unique(im)的图像中的颜色。让我们来看看为什么通过仅具有4个强度的随机图像:0,1,2和3。
import numpy as np
import cv2
# Ensure repeatable, deterministic randomness!
np.random.seed(42)
# Make a random image
im = np.random.randint(0,4,(480,640,3), dtype=np.uint8)
看起来像这样,每行是一个像素的RGB三联网:
array([[[2, 2, 3],
[3, 2, 1],
[2, 2, 0],
...,
[3, 3, 2],
[0, 0, 1],
[1, 1, 1]],
...,
[3, 3, 1],
[2, 3, 0],
[0, 1, 3]]], dtype=uint8)
现在,如果你尝试获得这样的唯一颜色,它就不起作用,因为每个颜色是
组合的3强度:
np.unique(im) # prints: array([0, 1, 2, 3], dtype=uint8)
,如果您希望唯一颜色的数量,则需要查找三个RGB / BGR值的唯一组合数:
np.unique(im.reshape(-1, im.shape[2]), axis=0)
给出图像中唯一的RGB / BGR三联网的向量 - 每行都是唯一的颜色组合:
array([[0, 0, 0],
[0, 0, 1],
[0, 0, 2],
[0, 0, 3],
[0, 1, 0],
[0, 1, 1],
[0, 1, 2],
[0, 1, 3],
[0, 2, 0],
[0, 2, 1],
[0, 2, 2],
[0, 2, 3],
[0, 3, 0],
[0, 3, 1],
[0, 3, 2],
[0, 3, 3],
[1, 0, 0],
[1, 0, 1],
[1, 0, 2],
[1, 0, 3],
[1, 1, 0],
[1, 1, 1],
[1, 1, 2],
[1, 1, 3],
[1, 2, 0],
[1, 2, 1],
[1, 2, 2],
[1, 2, 3],
[1, 3, 0],
[1, 3, 1],
[1, 3, 2],
[1, 3, 3],
[2, 0, 0],
[2, 0, 1],
[2, 0, 2],
[2, 0, 3],
[2, 1, 0],
[2, 1, 1],
[2, 1, 2],
[2, 1, 3],
[2, 2, 0],
[2, 2, 1],
[2, 2, 2],
[2, 2, 3],
[2, 3, 0],
[2, 3, 1],
[2, 3, 2],
[2, 3, 3],
[3, 0, 0],
[3, 0, 1],
[3, 0, 2],
[3, 0, 3],
[3, 1, 0],
[3, 1, 1],
[3, 1, 2],
[3, 1, 3],
[3, 2, 0],
[3, 2, 1],
[3, 2, 2],
[3, 2, 3],
[3, 3, 0],
[3, 3, 1],
[3, 3, 2],
[3, 3, 3]], dtype=uint8)
或,作为简单的唯一颜色:
len(np.unique(im.reshape(-1, im.shape[2]), axis=0)) # prints 64
所以,对于您的图像:
# Open image
im = cv2.imread('image.png',cv2.IMREAD_UNCHANGED)
# Count unique colours
len(np.unique(im.reshape(-1, im.shape[2]), axis=0) # prints 790
有比预期的颜色更多 h1>
为什么我有比我期望更多的颜色?两个最常见的原因是:
- 图像被保存为JPEG Li>
- 存在抗锯齿的文本或绘制的形状
让我们看看jpeg如何拯救你!
# Load image and count colours
im = cv2.imread('image.png',cv2.IMREAD_UNCHANGED)
len(np.unique(im.reshape(-1, im.shape[2]), axis=0)) # prints 790
# Save as JPEG
cv2.imwrite('temp.jpg',im)
# Reload and recount just the same
im = cv2.imread('temp.jpg',cv2.IMREAD_UNCHANGED)
len(np.unique(im.reshape(-1, im.shape[2]), axis=0)) # prints 4666 !!!
如何将图像调用图像 - (将颜色缩小为固定调色板)? h1>
如果要将图像映射到您自己的特定调色板,首先需要在BGR订单中指定您的调色板(@ 987654333)以匹配OpenCV的订购:
palette = np.array([
[0,0,0], # Black
[93,136,106], # Green
[208,224,64], # Blue
[85,124,168]], # Brown
dtype=np.uint8)
然后读取您的图像丢弃完全无意义的alpha通道:
test = cv2.imread("image.png",cv2.IMREAD_COLOR)
然后从每个像素计算到每个调色板条目的距离:
distance = np.linalg.norm(test[:,:,None] - palette[None,None,:], axis=3)
然后选择每个像素最接近的一个调色板颜色:
palettised = np.argmin(distance, axis=2).astype(np.uint8)
您的图像现在处于阵列palettised并存储在每个像素位置是您的调色板中最接近的颜色的索引 - 所以,当您的调色板有4个条目(0..3),所有图像的元素是0,1,2或3。
所以,现在您可以将85乘以:
result = palettised * 85