如何在灰度模式下从相机捕获视频?

时间:2021-05-29 06:24:38

标签: directshow

看看我到目前为止编写的这段代码,用于使用 directshow 从相机捕获视频/音频: https://gist.github.com/LinArcX/b43ce8b1905b165de2314e6f9b202c8c

它可以工作,但它使用 MEDIASUBTYPE_RGB24 并且结果是丰富多彩的。我想删除颜色并输出灰度视频。有人说我可以使用 YUV 子类型并从中删除 UV。但我不知道如何在我的代码中做到这一点。

1 个答案:

答案 0 :(得分:0)

您需要将来自相机的位图像素(在本例中为 MEDIASUBTYPE_RGB24)转换为 YUV 格式。您可以使用 these equations 做到这一点。 YUV 颜色空间的“Y”分量是灰度图像,而“U”和“V”分量具有颜色信息。您可以保留 Y 分量并丢弃其余部分,并将 24 位彩色图像的位图帧就地转换为灰度,因此:

void RGB24_to_InPlaceGreyscale(uint32_t  width, uint32_t height, uint8_t* buf)
{
    uint32_t count = width * height;
    while (count)
    {
        // Calculate the grey scale luminescence value "Y" of the
        // RGB pixel and replace the RGB values with the Y value.

        // Y =  0.257 * R + 0.504 * G + 0.098 * B + 16
        uint8_t Y = static_cast<uint8_t>(0.257f * static_cast<float>(buf[2]) + \
            0.504f * static_cast<float>(buf[1]) + \
            0.098f * static_cast<float>(buf[0]) + 16.0f);
        buf[0] = Y;    // blue
        buf[1] = Y;    // green
        buf[2] = Y;    // red
        buf += 3;
        count--;
    }
}

其中 widthheight 是以像素为单位的位图尺寸,buf 是指向位图在内存中所在的缓冲区的指针。

如果您希望视频预览显示灰度图像,那么您可以编写一个 Transform In Place Direct Show Filter 并将其添加到捕获图钉之后的图形中。否则,只需在从样本采集器获取位图后转换位图。如果您最终制作了一个 Direct Show 过滤器以灰度预览,那么我建议将 Y 值的浮点计算替换为包含每个 R 的 0-255 范围内的每个结果的预计算值的查找表, G、B 分量。它可能已经足够快了。我会让你试验一下。

附言我确实有一个 open-source library of C++ functions on GitHub 具有这种类型的 FourCC 视频位图转换。