使用Python尋找圖像最常見的顏色

2021-01-12 人工智慧遇見磐創

如果我們知道圖像或對象最常見的是哪種顏色,那麼可以解決圖像處理中的幾個用例,例如在農業領域,我們可能需要確定水果的成熟度。我們可以簡單地檢查一下水果的顏色是否在預定的範圍內,看看它是成熟的,腐爛的,還是未成熟的。

與往常一樣,我們可以使用Python和簡單但功能強大的庫(如Numpy、Matplotlib和OpenCV)來解決這個問題。我將演示如何使用這些軟體包在圖像中找到最常見的顏色的幾種方法。

步驟1-加載包

import cv2 as cvimport numpy as npimport matplotlib.pyplot as pltimport PIL%matplotlib inline在這裡加載基本包,後續會繼續加載更多的包。另外,由於我們是用Jupyter編程的,所以不要忘了包含%matplotlib內聯命令。

步驟2-加載並顯示示例圖像

在本教程中,我們將展示兩個並排的圖像。所以,讓我們用一個helper函數來實現。

def show_img_compar(img_1, img_2 ): f, ax = plt.subplots(1, 2, figsize=(10,10)) ax[0].imshow(img_1) ax[1].imshow(img_2) ax[0].axis('off') # 隱藏軸 ax[1].axis('off') f.tight_layout() plt.show()接下來,我們將加載一些在本教程中使用的示例圖像,並使用上面的函數演示它們。

img = cv.imread("img/img_1.jpg")img = cv.cvtColor(img, cv.COLOR_BGR2RGB)img_2 = cv.imread("img/img_2.jpg")img_2 = cv.cvtColor(img_2, cv.COLOR_BGR2RGB)dim = (500, 300)# 圖像大小自定義img = cv.resize(img, dim, interpolation = cv.INTER_AREA)img_2 = cv.resize(img_2, dim, interpolation = cv.INTER_AREA)show_img_compar(img, img_2)

現在我們準備好了。接下來要找出這些圖像中最常見的顏色了。

方法1-平均值

第一種方法是最簡單的(但無效的),找到平均像素值。

img_temp = img.copy()img_temp[:,:,0], img_temp[:,:,1], img_temp[:,:,2] = np.average(img, axis=(0,1))img_temp_2 = img_2.copy()img_temp_2[:,:,0], img_temp_2[:,:,1], img_temp_2[:,:,2] = np.average(img_2, axis=(0,1))show_img_compar(img, img_temp)show_img_compar(img_2, img_temp_2)使用numpy的average函數,我們可以很容易地得到行和寬度軸的平均像素值axis=(0,1)。

我們可以看出,平均法可以給出誤導或不準確的結果,因為它給出的最常見的顏色與實際偏離,這是因為平均值結合了所有像素值。當我們有高對比度的圖像(在一個圖像中「光」和「暗」),如在第二幅圖中,這個問題更明顯。

它給了我們一種在圖像中不明顯的新顏色。

方法2-最高像素頻率

第二種方法要比第一種方法精確一些,我們只需計算每個像素值中出現的次數。

幸運的是,numpy給了我們另一個函數,這個函數給出了精確的結果。但首先,我們必須重塑圖像數據結構,使其僅給出3個值的列表(每個R、G和B通道強度各一個)。

可以簡單地使用numpy的reshape函數來獲得像素值的列表。

現在我們有了正確結構的數據,我們可以開始計算像素值的頻率。只需使用numpy的unique函數,參數return_counts=True。

完成了,接下來在圖像上運行。

img_temp = img.copy()unique, counts = np.unique(img_temp.reshape(-1, 3), axis=0, return_counts=True)img_temp[:,:,0], img_temp[:,:,1], img_temp[:,:,2] = unique[np.argmax(counts)]img_temp_2 = img_2.copy()unique, counts = np.unique(img_temp_2.reshape(-1, 3), axis=0, return_counts=True)img_temp_2[:,:,0], img_temp_2[:,:,1], img_temp_2[:,:,2] = unique[np.argmax(counts)]show_img_compar(img, img_temp)show_img_compar(img_2, img_temp_2)

