使用OpenCV Python進行影像顏色量化?


顏色量化過程中,影像中使用的顏色數量會減少。這樣做的一個原因是為了減少記憶體佔用。有時,某些裝置只能產生有限數量的顏色。在這些情況下,會執行顏色量化。我們使用cv2.kmeans()來應用k均值聚類進行顏色量化。

步驟

要使用K均值聚類在影像中實現顏色量化,您可以按照以下步驟操作:

  • 匯入所需的庫OpenCVNumPy。確保您已經安裝了它們。

  • 使用cv2.imread()方法讀取兩個輸入影像。指定影像的完整路徑。將影像重新整形為Mx3大小的陣列(M是影像中畫素的總數)。將影像dtype轉換為np.float32

  • 定義迭代終止條件(criteria)、簇的數量(K)並應用K均值聚類演算法(cv2.kmeans())。傳遞標誌cv2.KMEANS_RANDOM_CENTERS或cv.KMEANS_PP_CENTERS以指定如何獲取初始中心。

  • 現在轉換回uint8,並透過將質心值應用於所有畫素來建立具有指定顏色數量(K)的結果影像。

  • 顯示結果影像。

讓我們來看一些使用K均值聚類在影像中實現顏色量化的示例。

輸入影像

我們將在下面的示例中使用此影像作為輸入檔案。


示例

在下面的Python程式碼中,我們使用K均值聚類演算法(K=8)對輸入影像進行顏色量化。

# import required libraries import numpy as np import cv2 # read input image img = cv2.imread('horizon.jpg') z = img.reshape((-1,3)) # convert to np.float32 z = np.float32(z) # define criteria, number of clusters(K) and apply kmeans() criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0) K = 8 ret,label,center=cv2.kmeans(z,K,None,criteria,10,cv2.KMEANS_RANDOM_CENTERS) # Convert back into uint8, and make original image center = np.uint8(center) res = center[label.flatten()] res2 = res.reshape((img.shape)) # display the image cv2.imshow('Image with K=8',res2) cv2.waitKey(0) cv2.destroyAllWindows()

輸出

執行上面的Python程式後,它將生成以下輸出視窗:


請注意,在上面的輸出影像中,使用的顏色數量減少到8,因為我們使用了K=8。

示例

在下面的Python程式碼中,我們使用K均值聚類演算法和不同的K值(K=2,K=5和K=8)對輸入影像進行顏色量化。

# import required libraries import numpy as np import cv2 import matplotlib.pyplot as plt # read input image img = cv2.imread('horizon.jpg') Z = img.reshape((-1,3)) # convert to np.float32 Z = np.float32(Z) # define criteria, number of clusters(K) and apply kmeans() criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0) def colorQuant(Z, K, criteria): ret,label,center=cv2.kmeans(Z,K,None,criteria,10,cv2.KMEANS_RANDOM_CENTERS) # Now convert back into uint8, and make original image center = np.uint8(center) res = center[label.flatten()] res2 = res.reshape((img.shape)) return res2 res1 = colorQuant(Z, 2, criteria) res2 = colorQuant(Z, 5, criteria) res3 = colorQuant(Z, 8, criteria) plt.subplot(221),plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB)) plt.title('Original Image'), plt.xticks([]), plt.yticks([]) plt.subplot(222),plt.imshow(cv2.cvtColor(res1, cv2.COLOR_BGR2RGB)) plt.title('K=2'), plt.xticks([]), plt.yticks([]) plt.subplot(223),plt.imshow(cv2.cvtColor(res2, cv2.COLOR_BGR2RGB)) plt.title('K=4'), plt.xticks([]), plt.yticks([]) plt.subplot(224),plt.imshow(cv2.cvtColor(res3, cv2.COLOR_BGR2RGB)) plt.title('K=8'), plt.xticks([]), plt.yticks([]) plt.show()

輸出

執行上述程式碼後,將產生以下輸出


請注意不同輸出影像中存在的顏色差異。較高的K值更接近原始影像。

更新於:2022年12月5日

3K+ 次檢視

啟動您的職業生涯

透過完成課程獲得認證

開始學習
廣告
© . All rights reserved.