8

我将 Mat 传递给另一个函数并在被调用函数内更改它。我原以为它是一种更复杂的类型,它会通过引用自动传递,因此矩阵在调用函数中会发生变化,但事实并非如此。有人可以向我解释如何从函数中正确返回更改后的 Mat 吗?

这是代码片段:

void callingFunction(Mat img)
{
  Mat tst(100,500,CV_8UC3, Scalar(0,255,0));
  saveImg(tst, "Original image", true);
  testImg(tst);
  saveImg(tst, "Want it to be same as inside testImg but is same as Original", true);
}

void testImg(Mat img)
{
  int rs = 50; // rows
  int cs = 100; // columns
  img = Mat(rs, cs, CV_8UC3, Scalar(255,0,0));
  Mat roi(img, Rect(0, 0, cs, rs/2));
  roi = Scalar(0,0,255); // change a subsection to a different color

  saveImg(img, "inside testImg", true);
}

谢谢!

4

3 回答 3

9

您必须定义Mat参数引用(&)。这是编辑后的代码:

void callingFunction(Mat& img)
{
  Mat tst(100,500,CV_8UC3, Scalar(0,255,0));
  saveImg(tst, "Original image", true);
  testImg(tst);
  saveImg(tst, "Want it to be same as inside testImg but is same as Original", true);
}

void testImg(Mat& img)
{
  int rs = 50; // rows
  int cs = 100; // columns
  img = Mat(rs, cs, CV_8UC3, Scalar(255,0,0));
  Mat roi(img, Rect(0, 0, cs, rs/2));
  roi = Scalar(0,0,255); // change a subsection to a different color

  saveImg(img, "inside testImg", true);
}
于 2012-06-27T21:59:06.800 回答
2

我自己也想知道同样的问题,所以我想进一步澄清@ArtemStorozhuk 给出的答案(这是正确的)。

OpenCV 文档在这里具有误导性,因为看起来您是按值传递矩阵,但实际上 cv::OutputArray 的构造函数定义如下:

_OutputArray::_OutputArray(Mat& m)

所以它通过引用获取矩阵!

由于像 cv::Mat::create 这样的操作会创建一个新矩阵,因此该操作会释放引用并将 couter 设置为 1。因此,为了将结果保留在调用函数中,您必须通过引用传递矩阵。

于 2014-01-09T12:08:42.667 回答
-3

如果确实必须通过引用显式传递,那么所有 OpenCV 函数如何工作?它们都没有通过引用传递值,但它们似乎以某种方式写入传入的 Mat 就好了。例如,下面是 imgproc.hpp 中 Sobel 函数的声明:

//! applies generalized Sobel operator to the image
CV_EXPORTS_W void Sobel( InputArray src, OutputArray dst, int ddepth,
                         int dx, int dy, int ksize=3,
                         double scale=1, double delta=0,
                         int borderType=BORDER_DEFAULT );

如您所见,它传入 src 和 dst 时不带 &。然而我知道,在我用一个空的 dst 调用 Sobel 之后,它最终会被填满。不涉及'&'。

于 2012-12-21T12:24:20.650 回答