C++ OpenCV通过子矩阵改变矩阵

C++ OpenCV通过子矩阵改变矩阵,c++,opencv,image-processing,computer-vision,C++,Opencv,Image Processing,Computer Vision,我想通过子矩阵一步一步地改变我的矩阵。但像素值没有变化。输出像素值与输入像素值相同。我的“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 = R

我想通过子矩阵一步一步地改变我的矩阵。但像素值没有变化。输出像素值与输入像素值相同。我的“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;
}
cv::Mat wave_trans=Mat::zeros(nr、nc、cv_64FC1);
对于(int i=0;i
使用
cv::Mat
时,务必记住它是底层数据数组的引用计数句柄

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

第一个是矩阵:

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

第二个是矩阵表达式:

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

因此,一个表达式,如

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
}

要解决此问题,可以使用将函数的结果复制到子矩阵/视图中

比如说

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

问题可能出在重新分配矩阵的
wavenoise
函数中(显示它会很有用)。然后分配结果,将
wave\u trans\u temp*
变量指向新数据。相反,使用
wavenoise
函数的结果上的
copyTo
将值复制到子矩阵中。您需要记住,
cv::Mat
的行为就像一个智能指针——赋值只会更改对象引用的内容,但不会导致数据的深度复制。