直接将GIL image_view转换为OpenCV Mat

问题描述

我从模拟器中以gil::image_view的形式获取图像流,需要将它们转换为cv::Mat以便进行进一步处理。到目前为止,我或多或少从this answer复制了代码,但并没有真正理解它:

auto image_view = // data received from an API
using pixel = decltype(image_view)::value_type;
static_assert(sizeof(pixel) == 4,"RGBA");
pixel raw_data[image_view.width() * image_view.height()];
boost::gil::copy_pixels(image_view,boost::gil::interleaved_view(image_view.width(),image_view.height(),raw_data,image_view.width() *
                                                                 sizeof(pixel)));
auto mat = cv::Mat(image_view.height(),image_view.width(),CV_8UC4,raw_data);

我确定没有使用alpha通道,因此我也可以定义另一个image_view:

auto rgb_view = boost::gil::color_converted_view<boost::gil::rgb8_pixel_t>(image_view);
using pixel = decltype(rgb_view)::value_type;
static_assert(sizeof(pixel) == 3,"RGB");
...

在这种情况下,使用boost::gil::copy_pixels(...)复制像素是有意义的,因为无法在恒定时间内将交错的rgba8转换为rgb8。

鉴于应用程序的性质,我很确定图像已经在内存中的某个位置。因此,从技术上讲,我可以只使用指向第一个元素的指针来创建我的OpenCV映像,而不必使用额外的通道。

解决方法

当时,尽管缺乏所有权,但我并没有真正想到image_view可以指向基础原始数据的存储位置。查看所有这些auto所翻译的内容并不能解决混乱问题。写下问题给了我一个解决的想法。

假设数据已经在内存中,则很容易访问原始数据,供下游库使用。以下代码段可以帮助其他人解决此问题:

  1. 转换为其他图像格式(此处为24bpp),然后转换为cv::Mat:需要复制所有像素
auto image_view = // data received from an API
auto rgb_view = boost::gil::color_converted_view<boost::gil::rgb8_pixel_t>(image_view);
using pixel = decltype(rgb_view)::value_type;
static_assert(sizeof(pixel) == 3,"RGB");
pixel raw_data[rgb_view.width() * rgb_view.height()];
boost::gil::copy_pixels(image_view,boost::gil::interleaved_view(rgb_view.width(),rgb_view.height(),raw_data,rgb_view.width() *
                                                                 sizeof(pixel)));
auto mat = cv::Mat(image_view.height(),image_view.width(),CV_8UC3,raw_data);
  1. 直接转换为cv::Mat:无需复制
auto image_view = // data received from an API
static_assert(sizeof(decltype(image_view)::value_type) == 4,"RGBA");
auto mat = cv::Mat(image_view.height(),CV_8UC4,&image_view(0,0));

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...