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++ 不应该';高斯模糊是对称的吗?_C++_Opencv_Gaussian - Fatal编程技术网

C++ 不应该';高斯模糊是对称的吗?

C++ 不应该';高斯模糊是对称的吗?,c++,opencv,gaussian,C++,Opencv,Gaussian,我期望高斯模糊操作是对称的,但是使用OpenCV 2.4.11GaussianBlur我得到了不同 这里有一个例子。我将一个GaussianBlur应用于图像和图像的翻转版本。我已经分别验证了flip操作不会更改图像像素值(未显示)。当我将模糊图像翻转回去时,我希望它与原始图像的模糊相同,但是diff显示了许多小差异(0.0和6.10351562E-005之间)。我知道这很小,但在我的后续处理中会产生连锁反应 高斯核是对称的,所以结果应该是相同的。这仅仅是实现中的舍入错误吗 int main(i

我期望高斯模糊操作是对称的,但是使用OpenCV 2.4.11
GaussianBlur
我得到了不同

这里有一个例子。我将一个
GaussianBlur
应用于图像和图像的翻转版本。我已经分别验证了
flip
操作不会更改图像像素值(未显示)。当我将模糊图像翻转回去时,我希望它与原始图像的模糊相同,但是
diff
显示了许多小差异(0.0和6.10351562E-005之间)。我知道这很小,但在我的后续处理中会产生连锁反应

高斯核是对称的,所以结果应该是相同的。这仅仅是实现中的舍入错误吗

int main(int, char **)
{
    // e.g. 2008_005541.jpg from VOC2012 dataset
    char const * const filename = "...";
    float const sig_diff = 1.24899971f;

    cv::Mat image = cv::imread(filename, cv::IMREAD_GRAYSCALE);
    cv::Mat gray_fpt;
    image.convertTo(gray_fpt, cv::DataType<float>::type, 1, 0);
    GaussianBlur(gray_fpt, gray_fpt, cv::Size(), sig_diff, sig_diff);

    cv::Mat mirror;
    flip(image, mirror, 1);
    cv::Mat mirror_gray_fpt;
    mirror.convertTo(mirror_gray_fpt, cv::DataType<float>::type, 1, 0);
    GaussianBlur(mirror_gray_fpt, mirror_gray_fpt, cv::Size(), sig_diff, sig_diff);

    flip(mirror_gray_fpt, mirror_gray_fpt, 1);
    cv::Mat diff = abs(gray_fpt - mirror_gray_fpt);
    double minval, maxval;
    minMaxLoc(diff, &minval, &maxval);

    // minval = 0.0;
    // maxval = 6.103515625e-005;

    // easier to visualise the differences with this:
    normalize(diff, diff, 0.0, 1.0, cv::NORM_MINMAX, CV_32FC1);
    return 0;
}
int main(int,char**)
{
//例如,来自VOC2012数据集的2008_005541.jpg
char const*const filename=“…”;
浮动常数sig_diff=1.2489971f;
cv::Mat image=cv::imread(文件名,cv::imread\U灰度);
cv::Mat gray_fpt;
convertTo(gray_fpt,cv::DataType::type,1,0);
GaussianBlur(gray_fpt,gray_fpt,cv::Size(),sig_diff,sig_diff);
cv::垫镜;
翻转(图像,镜像,1);
cv::Mat mirror\u gray\u fpt;
convertTo(mirror\u gray\u fpt,cv::DataType::type,1,0);
高斯模糊(镜像灰度fpt,镜像灰度fpt,cv::Size(),sig_diff,sig_diff);
翻转(镜像灰色fpt,镜像灰色fpt,1);
cv::Mat diff=abs(灰色fpt-镜面灰色fpt);
双最小值,最大值;
minMaxLoc(差异、最小值和最大值);
//minval=0.0;
//maxval=6.103515625e-005;
//通过以下方式更容易看出差异:
标准化(差异,差异,0.0,1.0,cv::NORM_MINMAX,cv_32FC1);
返回0;
}

编辑:我将类型从
cv::DataType::type
更改为
cv::DataType::type
,现在最大错误为1.1368683772161603e-013,因此舍入似乎是个问题。

将上面的代码更改为调用
高斯模糊
(下面)GaussianBlur在我到目前为止测试的示例图像中没有产生任何差异

由此可知,如果高斯运算的工作类型为
double
precision,则
float
ing point precision中的输出不会产生错误。这似乎是解决我问题的好办法

// Perform gaussian blur in double precision and convert back
void gaussian_blur(
    cv::Mat const &src, cv::Mat &dst,
    cv::Size ksize, double sigmaX, double sigmaY=0,
    int borderType=cv::BORDER_DEFAULT)
{
    cv::Mat src_dp;
    src.convertTo(src_dp, cv::DataType<double>::type, SIFT_FIXPT_SCALE, 0);

    cv::Mat dst_dp;
    GaussianBlur(src_dp, dst_dp, ksize, sigmaX, sigmaY, borderType);

    dst_dp.convertTo(dst, src.type(), SIFT_FIXPT_SCALE, 0);
}
//以双精度执行高斯模糊并转换回
空洞高斯模糊(
cv::材料常数和src,cv::材料和dst,
cv::大小ksize,双sigmaX,双sigmaY=0,
int borderType=cv::BORDER(默认值)
{
cv::Mat src_dp;
convertTo(src\u dp,cv::DataType::type,SIFT\u FIXPT\u SCALE,0);
cv::Mat dst_dp;
GaussianBlur(src_dp、dst_dp、ksize、sigmaX、sigmaY、borderType);
dst_dp.convertTo(dst,src.type(),SIFT_FIXPT_SCALE,0);
}

我假设它也是四舍五入的,但OpenCV专家还不足以证实这一点。但是,如果需要对称操作,那么复制图像、翻转、模糊、反向翻转以及直接模糊图像的平均值如何?当然,您可能需要检查两个方向的翻转。这是我的流程中的一小步,我不知道图像的方向,因此无法确定是否翻转。但不管水平方向如何,我都想要相同的值。6.103515625e-005非常接近floats@cdmh始终翻转并平均两个结果。不管然而,请注意,所有浮点步骤都会像这样累积“错误”:您通常需要处理这种可能性。