OpenCV更改函数内的Mat(Mat范围)

时间:2012-06-27 21:40:26

标签: opencv

我将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);
}

谢谢!

3 个答案:

答案 0 :(得分:8)

您必须将Mat定义为parameter-reference(&)。这是编辑过的代码:

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);
}

答案 1 :(得分:2)

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

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

_OutputArray::_OutputArray(Mat& m)

所以它通过引用得到矩阵!

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

答案 2 :(得分:-2)

如果您必须通过引用显式传递,那么所有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而没有&amp ;.但我知道,在我用一个空的dst打电话给索贝尔之后,它最终会被填满。没有'&'参与。