2017-04-02 7 views
1

Ich bin Anfänger in Python und Bildverarbeitung. Ich möchte den Prozentsatz der braunen Farbe von einem Bild mit Histogramm-Funktion finden.Farbprozentsatz in Bild Python opencv mit Histogramm

Ich tat die Histogrammfunktion, aber ich weiß nicht, wie man den Prozentsatz der braunen Farbe im Bild findet.

das ist mein Python-Code

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() 

das Bild, das ich

the image that I use

Ich habe diese Ausgabe des Code verwenden enter image description here

+0

Möchten Sie dies strikt mit Histogramm erreichen? – ZdaR

+0

Technisch verwendete ich den Histogrammansatz in meiner Antwort, indem ich über die Farbkanäle integriere und die Teilmenge der Integrale nehme, die der gewünschten Farbe entsprechen. Ich stimme Ihnen jedoch zu, dass die Frage diesbezüglich offen ist. Raten Sie, es ist Zeit für den Autor zu antworten. – mmensing

Antwort

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) 

Diese für Arbeit sollte Sie. Beachten Sie jedoch, dass dies in hohem Maße von Ihrem RGB-Wert für Braun sowie von Ihrer gewünschten Toleranz abhängt (diff).

Wenn Sie weitere Fragen zu den Details des obigen Codes haben, zögern Sie nicht zu fragen.

+0

erstaunlich, vielen Dank es funktioniert mit mir. aber der Prozentsatz ist immer 0? Was auch immer das Bild –

+1

Sie hatten Recht, dass der Prozentsatz hatte ein Problem - für Farbbilder img.size ergibt offenbar die Anzahl der Pixel mal die Anzahl der Kanäle - so fügte ich '/ 3' zu der Antwort und testete den Prozentsatz mit einem Test Bild, das halb braun war. Für das obige Bild liefert der Code 9,78% 'braune' Pixel. Beachten Sie jedoch, dass die Ergebnisse immer noch stark von Ihrer Definition von "braun" und Ihrer Toleranz (diff) abhängen. Wenn Sie lieber nach "dunkleren" als "helleren" Bereichen suchen, legen Sie ggf. separate Toleranzen für die untere und obere Grenze fest. – mmensing

+0

leider immer noch 0 Prozent :( –

0

Ich brauchte die gleichen Ergebnisse, also habe ich Ihren Code verwendet und Prozentsätze berechnet.

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() 

Ich hoffe, es hilft, hat gut für mich gearbeitet.