這比第一個更有意義,對吧?最常見的顏色是黑色區域。但我們可以更進一步,如果不只取一種最常見的顏色,而是多取一種呢?用同樣的方法,我們可以選擇前N種最常見的顏色。但是如果你看第一張圖片,頻率最高的許多顏色很可能是相鄰的顏色,可能只有幾個像素的差別。

換言之,我們要取最常見的,不同顏色的簇。

方法3-使用K均值聚類

我們使用Scikit-Learn來實現。我們可以使用K-Means聚類將顏色組聚集在一起。

現在,我們只需要一個函數來顯示上面的顏色簇並立即顯示出來。

def palette(clusters): width=300 palette = np.zeros((50, width, 3), np.uint8) steps = width/clusters.cluster_centers_.shape[0] for idx, centers in enumerate(clusters.cluster_centers_): palette[:, int(idx*steps):(int((idx+1)*steps)), :] = centers return paletteclt_1 = clt.fit(img.reshape(-1, 3))show_img_compar(img, palette(clt_1))clt_2 = clt.fit(img_2.reshape(-1, 3))show_img_compar(img_2, palette(clt_2))我們只需創建一個高度為50、寬度為300像素的圖像來顯示顏色組/調色板。對於每個顏色簇,將其指定給調色板。

K-Means聚類在檢測圖像中最常見的顏色方面給出了很好的結果。在第二張圖中,我們可以看到調色板中有太多的棕色陰影。這很可能是因為我們選擇了太多的簇。讓我們看看是否可以通過選擇較小的k值來修復它。

def palette(clusters): width=300 palette = np.zeros((50, width, 3), np.uint8) steps = width/clusters.cluster_centers_.shape[0] for idx, centers in enumerate(clusters.cluster_centers_): palette[:, int(idx*steps):(int((idx+1)*steps)), :] = centers return paletteclt_3 = KMeans(n_clusters=3)clt_3.fit(img_2.reshape(-1, 3))show_img_compar(img_2, palette(clt_3))

是的,解決了。

由於我們使用K-Means聚類,仍然需要自己確定適當的k。3似乎是個不錯的選擇。

但我們仍然可以在這些結果的基礎上改進。我們也展示一下這些簇在整個圖像中所佔的比例如何?

方法3.1-K均值+比例顯示

我們需要做的就是修改調色板函數。我們不使用固定的步長,而是將每個簇的寬度更改為與該簇中的像素數成比例。

from collections import Counterdef palette_perc(k_cluster): width = 300 palette = np.zeros((50, width, 3), np.uint8) n_pixels = len(k_cluster.labels_) counter = Counter(k_cluster.labels_) # 計算每個簇有多少像素 perc = {} for i in counter: perc[i] = np.round(counter[i]/n_pixels, 2) perc = dict(sorted(perc.items())) # 用於日誌記錄 print(perc) print(k_cluster.cluster_centers_) step = 0 for idx, centers in enumerate(k_cluster.cluster_centers_): palette[:, step:int(step + perc[idx]*width+1), :] = centers step += int(perc[idx]*width+1) return paletteclt_1 = clt.fit(img.reshape(-1, 3))show_img_compar(img, palette_perc(clt_1))clt_2 = clt.fit(img_2.reshape(-1, 3))show_img_compar(img_2, palette_perc(clt_2))

這樣好多了,它不僅給了我們圖像中最常見的顏色。它還提供了每個像素出現的比例。

它也有助於告訴我們應該使用多少個簇。在上面的圖像中,兩到四個簇似乎是合理的。在第二張圖像中,我們至少需要兩個簇。不使用一個簇(k=4)的原因是可能會遇到與平均方法相同的問題。

結論

我們介紹了使用Python和一些著名的庫來獲取圖像中最常見顏色的幾種技術。另外,我們也看到了這些技術的優缺點。到目前為止,使用K>1的K-Means找到最常見的顏色是在圖像中找到最常見顏色的最佳解決方案之一(至少與我們已經使用的其他方法相比)。

Github倉庫代碼:https://github.com/mrakelinggar/data-stuffs/tree/master/frequent_color。

