OpenCV通过子矩阵更改矩阵

3

我希望通过逐步使用子矩阵来更改我的矩阵。但是像素值没有改变。输出像素值与输入像素值相同。另外,我的"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*变量,指向新数据。相反,使用copyTo函数将wavenoise函数的结果复制到子矩阵中。需要记住的是,cv::Mat的行为类似于智能指针--赋值只是改变对象所引用的内容,但不会深度复制数据。 - Dan Mašek
1个回答

1
使用cv::Mat时,需要注意它是对底层数据数组的引用计数句柄。
因此,有两个(对于我们的目的)重载的赋值运算符,具有显着不同的行为。
第一个接受矩阵: cv::Mat& cv::Mat::operator= (const cv::Mat& m) 矩阵赋值是O(1)操作。这意味着没有数据被复制,但数据是共享的,如果有的话,引用计数器将增加。
第二个接受矩阵表达式: cv::Mat& cv::Mat::operator= (const cv::MatExpr& expr) 与第一种赋值操作相反,第二种形式可以重用已经分配的矩阵,如果它具有适合矩阵表达式结果的正确大小和类型。因此,例如以下表达式:
nc = nc / 2;

将更新nc的值,因为nc / 2是一个cv::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);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接