检测噪声帧

5
我有一个 FPV(第一人称视角)接收器,可以显示安装在无人机上的 FPV 摄像头发送的帧。当发射器工作时,接收器会显示摄像头的画面。否则,如果连接丢失或发射器不工作,则会显示噪声帧。
噪声帧具有随机模式(有时更多白色像素,有时更多黑色像素)。我想以有效的方式使用 Python 中的 OpenCV 检测这些噪声帧。我知道 OpenCV 有一个名为cv2.fastNlMeansDenoisingColored()的方法。但在这种情况下,我想检测噪声帧而不是每个帧中的噪声。
附有噪声帧的样本:

enter image description here

另一个噪声帧的示例:

enter image description here

一个有效的框架(可以是任何东西):

enter image description here


1
你能否添加一个噪声帧的示例,其中有更多的白色像素和正常帧? - nathancy
@nathancy 刚刚添加了。我的主要问题是找出传入的视频帧是否有效。 - aminrd
1个回答

10
假设您的有效视频帧至少具有一定数量的颜色信息,并且您的噪声帧更多地是黑白色,那么可能会有一种简单的方法,使用HSV颜色空间中的饱和度通道。
  • 使用cv2.cvtColor将图像转换为HSV颜色空间。
  • 计算饱和度通道的直方图,参见cv2.calcHist
  • 计算具有最小饱和度的像素的百分比,假设至少为0.05
  • 如果该百分比超过阈值,假设为0.5,则至少有50%的像素具有至少0.05的饱和度,因此该帧似乎是有效的帧。(根据需要调整阈值。)
import cv2
from matplotlib import pyplot as plt
import numpy as np
from skimage import io           # Only needed for web grabbing images, use cv2.imread for local images


def is_valid(image):

    # Convert image to HSV color space
    image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)

    # Calculate histogram of saturation channel
    s = cv2.calcHist([image], [1], None, [256], [0, 256])

    # Calculate percentage of pixels with saturation >= p
    p = 0.05
    s_perc = np.sum(s[int(p * 255):-1]) / np.prod(image.shape[0:2])

    ##### Just for visualization and debug; remove in final
    plt.plot(s)
    plt.plot([p * 255, p * 255], [0, np.max(s)], 'r')
    plt.text(p * 255 + 5, 0.9 * np.max(s), str(s_perc))
    plt.show()
    ##### Just for visualization and debug; remove in final

    # Percentage threshold; above: valid image, below: noise
    s_thr = 0.5
    return s_perc > s_thr


# Read example images; convert to grayscale
noise1 = cv2.cvtColor(io.imread('https://istack.dev59.com/Xz9l0.webp'), cv2.COLOR_RGB2BGR)
noise2 = cv2.cvtColor(io.imread('https://istack.dev59.com/9ZPAj.webp'), cv2.COLOR_RGB2BGR)
valid = cv2.cvtColor(io.imread('https://istack.dev59.com/0FNPQ.webp'), cv2.COLOR_RGB2BGR)

for img in [noise1, noise2, valid]:
    print(is_valid(img))

可视化输出(按照问题中的顺序):

Noise 1

Noise 2

Valid

而且,主要输出为:

False
False
True

去掉整个可视化部分后,在我的机器上,每张图像的is_valid调用不到0.01秒。不确定你在录制时使用了哪种硬件,但也许这种方法也适用于某些具有足够帧速率的“实时”处理。

最后一点说明:我试图摆脱OpenCV直方图,并直接使用NumPy计算百分比,但这比所提供的方法花费更多时间。奇怪。

希望有所帮助!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接