问题描述
看看我到目前为止编写的这段代码,用于使用 directshow 从相机捕获视频/音频: https://gist.github.com/LinArcX/b43ce8b1905b165de2314e6f9b202c8c
它可以工作,但它使用 MEDIASUBTYPE_RGB24
并且结果是丰富多彩的。我想删除颜色并输出灰度视频。有人说我可以使用 YUV 子类型并从中删除 UV。但我不知道如何在我的代码中做到这一点。
解决方法
您需要将来自相机的位图像素(在本例中为 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--;
}
}
其中 width
和 height
是以像素为单位的位图尺寸,buf
是指向位图在内存中所在的缓冲区的指针。
如果您希望视频预览显示灰度图像,那么您可以编写一个 Transform In Place Direct Show Filter 并将其添加到捕获图钉之后的图形中。否则,只需在从样本采集器获取位图后转换位图。如果您最终制作了一个 Direct Show 过滤器以灰度预览,那么我建议将 Y 值的浮点计算替换为包含每个 R 的 0-255 范围内的每个结果的预计算值的查找表, G、B 分量。它可能已经足够快了。我会让你试验一下。
附言我确实有一个 open-source library of C++ functions on GitHub 具有这种类型的 FourCC 视频位图转换。