Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 计算平均值:遮罩图像与ROI的不同结果_C++_Opencv - Fatal编程技术网

C++ 计算平均值:遮罩图像与ROI的不同结果

C++ 计算平均值:遮罩图像与ROI的不同结果,c++,opencv,C++,Opencv,我有一个奇怪的问题,我的平均梯度大小结果是不同的,如果我使用一个面具,而不是创建一个新的垫的小投资回报率。我将解释我做这件事的两种不同方式,以及我得到的两种不同的平均梯度大小结果。我想我应该得到相同的平均梯度大小结果 场景:图像A是我的风景源/原始图像。我想得到区域A(10100)、(100100)、(100150)、(10150)中的平均梯度大小 技术1: -创建一个仅显示区域a的ROIMat。因此它的维度是90by50 -执行cv::Sobel(),cv::magnity()然后执行cv::

我有一个奇怪的问题,我的平均梯度大小结果是不同的,如果我使用一个面具,而不是创建一个新的垫的小投资回报率。我将解释我做这件事的两种不同方式,以及我得到的两种不同的平均梯度大小结果。我想我应该得到相同的平均梯度大小结果

场景:图像A是我的风景源/原始图像。我想得到区域A
(10100)、(100100)、(100150)、(10150)
中的平均梯度大小

技术1:
-创建一个仅显示区域a的ROI
Mat
。因此它的维度是
90
by
50

-执行
cv::Sobel()
cv::magnity()
然后执行
cv::meanstdev()

-我的平均梯度大小结果是
11.34

技术2:
-创建一个新的
Mat
,它是一个掩码。垫子的尺寸与图像A相同,并且在区域A所在的位置有一个白色区域。然后创建一个新的垫子,仅显示图像a的区域和垫子的其余部分为黑色-希望这有意义。
-执行
cv::Sobel()
cv::magnity()
(但使用掩码),然后执行
cv::meanstdev()

-我的平均梯度大小结果是
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);
}
static Mat backupSrc;
静态钢筋混凝土;
//技术1
无效检查区域(常数点和strt、常数点和端点){
curSrc=Mat(backupSrc.size(),CV_8UC3);
CVT颜色(backupSrc、curSrc、CV_GRAY2RGB);
Rect区域=Rect(strt,end);
Mat regionImg=Mat(curSrc,region);
//计算整个图像的平均梯度大小/强度
Mat-dX,dY,mag;
Sobel(regionImg,dX,CV_32F,1,0);
Sobel(regionImg,dY,CV_32F,0,1);
震级(dX、dY、mag);
标量sMMean,sMStdDev;
平均值(mag、sMMean、sMStdDev);
双震级平均值=sMMean[0];
双震级stddev=sMStdDev[0];
矩形(curSrc,区域,{0},1);
printf(“[梯度震级平均值:%.3f,梯度震级标准偏差:%.3f]\n”,震级平均值,震级标准差);
}
//技术2
无效检查区域(常量标准::向量和PNT){
curSrc=Mat(backupSrc.size(),CV_8UC3);
CVT颜色(backupSrc、curSrc、CV_GRAY2RGB);
std::载体cPnts;
cPnts。推回(pnts);
Mat mask=Mat::零(curSrc.rows、curSrc.cols、CV_8UC1);
fillPoly(掩码,cPnts,{255});
matregionimg;
curSrc.copyTo(regionImg,mask);
//计算整个图像的平均梯度大小/强度
Mat-dX,dY,mag;
Sobel(regionImg,dX,CV_32F,1,0);
Sobel(regionImg,dY,CV_32F,0,1);
震级(dX、dY、mag);
标量sMMean,sMStdDev;
平均数据差(mag、sMMean、SMSTDEV、mask);
双震级平均值=sMMean[0];
双震级stddev=sMStdDev[0];
多段线(curSrc,pnts,true,{255},3);
printf(“[梯度震级平均值:%.3f,梯度震级标准偏差:%.3f]\n”,震级平均值,震级标准差);
}

在技巧2中,矩形边界周围的梯度将非常高,并会破坏计算


在计算梯度之前,请考虑扩展遮罩,使此峰值位于发送到
meanStdDev
函数的未扩展遮罩之外。

我认为您的遮罩应为CV_8UC3类型,即
Mat mask=Mat::Zero(curSrc.rows,curSrc.cols,CV_8UC3)。也许它只是复制了一个通道,谢谢:)扩大遮罩会使两个结果稍微接近,但侵蚀桅杆会使它们更接近-技术2现在给出11.97。是否有任何方法可以使此完全准确(与技术1相同)?为了清楚起见,您需要在调用
copyTo
之前放大遮罩。然后在调用
meanstdev
之前,应该将其腐蚀回原来的大小。你想做什么?谢谢:)我会试着把它放大。我试图做的是计算多边形中的平均梯度大小(多边形在航空图像中勾勒出公路车道)。在我上面的例子中,多边形是一个简单的矩形,但实际上它们是复杂的多边形。多边形是通过遮罩实现的,也就是说,除多边形内部外,大部分网格都是黑色外,网格与原始航空图像是相同的图像。因此,您希望第二种方法起作用。首先,没有理由将遮罩外的区域归零。不要调用
copyTo
。您正在
meanstdev
中使用掩码。够了。