从图像到直方图测量颜色

时间:2017-03-08 19:31:38

标签: python opencv image-processing matplotlib

我正在尝试制作一种白色到黄色鳞片的色度计。

我会尝试更好地解释,但由于我是Python和图像处理的新手,如果我说错了,请纠正我。

我正在使用HSV颜色空间,因为我读到它可以更好地表示三个组件(色调,饱和度和值)中的颜色特征。假设我有一些白色阴影的图像,程序应该能够根据像素的色调,饱和度和图像的值来计算一个值,因为如果我提供的图像略带白色到黄色,它应该给出类似的值。

以下是image of sugar crystals的示例。当忽略紫色背景时,糖有白色和黄色的色调。

我的第一次尝试是计算几乎全白图像的直方图并将其用作参考,然后计算另一个图像的直方图并比较它们以检查它们是否相似。它的颜色越黄,应该越不相似,记住单个图像可以同时具有白色和黄色像素,甚至可以在色调直方图中具有一系列不同的黄色色调):

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

image = cv2.imread("C:\...\im1.png")
image2 = cv2.imread("C:\...\im2.png")

hsv_image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
hsv_image2 = cv2.cvtColor(image2, cv2.COLOR_BGR2HSV)

hue_hist = cv2.calcHist([hsv_image], [0], None, [180], [0, 180])
sat_hist = cv2.calcHist([hsv_image], [1], None, [256], [0, 256])
val_hist = cv2.calcHist([hsv_image], [2], None, [256], [0, 256])

hue_hist2 = cv2.calcHist([hsv_image2], [0], None, [180], [0, 180])
sat_hist2 = cv2.calcHist([hsv_image2], [1], None, [256], [0, 256])
val_hist2 = cv2.calcHist([hsv_image2], [2], None, [256], [0, 256])

dh = cv2.compareHist(hue_hist, hue_hist2, cv2.cv.CV_COMP_CORREL)
ds = cv2.compareHist(sat_hist, sat_hist2, cv2.cv.CV_COMP_CORREL)
dv = cv2.compareHist(val_hist, val_hist2, cv2.cv.CV_COMP_CORREL)

之后,我会得到这三个分开的值,表示直方图在色调,饱和度和值上的相似性, 然后我可以尝试一些数学建模,以便为dh,ds,dv的每个组合获得一些y得分值。

问题在于,如果比较黄色像素图像的色调直方图,相关性比较将表明它们完全不同,即使它们可以被解释为相似,因为白色到黄色的色调略有变化。我需要的东西不仅仅依赖于直方图上像素的频率,还需要接近色调值。

我认为另一个解决方案是计算直方图的加权平均值,所以也许我可以得到更接近的值 对于类似的分布甚至如果将图像与具有30色调的像素峰值和具有峰值的另一个图像进行比较 具有25色调的像素(它们彼此之间不会完全相同)。我还没试过这个。

你知道是否有更好的方法来达到这个目标,或者至少我是否正确地采用这种方式?

2 个答案:

答案 0 :(得分:2)

要获得图像的“黄色”,首先选择Hue。然后将其划分为扇区,切割为180-300-60(C-M-Y)。 60到180之间的任何东西都是黄色和青色的线性组合; 60到300之间的任何东西都是黄色和洋红色的线性组合。 160到300之间的任何值都将为黄色值0.将线性组合转换为0-100%黄色。调用此值y

要获得白色“白度”,请使用饱和度。 S = 0是100%白色,S = 30是70%白色。调用此值w

然后你可以做类似

的事情
yellowness = y / (y + w)
whiteness = w / (y + w)

答案 1 :(得分:1)

我不会使用HSV空间,因为白色的Hue未确定(因为噪音,你可以得到任何值)。

我首先会观察RGB空间中像素的扩散。 (但您没有提供任何样本图像。)