opencv,BGR2HSV创建了大量的工件

Dr *_*ban 4 python opencv image-processing hsv

在此输入图像描述

这个图像只是一个例子.右上角是原始图像,左上角是色调,左下角是饱和度,右下角是值.可以很容易地看出,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])
Run Code Online (Sandbox Code Playgroud)

Sor*_*vux 10

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

Hue(HSV的第一个通道)是锥体上的角度,饱和度(HSV的第二个通道,图像中称为Chroma)是到锥体中心的距离,而值(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图像,您可以获得与开始时完全相同的图像,不添加任何工件.


Boy*_*nov 2

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

  • Capture通过使用代替VideoCapture或来使用一系列静态镜头
  • 提取 5-10 个视频帧,并对它们进行平均。