OpenCV 影象的平均顏色

Ammar Ali 2023年1月30日 2022年5月17日
  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, 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,矩形將被顏色填充。

Author: 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