【问题标题】:Measuring colors from images through Histograms通过直方图测量图像的颜色
【发布时间】:2017-07-29 13:13:19
【问题描述】:

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

我会尝试更好地解释,但由于我是 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 个色相的像素(它们不会完全远离彼此)。这个我还没试过。

您知道是否有更好的方法来实现这一目标,或者至少我是否在正确的方式上进行此类应用?

【问题讨论】:

  • 你想如何处理全黑的图像?
  • 实际上,出于我的特定目的,我不必处理黑色图像,但如果我这样做,我希望将其检测为完全不符合规范的颜色,因为我对白色感兴趣变成黄色。
  • 糖晶体的图像可以说明我正在尝试进行的处理,因为您将拥有从白色到黄色的不同级别的颜色。

标签: python opencv image-processing matplotlib


【解决方案1】:

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

我会首先观察像素在 RGB 空间中的分布。 (但您没有提供任何示例图片。)

【讨论】:

  • 听起来很有趣,我可以在 RGB 颜色空间中尝试一些结果。对于 HSV,我考虑使用滤镜蒙版来确保色调值在限制范围内。有一个示例image。考虑到紫色背景,您会看到糖晶体可以有白色和黄色的阴影。
  • 差异非常微妙,您需要在受控良好的条件下工作,并使用工业级照明以获得可重现的结果。当然,彩色背景是不可能的,因为它会污染整个堆:在这张图片上,你会发现蓝色的糖。
  • “确保色调值在限制范围内”:当色调不确定时,这是没有用的。
  • @pfnuesel:我不同意。问题是“你知道是否有更好的方法来实现这一目标,或者至少我是否在正确的方式上进行这种应用?”我确实回答了这个问题。
【解决方案2】:

要获得图像的“黄色”,请先获取色调。然后将其分成扇区,以 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)

【讨论】:

  • 线性化似乎是一个好主意,尽管我不确定它是否会像那样简单,因为我可以为同一图像上的每个像素有许多不同的色调。这就是为什么我尝试使用直方图,评估每个色调值上的像素数,然后对饱和度和亮度进行相同的操作,如果我应用正确的方法来比较直方图,则会提供更高的准确性。我需要的东西不仅依赖于像素的频率,还依赖于色调值的接近度。
  • 这种转换不会阻止您制作直方图。它只会改变你的直方图是什么。还是您想要一种不使用直方图的方法?你能详细说明一下“接近”是什么意思吗?
  • 不,不,我想坚持使用直方图,因为我相信它们可以提供有关颜色分量如何在图像上分布的准确信息。当我说接近度时,我的意思是我需要一种考虑分布形状的比较方法,那么在 29 色相上具有 3000 像素的直方图不会完全远离 30 色相上的 3000 像素。你觉得这行得通吗?
猜你喜欢
  • 2012-08-22
  • 2012-01-02
  • 2020-09-07
  • 2012-01-18
  • 2019-12-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多