2017-04-02 560 views
1

我是初學者在Python和圖像處理。我想使用直方圖函數從圖像中找到棕色的百分比。顏色比例在圖像python opencv使用直方圖

我做了直方圖函數,但我不知道如何找到圖像中棕色的百分比。

這是我的Python代碼

import cv2 
import numpy as np 
from matplotlib import pyplot as plt 

img = cv2.imread('C:\Users\MainUser\Desktop\histogram\dates.jpg', -1) 
cv2.imshow('GoldenGate',img) 

color = ('b','g','r') 
for channel,col in enumerate(color): 
    histr = cv2.calcHist([img],[channel],None,[256],[0,256]) 
    plt.plot(histr,color = col) 
    plt.xlim([0,256]) 
plt.title('Histogram for color scale picture') 
plt.show() 

while True: 
    k = cv2.waitKey(0) & 0xFF  
    if k == 27: break    # ESC key to exit 
cv2.destroyAllWindows() 

,我使用的圖像

the image that I use

我的代碼 enter image description here

+0

你想嚴格使用直方圖來完成嗎? – ZdaR

+0

技術上我通過在顏色通道整合,並相應採取對應所需顏色的積分的子集,用於我的回答直方圖方法。不過,我同意你的看法,在這方面,這個問題有待解釋。猜猜是作者回復的時候了。 – mmensing

回答

3
import numpy as np 
import cv2 

img = cv2.imread('J9MbW.jpg') 

brown = [145, 80, 40] # RGB 
diff = 20 
boundaries = [([brown[2]-diff, brown[1]-diff, brown[0]-diff], 
       [brown[2]+diff, brown[1]+diff, brown[0]+diff])] 
# in order BGR as opencv represents images as numpy arrays in reverse order 

for (lower, upper) in boundaries: 
    lower = np.array(lower, dtype=np.uint8) 
    upper = np.array(upper, dtype=np.uint8) 
    mask = cv2.inRange(img, lower, upper) 
    output = cv2.bitwise_and(img, img, mask=mask) 

    ratio_brown = cv2.countNonZero(mask)/(img.size/3) 
    print('brown pixel percentage:', np.round(ratio_brown*100, 2)) 

    cv2.imshow("images", np.hstack([img, output])) 
    cv2.waitKey(0) 

這應該工作的這個輸出您。但是,請注意,這是高度依賴於棕色的RGB值以及所需的公差(diff)。

如果您對上述代碼的詳細信息有進一步的問題,請隨時詢問。

+0

驚人的,非常感謝它與我。但百分比總是0?無論圖片 –

+1

你是對的,百分比有問題 - 對於彩色圖像img.size顯然產生的像素數乘以通道數 - 所以我給答案加了'/ 3',並用測試測試了百分比圖像是一半棕色。對於上面提供的圖像,代碼產生9.78%'棕色'像素。然而,回顧,結果還是在很大程度上取決於你的「棕」和你的寬容(差異)的定義。此外,如果你寧願檢查「暗」 VS「亮」的區域,也許對於下限和上限分別設置公差。 – mmensing

+0

不幸的是仍然出現0百分比:( –

0

我需要相同的結果,所以我使用你的代碼並計算百分比。

import cv2 
import numpy as np 
from matplotlib import pyplot as plt 
import operator 

img = cv2.imread('azul200.png', -1) 
cv2.imshow('Imagem:',img) 

color = ('b','g','r') 
qtdBlue = 0 
qtdGreen = 0 
qtdRed = 0 
totalPixels = 0 

for channel,col in enumerate(color): 
    histr = cv2.calcHist([img],[channel],None,[256],[1,256]) 
    plt.plot(histr,color = col) 
    plt.xlim([0,256]) 
    totalPixels+=sum(histr) 
    print histr 
    if channel==0: 
     qtdBlue = sum(histr) 
    elif channel==1: 
     qtdGreen = sum(histr) 
    elif channel==2: 
     qtdRed = sum(histr) 

qtdBlue = (qtdBlue/totalPixels)*100 
qtdGreen = (qtdGreen/totalPixels)*100 
qtdRed = (qtdRed/totalPixels)*100 

qtdBlue = filter(operator.isNumberType, qtdBlue) 
qtdGreen = filter(operator.isNumberType, qtdGreen) 
qtdRed = filter(operator.isNumberType, qtdRed) 

plt.title("Red: "+str(qtdRed)+"%; Green: "+str(qtdGreen)+"%; Blue: "+str(qtdBlue)+"%") 
plt.show() 

我希望它有幫助,對我很好。