Python OpenCV中使用直方图计算图像颜色百分比

6

我是Python和图像处理的初学者。我想使用直方图函数找到图像中棕色颜色的百分比。

我已经实现了直方图函数,但我不知道如何找到图像中棕色颜色的百分比。

这是我的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()

我使用的图片

我使用的图片

我有代码的输出结果 输入图像描述

你想严格通过直方图来完成这个任务吗? - ZdaR
从技术上讲,我在我的答案中使用了直方图方法,通过对颜色通道进行积分并取出与所需颜色相对应的积分子集来实现。尽管如此,我同意您在这方面的看法是有待商榷的。猜想现在是作者回应的时候了。 - mmensing
2个回答

7
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?无论图片如何。 - Majazen ـG
1
你是正确的,百分比有问题 - 对于彩色图像,img.size 显然会产生像素数乘以通道数 - 所以我在答案中添加了 '/3' 并使用一张一半棕色的测试图像测试了百分比。对于上面提供的图像,代码给出了 9.78% 的 '棕色' 像素。尽管如此,请记住结果仍然强烈依赖于您对 '棕色' 的定义和您的容差(diff)。此外,如果您更愿意检查 '较暗' vs '较亮' 区域,也许可以为下限和上限设置单独的容差。 - mmensing
不幸的是,仍然显示0% :( - Majazen ـG
我使用Python 3.5、NumPy 1.12和OpenCV 3.1完成了它 - 你能用这些版本检查一下吗? - mmensing
实际上我需要它的2.7.3版本,您能帮我吗?谢谢。 - Majazen ـG
显示剩余2条评论

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

希望它能有所帮助,对我来说效果很好。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接