如何从函数返回多维 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<cv::Mat>
或std::array<cv::Mat,3>
您当前创建了三个不同的cv::Mat
s,因为您cv::split
输入图像。你只需要在返回之前再次cv::merge
他们。
【参考方案1】:
函数three_channel_convolution
的返回值是cv::Mat
,但是你返回的是cv::Mat[3]
。
如果您想返回一个 3d 矩阵,您需要将函数的签名更改为 std::array<cv::Mat, 3>
之类的东西。请记住,这可能存在一些性能问题。
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<cv::Mat, 3>
。 std::array
是一个对象,就像 std::string
或 std::vector
或 cv::Mat
一样,您将返回其中一个。这是简单的解决方案,比返回指针要简单得多。您遇到的基本问题是常规数组不是 C++ 中的第一类对象,并且有些事情它们不能做(比如从函数返回)。 std::array
是一种填补常规数组所具有的空白的方法。
@jhon 一旦我将返回的对象放入主函数中的有效变量中,我可以像普通的 cv::Mat 对象一样使用 cv::Mat 方法或属性吗?
以上是关于如何从函数返回多维 Mat 数组的主要内容,如果未能解决你的问题,请参考以下文章
C语言基础:C 中数组详解(多维数组传递数组给函数 从函数返回数组 指向数组的指针 )