gpt4 book ai didi

python - 如何在 OpenCV 中创建自定义调色板的颜色直方图?

转载 作者:太空宇宙 更新时间:2023-11-03 22:56:37 25 4
gpt4 key购买 nike

我有一张图片:

enter image description here

并且图像中的颜色范围通过这些 RGB 值作为线性插值生成:

rgb = [165,0,38], w = 0.0
rgb = [222,63,46], w = 0.125
rgb = [248,142,82], w = 0.25
rgb = [253,212,129], ...
rgb = [254,254,189]
rgb = [203,232,129]
rgb = [132,202,102]
rgb = [42,159,84]
rgb = [0,104,55], w = 1.0

如何创建一个图形/直方图,其中 x 轴是颜色范围,值是具有该像素颜色的图像的百分比。

最佳答案

这是我将如何解决此问题的蛮力尝试。请注意,我正在寻找 RGB 空间中的颜色距离,但众所周知,RGB 中的颜色距离并不能很好地模拟人类对颜色的感知......但这是让你开始的东西。请注意,您需要 numpy matplotlib 安装。 matplotlib是允许将直方图绘制为茎图。

基本上,您定义的那些 RGB 值我们可以认为是 关键点 .从这里开始,我们需要定义直方图中需要计算的 bin 总数。我将其设置为 64 开始。您首先需要做的是为您定义的那些值插入红色、绿色和蓝色值,以便我们可以创建一个 RGB 查找表。因此,我们需要使用您定义的那些关键点生成从开始 RGB 元组到结束 RGB 元组的 64 个 RGB 值,我们将对这些 RGB 值进行线性插值。

此 RGB 查找表将是一个 64 x 3 数组,基本算法是从图像中提取 RGB 像素并确定 最近的像素从这个像素到查找表。我们找到产生最小距离的这个索引,我们将增加直方图中相应的 bin。我通过欧几里得距离的平方来计算。取平方根来获得欧几里得距离是没有意义的,因为我们想要找到最小距离。每个术语的平方根不会改变哪个像素颜色最接近查找表中的哪个条目。我们将对图像中的其余像素重复此操作。

要计算最小距离,请使用 numpy.sum 以及通过 broadcasting 减去查找表中每个位置在输入图像中获得的每个像素.我们对每个距离求平方,将它们相加,然后在查找表中确定为我们提供最小值的位置 numpy.argmin .

现在,为了创建插值 RGB 查找,我调用了 numpy.interp 在红色、绿色和蓝色 channel 关键点上,输出 ( y ) 值来自您定义的红色、绿色和蓝色值的关键点值,输入 ( x ) 值是 假人 输入值从 0 线性增加到我们减去 1 的控制点。所以我们的输入 x关键点是:

[0, 1, 2, 3, ..., N-1]
N是关键点的总数,输出关键点分别是红色、绿色和蓝色的关键点值。为了创建 64 个值的查找,我们需要在 0 之间创建 64 个点。至 N-1 ,我们可以通过 numpy.linspace 来实现.

现在,OpenCV 的一个复杂之处在于以 BGR 格式读取图像。因此,我 翻转 channel 使它们是 RGB,我还将图像转换为 float32这样我们就可以在计算距离时保持精度。另外,一旦我计算出直方图,因为你想要 百分比 ,我将直方图转换为百分比,方法是除以直方图中的值总数(即图像中的像素数),然后乘以 100% 以得到百分比。

事不宜迟,这是我的代码尝试。你的图片看起来像麦田,所以我把你的图片命名为 wheat.png ,但将其重命名为您的图像名称:
import numpy as np # Import relevant libraries
import cv2
import matplotlib.pyplot as plt

# Read in image
img = cv2.imread('wheat.png')

# Flip the channels as the image is in BGR and cast to float
img = img[:,:,::-1].astype('float32')

# control points for RGB - defined by you
rgb_lookup = np.array([[165,0,38], [222,63,46], [248,142,82],
[253,212,129], [254,254,189], [203,232,129],
[132,202,102], [42,159,84], [0,104,55]])

# Define number of bins for histogram
num_bins = 64

# Define dummy x keypoint values
x_keypt = np.arange(rgb_lookup.shape[0])

# Define interpolating x values
xp = np.linspace(x_keypt[0], x_keypt[-1], num_bins)

# Define lookup tables for red, green and blue
red_lookup = np.interp(xp, x_keypt, rgb_lookup[:,0])
green_lookup = np.interp(xp, x_keypt, rgb_lookup[:,1])
blue_lookup = np.interp(xp, x_keypt, rgb_lookup[:,2])

# Define final RGB lookup
rgb_final_lookup = np.column_stack([red_lookup, green_lookup, blue_lookup])

# Brute force
# For each pixel we have in our image, find the closest RGB distance
# from this pixel to each pixel in our lookup. Find the argmin,
# then log into histogram accordingly
hist = np.zeros(num_bins)

# Get the rows and columns of the image
rows = img.shape[0]
cols = img.shape[1]

# For each pixel
for i in np.arange(rows):
for j in np.arange(cols):
# Get colour pixel value
val = img[i,j,:]

# Find closest distance to lookup
dists = np.sum((rgb_final_lookup - val)**2.0, axis=1)

# Get location for histogram
ind = np.argmin(dists)

# Increment histogram
hist[ind] += 1

# Get percentage calculation
hist = 100*hist / (rows*cols)

# Plot histogram
plt.stem(np.arange(num_bins), hist)
plt.title('Histogram of colours')
plt.xlabel('Bin number')
plt.ylabel('Percentage')
plt.show()

我们得到的图表是:

enter image description here

上图很有道理。在您的色谱开始处,有很多红色和淡黄色像素,它们在您的色谱开始附近定义。绿色和白色像素更接近末端,不包含大部分像素。您需要调整垃圾箱的数量才能使其符合您的口味。

祝你好运!

关于python - 如何在 OpenCV 中创建自定义调色板的颜色直方图?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28994420/

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