【问题标题】:OpenCV, how do I quantify a pixel changeing color throughout framesOpenCV,我如何量化像素在整个帧中的颜色变化
【发布时间】:2021-02-10 14:49:27
【问题描述】:

我正在尝试使用 openCV 编写这段小代码,它会告诉我图像改变颜色的程度,并基于此和阈值它成为一个或另一个组的一部分。 我所拥有的是颜色略有不同的相同图像列表。

现在这些是测试图像,基于它们我应该以某种方式量化颜色的变化,并以此为基础让其他一些图片通过或不通过。

我想过要取平均值,但这只是棕黄色,不是一个好的衡量标准。 我想到了主色,但随着图片在整个过程中改变颜色...... 但我不知道我还能尝试什么。 有没有办法设置一系列图片必须遵守验证的颜色范围?

如果有人可以帮助我朝一个很棒的方向前进!

根据要求提供示例第一张图片:

第二张图片: 第三张图片:

图片列表是这张图片的列表,但色调稍暗或稍浅,反光或多或少。 到目前为止,我编写的所有代码只是为了获取我可以分析的 ROI 列表。

编辑: 形状总是一样的,背景也是一样的。只有颜色和亮度似乎都在变化。 我现在已经在时间序列中绘制了 RG&B 值。这并没有说很多。 我现在正试图通过评估背景中的颜色差异(因为它不应该改变每个差异应该是由于亮度)来将亮度从等式中分离出来,并使用该系数来加权 R、G 和 B 通道。 我会及时通知你们。

【问题讨论】:

标签: python opencv pycharm


【解决方案1】:

我认为稍微不同的方法可能会更好:

  • 我没有将背景亮度变化归一化,而是考虑通过从左上角开始填充填充来完全移除背景

  • 与其查看 RGB 值,不如转换为 HSV colorspace 并查看那里的图像。

所以,我将您的 3 个帧重命名为 f-1.pngf-2.pngf-3.png 并运行:

#!/usr/bin/env python3

import cv2
import numpy as np
import pathlib

def ProcessOne(filename):
   """Process a single image for the Hue, Saturation and Value of the foreground pixels"""
   # Load image
   im = cv2.imread(filename, cv2.IMREAD_COLOR)

   # Segment to get interesting area
   grey = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
   _, th = cv2.threshold(grey,128,255,cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)
   ff = th.copy()
   h, w = th.shape[:2]
   mask = np.zeros((h+2, w+2), np.uint8)
   # Floodfill from (0, 0)
   cv2.floodFill(ff, mask, (0,0), 255);
   res = ~(th | ~ff)

   # This is all debug and can be removed
   cv2.imwrite('DEBUG-grey.png',grey)
   cv2.imwrite('DEBUG-th.png',th)
   cv2.imwrite('DEBUG-mask.png',mask)
   cv2.imwrite('DEBUG-ff.png',ff)
   cv2.imwrite('DEBUG-res.png',res)

   # Convert original image to HSV and split channels
   HSV = cv2.cvtColor(im, cv2.COLOR_BGR2HSV) 
   H, S, V = cv2.split(HSV)
   maskedHue = np.ma.masked_where(res,H)
   meanHue   = maskedHue.mean()
   maskedSat = np.ma.masked_where(res,S)
   meanSat   = maskedSat.mean()
   maskedVal = np.ma.masked_where(res,V)
   meanVal   = maskedVal.mean()
   print(f'Filename: {filename}, Hue: {meanHue}, Sat: {meanSat}, Val: {meanVal}')

# Process all frames f-XXX.png
for filename in pathlib.Path.cwd().glob('f-*.png'):
   ProcessOne(filename.name)

我得到了这些结果:

Filename: f-1.png, Hue: 166.95651173492868, Sat: 125.59134836631385, Val: 116.88587206626784
Filename: f-2.png, Hue: 141.85912185959145, Sat: 62.537684902559285, Val: 64.28621742193003
Filename: f-3.png, Hue: 163.32165750915752, Sat: 110.39972527472527, Val: 90.87522893772893

希望你能看到:

  • 第一个图像是饱和的 (Hue=125) 和明亮的值 (Val=116)
  • 第二张图像较灰,或饱和度较低 (Sat=62),较暗 (Val=64)
  • 第三张图像几乎和第一张一样饱和和明亮

请注意,您可以使用 ImageMagick 在终端中执行非常类似的操作。在这里,我从左上角的偏移量 (40,40) 开始裁剪出一个 30x30 像素的正方形(以青色标记)。

然后我通过将像素大小调整为 1x1 来平均像素并转换为 HSV 色彩空间并将结果打印为文本:

magick f-1.png -crop 30x30+40+40 -resize 1x1\! -colorspace HSV txt:

0,0: (343.898,50.9512%,45.2334%)  #F48273  hsv(343.898,50.9512%,45.2334%)

magick f-2.png -crop 30x30+40+40 -resize 1x1\! -colorspace HSV txt:

0,0: (353.646,26.5537%,24.0175%)  #FA443D  hsv(353.646,26.5537%,24.0175%)

magick f-3.png -crop 30x30+40+40 -resize 1x1\! -colorspace HSV txt:

0,0: (346.963,45.7643%,35.3905%)  #F6755A  hsv(346.963,45.7643%,35.3905%)

它显然使用了稍微不同的图像区域和不同的值范围,但如果你查看最后一个字段,即hsv(...),你会发现它遵循与 Python 相同的模式。

【讨论】:

  • 非常感谢!这真的是另一种方法!我会尝试一下,画出所有的差异,看看我是否能想出某种趋势。如果我这样做,我会发布更新。非常感谢!
  • 好的,我测试了这个,我另外除以背景值,以除掉任何亮度因子。我为 RGB 和 HSV 做了这个,然后我根据绿色对结果进行了标准化,并对所有结果进行了排序。现在我确实发现红色的结果相当稳定,蓝色似乎到处都是。 H也一样,相当稳定,其余的都在。尽管如此,您的帮助还是非常感谢和可靠的。非常感谢!
猜你喜欢
  • 2014-12-24
  • 2021-10-17
  • 1970-01-01
  • 1970-01-01
  • 2016-11-20
  • 2016-09-26
  • 2014-10-04
  • 2021-12-08
  • 2016-07-03
相关资源
最近更新 更多