计算平均值:屏蔽图像与ROI的不同结果

时间:2018-05-20 08:08:40

标签: c++ opencv

我有一个奇怪的问题,如果我使用掩码而不是创建一个小ROI的新Mat,我的平均梯度幅度结果是不同的。我将解释我执行此操作的两种不同方式,并获得2种不同的平均梯度幅度结果。我以为我应该得到相同的平均梯度幅度结果?

  

场景:图像A是我的景观源/原始图像。我想获得区域A (10,100), (100,100), (100,150), (10,150)中的平均梯度幅度。

技术1:
- 创建仅显示区域A的投资回报率Mat。因此90的尺寸为50。{ - 执行cv::Sobel()cv::magnitude()然后cv::meanStdDev()执行 - 我的平均梯度幅度结果为11.34

技术2:
- 创建一个新的Mat作为掩码。垫子与图像A的尺寸相同,并且区域A具有白色区域。然后创建一个新的Mat,它只显示图像A的区域和Mat的其余部分是黑色的 - 希望这是有道理的 - 执行cv::Sobel()cv::magnitude()(但使用掩码)然后cv::meanStdDev()
- 我的平均梯度幅度结果为43.76

为什么会有不同的结果?

以下是我的代码:

static Mat backupSrc;
static Mat curSrc;

// Technique 1
void inspectRegion(const Point& strt, const Point& end) {

    curSrc = Mat(backupSrc.size(), CV_8UC3);
    cvtColor(backupSrc, curSrc, CV_GRAY2RGB);

    Rect region = Rect(strt, end);
    Mat regionImg = Mat(curSrc, region);

    // Calculate the average gradient magnitude/strength across the image
    Mat dX, dY, mag;
    Sobel(regionImg, dX, CV_32F, 1, 0);
    Sobel(regionImg, dY, CV_32F, 0, 1);
    magnitude(dX, dY, mag);

    Scalar sMMean, sMStdDev;
    meanStdDev(mag, sMMean, sMStdDev);
    double magnitudeMean = sMMean[0];
    double magnitudeStdDev = sMStdDev[0];

    rectangle(curSrc, region, { 0 }, 1);

    printf("[Gradient Magnitude Mean: %.3f, Gradient Magnitude Std Dev: %.3f]\n", magnitudeMean, magnitudeStdDev);
}

// Technique 2
void inspectRegion(const std::vector<Point>& pnts) {

    curSrc = Mat(backupSrc.size(), CV_8UC3);
    cvtColor(backupSrc, curSrc, CV_GRAY2RGB);

    std::vector<std::vector<Point>> cPnts;
    cPnts.push_back(pnts);

    Mat mask = Mat::zeros(curSrc.rows, curSrc.cols, CV_8UC1);
    fillPoly(mask, cPnts, { 255 });
    Mat regionImg;
    curSrc.copyTo(regionImg, mask);


    // Calculate the average gradient magnitude/strength across the image
    Mat dX, dY, mag;
    Sobel(regionImg, dX, CV_32F, 1, 0);
    Sobel(regionImg, dY, CV_32F, 0, 1);
    magnitude(dX, dY, mag);

    Scalar sMMean, sMStdDev;
    meanStdDev(mag, sMMean, sMStdDev, mask);
    double magnitudeMean = sMMean[0];
    double magnitudeStdDev = sMStdDev[0];

    polylines(curSrc, pnts, true, { 255 }, 3);

    printf("[Gradient Magnitude Mean: %.3f, Gradient Magnitude Std Dev: %.3f]\n", magnitudeMean, magnitudeStdDev);
}

1 个答案:

答案 0 :(得分:1)

在技术2中,矩形边界周围的渐变会非常高,会破坏计算。

在计算渐变之前,请考虑扩大遮罩,以便此尖峰位于您发送到meanStdDev函数的非扩张遮罩之外。