从 Gstreamer 创建 OpenCv 垫会创建灰色图像,但我想要颜色
Creating OpenCv mat from Gstreamer creates grey image, but I want color
我使用 gstreamer 访问网络摄像头图像。我使用 appsrc 来访问这些图像,然后我希望能够使用 openCv 处理它们。所以首先我需要将它们加载到一个 Mat 对象中。但是,我只能以灰度进行此操作。如果我尝试读取多个频道,我会收到 'read access violation' 异常。
我用来创建垫子的代码如下:
GstSample* sample;
GstBuffer* buffer;
GstMapInfo map;
g_signal_emit_by_name(sink, "pull-sample", &sample);
g_print("Check frame");
if (sample != NULL) {
buffer = gst_sample_get_buffer(sample);
if (gst_buffer_map(buffer, &map, GST_MAP_READ))
{
Mat frame(Size(width, height), CV_8UC3, map.data, cv::Mat::AUTO_STEP);
imwrite("elephant.jpg", frame);
}
g_print("Found frame");
return GST_FLOW_OK;
}
return GST_FLOW_ERROR;
当我之前使用文件接收器写入文件时,图像是彩色的。
我在我的代码中使用了以下过滤帽:
filtercaps = gst_caps_new_simple("image/jpeg", "format", G_TYPE_STRING, "RGB", "width", G_TYPE_INT, width,
"height", G_TYPE_INT,
height, "framerate", GST_TYPE_FRACTION, 30,
1, NULL);
我试过将这个过滤器放在源之后和接收器之前,都没有解决问题。我的管道中还有一个 jpeg 解码器。
我真的不知道如何解决这个问题。非常感谢任何帮助或提示!
我自己想出来的。问题是管道的输出不是 RGB。我尝试实施一个 capsfilter 来解决这个问题,但这没有成功(我不明白为什么)。
我通过简单地转换管道的输出解决了它。在here you can see that the preferred output is I420 (A YUV color format). I used the code suggested in this post改造BGRA。我的最终代码如下所示:
GstSample* sample;
GstBuffer* buffer;
GstMapInfo map;
GstMemory *mem;
mem = gst_allocator_alloc(NULL, 1000000, NULL);
gst_memory_map(mem, &map, GST_MAP_WRITE);
g_signal_emit_by_name(sink, "pull-sample", &sample);
g_print("Check frame");
if (sample != NULL) {
buffer = gst_sample_get_buffer(sample);
if (gst_buffer_map(buffer, &map, GST_MAP_READ))
{
g_print("size: %d", map.size);
Mat frameYUV(height+height/2, width, CV_8UC1 , map.data, cv::Mat::AUTO_STEP);
cv::Mat frameRGB(height, width, CV_8UC4);
cv::cvtColor(frameYUV, frameRGB, CV_YUV2BGRA_I420);
imwrite("elephant.jpg", frameRGB);
}
g_print("Found frame");
return GST_FLOW_OK;
}
gst_memory_unmap(mem, &map);
return GST_FLOW_ERROR;
我使用 gstreamer 访问网络摄像头图像。我使用 appsrc 来访问这些图像,然后我希望能够使用 openCv 处理它们。所以首先我需要将它们加载到一个 Mat 对象中。但是,我只能以灰度进行此操作。如果我尝试读取多个频道,我会收到 'read access violation' 异常。
我用来创建垫子的代码如下:
GstSample* sample;
GstBuffer* buffer;
GstMapInfo map;
g_signal_emit_by_name(sink, "pull-sample", &sample);
g_print("Check frame");
if (sample != NULL) {
buffer = gst_sample_get_buffer(sample);
if (gst_buffer_map(buffer, &map, GST_MAP_READ))
{
Mat frame(Size(width, height), CV_8UC3, map.data, cv::Mat::AUTO_STEP);
imwrite("elephant.jpg", frame);
}
g_print("Found frame");
return GST_FLOW_OK;
}
return GST_FLOW_ERROR;
当我之前使用文件接收器写入文件时,图像是彩色的。
我在我的代码中使用了以下过滤帽:
filtercaps = gst_caps_new_simple("image/jpeg", "format", G_TYPE_STRING, "RGB", "width", G_TYPE_INT, width,
"height", G_TYPE_INT,
height, "framerate", GST_TYPE_FRACTION, 30,
1, NULL);
我试过将这个过滤器放在源之后和接收器之前,都没有解决问题。我的管道中还有一个 jpeg 解码器。
我真的不知道如何解决这个问题。非常感谢任何帮助或提示!
我自己想出来的。问题是管道的输出不是 RGB。我尝试实施一个 capsfilter 来解决这个问题,但这没有成功(我不明白为什么)。
我通过简单地转换管道的输出解决了它。在here you can see that the preferred output is I420 (A YUV color format). I used the code suggested in this post改造BGRA。我的最终代码如下所示:
GstSample* sample;
GstBuffer* buffer;
GstMapInfo map;
GstMemory *mem;
mem = gst_allocator_alloc(NULL, 1000000, NULL);
gst_memory_map(mem, &map, GST_MAP_WRITE);
g_signal_emit_by_name(sink, "pull-sample", &sample);
g_print("Check frame");
if (sample != NULL) {
buffer = gst_sample_get_buffer(sample);
if (gst_buffer_map(buffer, &map, GST_MAP_READ))
{
g_print("size: %d", map.size);
Mat frameYUV(height+height/2, width, CV_8UC1 , map.data, cv::Mat::AUTO_STEP);
cv::Mat frameRGB(height, width, CV_8UC4);
cv::cvtColor(frameYUV, frameRGB, CV_YUV2BGRA_I420);
imwrite("elephant.jpg", frameRGB);
}
g_print("Found frame");
return GST_FLOW_OK;
}
gst_memory_unmap(mem, &map);
return GST_FLOW_ERROR;