功能相同但结果不同

时间:2017-11-21 02:42:45

标签: c++ opencv image-processing

交叉发布here

这是我的私人功能,用于显示那些红色的投资回报率。

Mat highlight(Mat srcImg, Mat mask) {
    if (srcImg.size != mask.size) {
        cout << "Your two images tried to highlight have different SIZE.\n";
        exit(1);
    }
    if (mask.channels() != 1)
        cvtColor(mask, mask, COLOR_BGR2GRAY);
    if (mask.type() != CV_8UC1)
        mask.convertTo(mask, CV_8UC1);
    threshold(mask, mask, 0, 255, THRESH_BINARY_INV + THRESH_OTSU);
    cvtColor(mask, mask, COLOR_GRAY2BGR);
    if (srcImg.channels() != 3)
        cvtColor(srcImg, srcImg, COLOR_GRAY2BGR);
    if (srcImg.type() != CV_8UC3)
        srcImg.convertTo(srcImg, CV_8UC3);
    dilate(mask - Scalar(0, 0, 255), mask, Mat(), Point(-1, -1), 2);
    return srcImg - mask;
}

这是我的代码。

#include<opencv.hpp>
using namespace std;
using namespace cv;
Mat highlight(Mat, Mat);
int main() {
    Mat emptyImg = imread("test.jpg", 0);
    Mat test = emptyImg.clone();

    Mat mask(5, 5, CV_8UC1, Scalar(0));
    for (int i = 0; i < mask.rows; i++) {
        uchar* data = mask.ptr<uchar>(i);
        for (int j = 0; j < mask.cols; j++)
            if ((i + j) % 2 == 0)
                data[j] = 255;
    }
    resize(mask, mask, emptyImg.size(), 0, 0, INTER_NEAREST);
    Mat img1, img2,mask1,mask2;
    img1 = highlight(emptyImg, mask);
    imshow("img1", img1);
    img2 = highlight(test, mask);
    imshow("img2", img2);

    waitKey();
    return 0;
}

这是我的test image。我很困惑。为什么我会得到不同的结果,如下面的

根据我的预期,img1img2应完全相同。有什么我想念的吗?

1 个答案:

答案 0 :(得分:2)

当您第一次致电img1 = highlight(emptyImg, mask);时,它会更改mask并将其用于img1。当您再次致电highlight时,它会使用相同的mask,再次更改它,并将其用于img2。但究竟是什么导致了这个问题呢?

threshold(mask, mask, 0, 255, THRESH_BINARY_INV + THRESH_OTSU);是罪魁祸首。它会因mask而反转THRESH_BINARY_INV,然后当您再次调用它时,它会再次反转它。请记住,cv::Mat是一个引用变量(cv::Mat就像一个指针),所以当你在函数的参数中传递它时,对它做的任何更改都会发生在原始的mat上。这就是我们使用.clone()的原因,它会创建cv::Mat的副本。在您在函数中传递掩码之前,最快的修复方法是.clone()掩码。

简化调试代码(删除threshold行导致反转的棋盘不会发生)。

using namespace std;
using namespace cv;
Mat highlight(Mat, Mat);
int main() {
    Mat emptyImg = imread("test.jpg", 0);
    Mat test = emptyImg.clone();
    Mat mask(5, 5, CV_8UC1, Scalar(0));
    for (int i = 0; i < mask.rows; i++) {
        uchar* data = mask.ptr<uchar>(i);
        for (int j = 0; j < mask.cols; j++)
            if ((i + j) % 2 == 0)
                data[j] = 255;
    }
    resize(mask, mask, emptyImg.size(), 0, 0, INTER_NEAREST);
    Mat img1, img2, mask1, mask2;
    imshow("m1", mask);
    img1 = highlight(emptyImg, mask);
    imshow("img1", img1);
    imshow("m2", mask);
    img2 = highlight(test, mask);
    imshow("img2", img2);
    waitKey();
    return 0;
}
Mat highlight(Mat srcImg, Mat mask) {
    threshold(mask, mask, 0, 255, THRESH_BINARY_INV + THRESH_OTSU);
    return srcImg - mask;
}