OpenCV 图像的平均颜色

Ammar Ali 2024年2月15日
  1. 在 Python 中使用 NumPy 的 average() 函数查找图像的平均颜色
  2. 在 Python 中使用 sklearnKMeans() 函数查找图像中的主色
OpenCV 图像的平均颜色

本教程将讨论在 Python 中使用 NumPy 的 average() 函数查找图像的平均颜色。

在 Python 中使用 NumPy 的 average() 函数查找图像的平均颜色

在数学中,我们可以通过将向量中所有元素的总和除以元素总数来找到向量的平均值。图像由像素组成,每个像素具有由 RGB 三元组值定义的特定颜色。

要找到图像中的平均颜色,我们必须取所有 RGB 三元组值的平均值。我们可以使用 imread() 函数读取图像并将其存储在矩阵中。

我们可以使用 NumPy 的 average() 函数来找到图像矩阵的平均值并使用 print 函数显示它。

我们还可以使用 NumPy 的 ones() 函数创建黑色图像,然后将平均颜色放入该图像中,并使用 OpenCV 的 imshow() 函数显示它。

请参阅下面的代码。

import cv2
import numpy as np

src_img = cv2.imread("fruit.jpg")
average_color_row = np.average(src_img, axis=0)
average_color = np.average(average_color_row, axis=0)
print(average_color)

d_img = np.ones((312, 312, 3), dtype=np.uint8)
d_img[:, :] = average_color

cv2.imshow("Source image", src_img)
cv2.imshow("Average Color", d_img)
cv2.waitKey(0)

输出:

[ 66.37342135 132.52483748 176.58277285]

使用 numpy 的平均颜色

RGB 三元组值保存在 average_color 变量中,它也与源图像一起显示。average() 函数中的第一个参数是源图像。

第二个参数指定平均发生的方向。在上面的代码中,axis=0 取图像矩阵中的平均行数。

average() 函数在上面的代码中使用了两次。我们第一次使用它来取所有行的平均值。

然后我们再次使用它来获取第一个 average() 函数的平均输出,因为矩阵是二维的,而 average() 函数仅适用于一维。

在 Python 中使用 sklearnKMeans() 函数查找图像中的主色

除了寻找单一的平均颜色,我们还可以使用 k_mean 聚类算法在图像中找到最主要的颜色。

例如,要在图像中找到五种主色,我们可以使用 sklearn 库的 KMeans() 函数在给定图像中创建五个颜色簇。

此函数根据最近邻原理工作,其中与像素最近的值将被放置在该像素的簇中,依此类推。

例如,如果一个簇包含黑色,则黑色附近的其他颜色也将放置在该簇内,依此类推。然后我们可以使用聚类的直方图找到每个聚类中哪种颜色占主导地位。

我们可以使用 OpenCV 的 rectangle() 函数显示主色。我们还将显示主色的百分比。

请参阅下面的代码。

import cv2
import numpy as np
from sklearn.cluster import KMeans


def visualize_Dominant_colors(cluster, C_centroids):
    C_labels = np.arange(0, len(np.unique(cluster.labels_)) + 1)
    (C_hist, _) = np.histogram(cluster.labels_, bins=C_labels)
    C_hist = C_hist.astype("float")
    C_hist /= C_hist.sum()

    rect_color = np.zeros((50, 300, 3), dtype=np.uint8)
    img_colors = sorted(
        [(percent, color) for (percent, color) in zip(C_hist, C_centroids)]
    )
    start = 0
    for (percent, color) in img_colors:
        print(color, "{:0.2f}%".format(percent * 100))
        end = start + (percent * 300)
        cv2.rectangle(
            rect_color,
            (int(start), 0),
            (int(end), 50),
            color.astype("uint8").tolist(),
            -1,
        )
        start = end
    return rect_color


# Load image
src_image = cv2.imread("fruit.jpg")
src_image = cv2.cvtColor(src_image, cv2.COLOR_BGR2RGB)
reshape_img = src_image.reshape((src_image.shape[0] * src_image.shape[1], 3))

# Display dominant colors Present in the image
KM_cluster = KMeans(n_clusters=5).fit(reshape_img)
visualize_color = visualize_Dominant_colors(KM_cluster, KM_cluster.cluster_centers_)
visualize_color = cv2.cvtColor(visualize_color, cv2.COLOR_RGB2BGR)
cv2.imshow("visualize_Color", visualize_color)
cv2.waitKey()

输出:

[250.02183207 247.76400891 234.31283544] 10.79%
[229.50988728 214.10649735 107.32981816] 17.88%
[191.01593309  56.83353011  24.6890951 ] 22.11%
[75.10083377 57.61393153 30.72486672] 24.38%
[193.66472128 165.29669679  36.39122105] 24.84%

使用 kmeans 的颜色

如图所示,RGB 三元组值以及主色百分比显示在输出中。OpenCV 读取 BRG 颜色空间中的图像,这就是我们使用 OpenCV 的 cvtColor() 函数将图像转换为 RGB 的原因。

上面代码中的 zeros() 函数用于创建空白图像,然后我们使用 rectangle() 函数根据其在空白图像顶部的百分比创建主色矩形。

在上面的代码中,簇数的值设置为 5,但是我们可以使用任意数量的簇。

如果我们使用 10 个集群,代码将返回主色,但代码将花费比 5 个集群更多的时间。我们还可以在 KMeans() 函数中设置许多其他参数,例如使用默认设置为 300 的 max_iter 参数的最大迭代次数。

我们还可以使用默认设置为 0.0001 的 tol 参数和用于查找集群的算法默认设置为自动设置容差。查看此链接以获取有关 KMeans() 函数的更多详细信息。

rectangle() 函数的第一个参数是我们要在其上绘制颜色框的图像。第二个参数是起始位置,它将设置矩形的起始点。

第三个参数是矩形的结束位置。第四个参数以 BGR 三元组格式定义矩形的颜色,第五个参数是矩形的线条粗细。

如果线宽设置为-1,矩形将被颜色填充。

作者: Ammar Ali
Ammar Ali avatar Ammar Ali avatar

Hello! I am Ammar Ali, a programmer here to learn from experience, people, and docs, and create interesting and useful programming content. I mostly create content about Python, Matlab, and Microcontrollers like Arduino and PIC.

LinkedIn Facebook

相关文章 - OpenCV Image