相關焦點

  • 基於Python查找圖像中最常見的顏色
    來源:公眾號 小白學視覺 授權如果我們能夠得知道一幅圖像中最多的顏色是什麼的話,可以幫助我們解決很多實際問題。使用numpy的average功能,我們可以輕鬆獲得行和寬度上的平均像素值-axis=(0,1)img_temp = img.copy()img_temp[:,:,0], img_temp[:,:,1], img_temp[:,:,2] = np.average(img, axis=(0,1))img_temp_2 = img_2.
  • opencv-python圖像預處理-濾波
    為了消除外界環境對圖像採集的幹擾,增強圖像的邊緣及灰度跳變的部分,使圖像變得清晰以及提高圖像處理速度需要對圖像進行預處理操作,主要是對圖像進行濾波和增強操作。使用的方法可以分為空間域處理和頻率域處理兩類。空間域指圖像平面本身,這類圖像處理方法用各種模板直接與圖像進行卷積運算,實現對圖像的處理。
  • 使用Python調整圖像大小
    可以說,每一個「使用計算機的人」都需要在某個時間點調整圖像的大小。MacOS的預覽版可以做到,WindowsPowerToys也可以。本文使用Python來調整圖像大小,幸運的是,圖像處理和命令行工具是Python的兩個特長。
  • 常用的十大 python 圖像處理工具
    但無論是用於何種用途,這些圖像都需要進行處理。圖像處理就是分析和處理數字圖像的過程,主要旨在提高其質量或從中提取一些信息,然後可以將其用於某種用途。圖像處理中的常見任務包括顯示圖像,基本操作如裁剪、翻轉、旋轉等,圖像分割,分類和特徵提取,圖像恢復和圖像識別。
  • Python十大工具,讓圖像簡潔直觀有魅力!
    但圖像無論有何用途,都要經過處理。因此,圖像處理就是對數字圖像進行分析、操作的過程,其主要目的是為改善圖像質量或從中提取一些有用信息。圖像處理的常見任務包括圖像顯示、圖像基本操作(裁剪、翻轉、旋轉等)、圖像分割、分類及特徵提取、圖像修復和圖像識別。
  • 教程:使用Python進行基本圖像數據分析!
    矢量圖形是一種有點不同的存儲圖像方法,旨在避免與像素相關的問題。但是,即使是矢量圖像,最終也會顯示為像素一樣的馬賽克。顏色像素表示圖像元素,描述每個像素的簡單方法是使用三種顏色的組合,即紅色,綠色,藍色,這就是我們所說的RGB圖像。  在RGB圖像中,每個像素分別與紅色,綠色,藍色的值相關聯的三個8比特數字表示。
  • ImagePy——UI界面支持開放插件的Python開源圖像處理框架
    在 github:https://github.com/Image-Py/imagepy 上,不僅有關於這款圖像處理軟體的詳細介紹,還有一些使用示例,雷鋒網 AI 科技評論接下來將詳細介紹這一開源圖像處理框架。
  • python圖像處理-gif動圖
    動圖分解成一張張圖片先使用open方法打開動圖,接著使用ImageSequence將打開的圖片對象轉換成可迭代的圖片序列,通過for循環將圖片一張張保存到本地,名字可以自定義。python圖像處理-1python圖像處理-批量生成純色圖片
  • 使用一行Python代碼從圖像讀取文本
    雖然圖像分類和涉及到一定程度計算機視覺的任務可能需要大量的代碼和紮實的理解,但是從格式良好的圖像中讀取文本在Python中卻是簡單的,並且可以應用於許多現實生活中的問題。在今天的帖子中,我想證明這一點。雖然會安裝一些庫,但不會花很多時間。
  • 使用Python玩轉高等數學(5):三角函數
    從三角函數開始,我們使用matplotlib繪製函數圖像,matplotlib是圖形繪製庫,使用matplotlib可以方便的繪製函數圖形,以及直方圖
  • python人工智慧-圖像識別
    PIL:(Python Imaging Library)是Python平臺上的圖像處理標準庫,功能非常強大。pytesseract:圖像識別庫。我這裡使用的是python3.6,PIL不支持python3所以使用如下命令pip install pytesseractpip install pillow如果是python2,則在命令行執行如下命令:pip install pytesseractpip install PIL這時候我們去運行上面的代碼會發現如下錯誤
  • python|圖像識別
    影響力之大和最吸引人的技術就是圖像識別,圖像識別技術是人工智慧的一個重要領域,它是指利用計算機對圖像進行處理、分析和理解,以識別各種不同模式的目標和對象的技術。今天以女神宋慧喬的兩張不同照片為例,利用python識別其相似度,從而判定是否是同一人,同時讓我們對圖像識別有個初步的了解,什麼?照片可以換蒼老師和波老師嗎?我懷疑你們在開車,可是我沒有證據!
  • opencv-python獲取圖像:面向對象與面向過程
    Lena圖像在科研領域流行的原因:1.該圖適度的混合了細節、平滑區域、陰影和紋理,從而能很好的測試各種圖像處理算法。2.Lenna是個美女,對於圖像處理界的研究者(大部分都是男性)來說,美女圖可以有效地吸引他們來做研究。
  • python sys模塊的常見用法匯總
    python的內置模塊sys,提供了系統相關的一些變量和函數,在實際開發中,常見的有以下幾種用法1.> sys.platform'linux2'經典的使用場景版本有限制的代碼,可以通過以上方法來判斷python版本是否符合要求。
  • 使用Python和Tesseract來識別圖形驗證碼
    Tesseract的OCR引擎最早是HP實驗室開發的,曾經是 OCR業內最準確的三款識別引擎之一。2005年該引擎交給了Google,作為開源項目發布在Google Project上了。Tesseract提供獨立程序和API兩種形式供用戶使用。純白色背景、字符規整無幹擾像素的驗證碼圖片可以直接調用tesseract程序來進行識別。
  • 使用OpenCV和Python構建自己的車輛檢測模型
    我們可以使用目標檢測算法來執行超級有用的高價值任務,如監視、交通管理、打擊犯罪等。下面的GIF圖演示了這個想法:在目標檢測中,我們可以執行許多子任務,例如計算目標數量、查找目標的相對大小或查找目標之間的相對距離。這些子任務都很重要,因為它們有助於解決一些最棘手的現實問題。
  • 使用Python+OpenCV進行圖像處理(二)
    整個視覺入門系列內容如下:理解顏色模型與在圖像上繪製圖形(圖像處理基本操作)。基本的圖像處理與濾波技術。從特徵檢測到人臉檢測。圖像分割與分水嶺(Watershed)算法(TBU)在邊緣和輪廓檢測中,噪聲對檢測的精度有很大的影響。
  • 三種用Python從圖像數據中提取特徵的技術
    全文共4073字,預計學習時長8分鐘你之前是否使用過圖像數據?也許你想建立自己的物體檢測模型,或者僅僅是想統計走進某棟建築物的人數,使用計算機視覺技術處理圖像擁有無窮無盡的可能性。彩色圖像通常由多種顏色組成,幾乎所有顏色都可以從三原色(紅色,綠色和藍色)生成。因此,如果是彩色圖像,則要用到三個矩陣(或通道)——紅、綠、藍。每個矩陣值介於0到255之間,表示該像素的顏色強度。
  • mac使用python識別圖形驗證碼!
    在網上查了很多版本的圖形驗證碼識別,目前看到最多的兩個模塊是pytesseract和tesserocr,但是因為我這裡安裝tesserocr的時候各種出錯,所以最終我鎖定了使用pytesseract。那麼接下來,就記錄下安裝以及使用過程。這裡的系統環境是mac os 10.14.
  • 使用Python OpenCV處理圖像之使用OpenCV獲取並修改圖像的像素值
    使用Python OpenCV處理圖像之圖像文件的打開、顯示和保存操作,我們還使用OpenCV更改了微信頭像使用Python OpenCV處理圖像之詳解使用OpenCV處理鍵盤滑鼠事件。灰度圖片使用類似,不再贅述,只是圖像屬性參數不一樣。怎麼樣?是不是很簡單?有沒有更好的解決方案?