C++ 不应该';高斯模糊是对称的吗?
我期望高斯模糊操作是对称的,但是使用OpenCV 2.4.11C++ 不应该';高斯模糊是对称的吗?,c++,opencv,gaussian,C++,Opencv,Gaussian,我期望高斯模糊操作是对称的,但是使用OpenCV 2.4.11GaussianBlur我得到了不同 这里有一个例子。我将一个GaussianBlur应用于图像和图像的翻转版本。我已经分别验证了flip操作不会更改图像像素值(未显示)。当我将模糊图像翻转回去时,我希望它与原始图像的模糊相同,但是diff显示了许多小差异(0.0和6.10351562E-005之间)。我知道这很小,但在我的后续处理中会产生连锁反应 高斯核是对称的,所以结果应该是相同的。这仅仅是实现中的舍入错误吗 int main(i
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始终翻转并平均两个结果。不管然而,请注意,所有浮点步骤都会像这样累积“错误”:您通常需要处理这种可能性。