如何从函数返回多维 Mat 数组

Posted

技术标签:

【中文标题】如何从函数返回多维 Mat 数组【英文标题】:How to return a multidimensional Mat array from a function 【发布时间】:2019-02-14 13:38:08 【问题描述】:

我想返回一个尺寸为 [w][h][c] 的 cv::Mat 对象,其中 w 是宽度,h 是高度,c 是通道或深度。但是编译器给了我一个错误。

这是我的代码:

cv::Mat three_channel_convolution(cv::Mat bgr_image, cv::Mat kernel)

   cv::Mat feature_map[3];
   cv::Mat bgr[3];

   cv::split(bgr_image, bgr);

   for (uchar i = 0; i < 3; i++)
   
      feature_map[i] = one_channel_convolution(bgr[i], kernel);
      std::string name_feature_map = "bgr_feature_map_" + std::to_string(i) + ".jpg";
      cv::imwrite(name_feature_map, feature_map[i]);
   

return feature_map;

在这个函数中,我想为图像 BGR 中的三个通道中的每一个通道使用一个过滤器(内核)进行卷积。所以卷积函数在一个通道中返回运算结果(A single 2D Mat [][]),并将其存储在 feature_map Mat 数组中。如何返回这个 Mat 数组?

然后在我的 main() 函数中,我这样调用函数:

feature_map = three_channel_convolution(image, kernels[0]);

感谢您的帮助!

【问题讨论】:

你得到什么错误? 您声明了返回cv::Mat的方法 您正在返回对临时对象(临时数组)的引用。您可以返回std::shared_ptr&lt;cv::Mat&gt;std::array&lt;cv::Mat,3&gt; 您当前创建了三个不同的cv::Mats,因为您cv::split 输入图像。你只需要在返回之前再次cv::merge他们。 【参考方案1】:

函数three_channel_convolution的返回值是cv::Mat,但是你返回的是cv::Mat[3]

如果您想返回一个 3d 矩阵,您需要将函数的签名更改为 std::array&lt;cv::Mat, 3&gt; 之类的东西。请记住,这可能存在一些性能问题。

std::array<cv::Mat, 3> three_channel_convolution(cv::Mat bgr_image, cv::Mat kernel) 
   std::array<cv::Mat, 3> feature_map;
   std::array<cv::Mat, 3> bgr;

   cv::split(bgr_image, bgr);

   for (uchar i = 0; i < 3; i++) 
      feature_map[i] = one_channel_convolution(bgr[i], kernel);
      std::string name_feature_map = "bgr_feature_map_" + std::to_string(i) + ".jpg";
      cv::imwrite(name_feature_map, feature_map[i]);
   

    return feature_map;

附言。请在后续帖子中报告确切的错误消息。

【讨论】:

“指针”解决方案有效。我知道我正在做的是返回一个指向 mat 数组存储位置的指针。但是你能解释一下,如果我在函数的返回值中使用 std::array<:mat> 我在做什么? 一个普通的旧数组不能用作返回值。你可以做两件事。首先(旧的 c 风格),您可以返回指向数组开头的指针。这可能无法保存,您必须注意内存。如果您将指针作为函数的输出参数,这也成立。其次,你可以给我们一个 C++ 容器一个返回值。从 C++11 开始,您将拥有所谓的返回值优化,这将使其非常快,并且不会创建不需要的副本。 @PabloCano 在这种情况下,您将返回 std::array&lt;cv::Mat, 3&gt;std::array 是一个对象,就像 std::stringstd::vectorcv::Mat 一样,您将返回其中一个。这是简单的解决方案,比返回指针要简单得多。您遇到的基本问题是常规数组不是 C++ 中的第一类对象,并且有些事情它们不能做(比如从函数返回)。 std::array 是一种填补常规数组所具有的空白的方法。 @jhon 一旦我将返回的对象放入主函数中的有效变量中,我可以像普通的 cv::Mat 对象一样使用 cv::Mat 方法或属性吗?

以上是关于如何从函数返回多维 Mat 数组的主要内容,如果未能解决你的问题,请参考以下文章

C语言基础:C 中数组详解(多维数组传递数组给函数 从函数返回数组 指向数组的指针 )

如何将 cv::mat 对象从 python 模块传递给 c++ 函数并返回返回的 cv::mat 类型的对象?

在 C++ 中返回多维数组的函数

使用php从多维数组中获取子数组

来自 C 函数的多维字符数组返回错误

从给定数组返回多维数组