2017-04-02 204 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() 

我希望它有帮助,对我很好。