你的问题和假设存在一些问题。
使用np.unique(image)
无法计算颜色数量
使用np.unique(im)
无法计算图像中的颜色数量。让我们通过创建仅包含4个强度值(0、1、2和3)的随机图像来了解原因。
import numpy as np
import cv2
np.random.seed(42)
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)
现在,如果您尝试像这样获取唯一的颜色,它将不起作用,因为每种颜色都是三种强度的
组合:
np.unique(im)
如果你想要得到独特颜色的数量,你需要查找三个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))
所以,针对您的图片:
im = cv2.imread('image.png',cv2.IMREAD_UNCHANGED)
len(np.unique(im.reshape(-1, im.shape[2]), axis=0)
颜色比你想象的多
为什么我的颜色比想象中多?最常见的两个原因是:
- 图像被保存为JPEG格式
- 存在文本或绘制的形状进行了反锯齿处理
让我们看看如何将保存为JPEG格式会导致问题!
im = cv2.imread('image.png',cv2.IMREAD_UNCHANGED)
len(np.unique(im.reshape(-1, im.shape[2]), axis=0))
cv2.imwrite('temp.jpg',im)
im = cv2.imread('temp.jpg',cv2.IMREAD_UNCHANGED)
len(np.unique(im.reshape(-1, im.shape[2]), axis=0))
如何将图像进行调色板处理 - (减少颜色到固定的调色板)?
如果您想将图像调色板化为自己特定的调色板,首先需要按BGR顺序指定您的调色板(!
),以匹配OpenCV的排序:
palette = np.array([
[0,0,0],
[93,136,106],
[208,224,64],
[85,124,168]],
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
![enter image description here](https://istack.dev59.com/Z8uQO.webp)
gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
。 - Charles Parrnp.unique()
计算了灰度值的数量吗? - Mark Setchell