6

在此处输入图像描述

这张图片只是一个例子。右上是原始图像,左上是色调,左下是饱和度,右下是值。可以很容易地看出,H 和 S 都充满了伪影。我想降低亮度,所以结果会挑选出很多这样的伪影。

我做错了什么?

我的代码很简单:

vc = cv2.VideoCapture( 0 )
# while true and checking ret
ret, frame = vc.read()
frame_hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
cv2.imshow("h", frame_hsv[:,:,0])
cv2.imshow("s", frame_hsv[:,:,1])
cv2.imshow("v", frame_hsv[:,:,2])
4

2 回答 2

16

我觉得你的问题有误解。虽然 Boyko Peranov 的回答肯定是正确的,但您提供的图像没有问题。其背后的逻辑如下:您的相机在 RGB 颜色空间中拍照,根据定义,它是一个立方体。当您将其转换为 HSV 颜色空间时,所有像素都映射到以下锥体: HSV 锥体

色调(HSV 的第一个通道)是锥体上的角度,饱和度(HSV 的第二个通道,在图像中称为色度)是到锥体中心的距离,值(HSV 的第三个通道)是高度在锥体上。

Hue 通道通常定义在 0-360 之间,从 0 处的红色开始(在 8 位图像的情况下,OpenCV 使用 0-180 范围来拟合无符号字符,如文档中所述)。但问题是,值 0 和 359 的两个像素在颜色上确实非常接近。通过仅取外表面(当饱和度最大时)使 HSV 锥体变平时,可以更容易地看到: 扁平 HSV 锥体

即使这些值在感知上很接近(0 处为完美的红色,359 处为红色,带有一点点紫色),这两个值也相距甚远。这就是您在 Hue 频道中描述的“伪影”的原因。当 OpenCV 以灰度显示它时,它会将黑色映射到 0,将白色映射到 359。事实上,它们是非常相似的颜色,但是当以灰度映射时,显示的距离太远了。有两种方法可以规避这个反直觉的事实:您可以将 H 通道重新投射到具有固定饱和度和值的 RGB 空间中,这将更接近我们的感知。您还可以使用其他基于感知的颜色空间(例如Lab 颜色空间),它不会给您带来这些数学副作用。

Boyko Peranov 解释了这些工件补丁是方形的原因。JPEG 压缩通过将像素替换为近似于它所替换的补丁的更大方块来工作。如果您在创建 jpg 时将压缩质量设置得很低,您甚至可以看到这些方块出现在 RGB 图像中。质量越低,正方形越大越明显。这些方块的平均值是单个值,对于红色色调,最终可能介于 0 和 5(显示为黑色)或 355 和 359(显示为白色)之间。这就解释了为什么“人工制品”是方形的。

我们也可能会问自己,为什么在色调通道中会出现更多的 JPEG 压缩伪影。这是因为色度二次采样,基于感知的研究表明,我们的眼睛不太容易看到颜色的快速变化而不是强度的快速变化。因此,在压缩时,JPEG 会故意丢失色度信息,因为我们无论如何都不会注意到它。

饱和度(左下角的图像)白色变化点的情况类​​似。您正在描述几乎黑色的像素(在锥体的尖端)。因此,饱和度值可能变化很大,但不会对像素的颜色产生太大影响:它将始终接近黑色。这也是 HSV 颜色空间不完全基于感知的副作用。

RGB(或 OpenCV 的 BGR)和 HSV 之间的转换(理论上)是无损的。您可以说服自己:将您的 HSV 图像重新转换为 RGB 图像,您将获得与开始时完全相同的图像,没有添加任何伪像。

于 2015-01-28T20:32:53.017 回答
3

您正在使用有损压缩图像,因此会出现矩形伪影。对于视频,您的展示时间很短,可能有带宽限制等。因此整体图片质量会下降。你可以:

  • Capture通过使用代替VideoCapture或使用一系列静止图像
  • 提取 5-10 个视频帧,并对它们进行平均。
于 2013-06-21T16:25:39.833 回答