【问题标题】:OpenCV changing matrix via submatrixesOpenCV 通过子矩阵改变矩阵
【发布时间】:2016-05-17 00:54:19
【问题描述】:

我想通过子矩阵逐步改变我的矩阵。但是像素值没有变化。输出像素值与输入像素值相同。我的“wavenoise”功能也很有效。

这是我的代码:

cv::Mat wave_trans = Mat::zeros(nr, nc, CV_64FC1);
for (int i = 0; i < L; i++){
    Range Hhigh = Range(nc / 2, nc-1);
    Range Hlow = Range(0, nc / 2 - 1);
    Range Vhigh = Range(nr / 2, nr-1);
    Range Vlow = Range(0, nr / 2 - 1);


    Mat wave_trans_temp1 = Mat(wave_trans, Vlow, Hhigh);
    wave_trans_temp1 = wavenoise(wave_trans_temp1, NoiseVar);


    Mat wave_trans_temp2 = Mat(wave_trans, Vhigh, Hlow);
    wave_trans_temp2 = wavenoise(wave_trans_temp2, NoiseVar);


    Mat wave_trans_temp3 = Mat(wave_trans, Vhigh, Hhigh);
    wave_trans_temp3 = wavenoise(wave_trans_temp3, NoiseVar);

    nc = nc / 2;
    nr = nr / 2;
}

【问题讨论】:

  • 问题可能出在您的wavenoise 函数中,该函数重新分配了矩阵(显示它会很有用)。然后分配结果,将wave_trans_temp* 变量指向新数据。相反,在wavenoise 函数的结果上使用copyTo 将值复制到子矩阵中。您需要记住,cv::Mat 的行为类似于智能指针 - 赋值只会更改对象所指的内容,但不会导致数据的深层复制。

标签: c++ opencv image-processing computer-vision


【解决方案1】:

使用cv::Mat 时,请务必记住,它是基础数据数组的引用计数句柄。

因此,赋值运算符有两个(出于我们的目的)重载,它们具有明显不同的行为。

第一个取一个矩阵:

cv::Mat&amp; cv::Mat::operator= (const cv::Mat&amp; m)

矩阵赋值是一个 O(1) 运算。这意味着不会复制任何数据,但会共享数据,并且引用计数器(如果有)会递增。

第二个采用矩阵表达式:

cv::Mat&amp; cv::Mat::operator= (const cv::MatExpr&amp; expr)

与赋值操作的第一种形式相反,第二种形式可以重用已分配的矩阵,如果它具有适合矩阵表达式结果的大小和类型。

因此,一个表达式,如

nc = nc / 2;

将更新nc 的值,因为nc / 2cv::MatExpr

然而,当我们分配一个cv::Mat,比如从某个函数返回的时候

cv::Mat foo(cv::Mat m);

// ...
void baz(cv::Mat input) {
     cv::Mat bar(input);

     bar = foo(bar); // bar now points to whatever foo returned, input is not changed
}

要解决这个问题,您可以使用cv::Mat::copyTo 将您的函数结果复制到子矩阵/视图中。

例如

Mat wave_trans_temp3 = Mat(wave_trans, Vhigh, Hhigh);
wavenoise(wave_trans_temp3, NoiseVar).copyTo(wave_trans_temp3);

【讨论】:

    猜你喜欢
    • 2017-08-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-23
    • 2017-12-12
    • 1970-01-01
    • 2012-06-09
    • 2014-07-19
    相关资源
    最近更新 更多