我正在尝试使用ROI
和Gaussian filter
软件模糊图像中的imageJ
。
我在blur radius as 9
中使用imageJ
获得了期望的结果。
现在,我试图编写相应的OpenCV C++ application
来执行与imageJ
相同的操作。Gaussian Blur
中的openCV
签名如下:C++: void GaussianBlur(InputArray src, OutputArray dst, Size ksize, double sigmaX, double sigmaY=0, int borderType=BORDER_DEFAULT )
什么是sigmaX
和sigmaY
对应的ImageJ blur radius of 9
和OpenCV
?
我尝试了许多资源,例如:
Blur Radius
但是我使用ojit_code并没有得到相同的结果。
最佳答案
您能否详细说明结果如何“不同”?
ImageJ中的模糊半径定义为““半径”是指衰减到exp(-0.5)〜61%的半径,即高斯的标准偏差sigma”(来自ImageJ文档:https://imagej.nih.gov/ij/developer/api/ij/plugin/filter/GaussianBlur.html#GaussianBlur--)
我认为没有理由不应该在OpenCV中以相同的方式实现它。
但是,我也观察到ImageJ和OpenCV高斯模糊之间的这些差异。
虽然目前我还没有解决方案可以使它们完全相同,但是我设法使它们更接近,并且可以在实现中看到一个潜在的区别和一个肯定的区别:
内核大小(电位差):
您是否知道内核大小和高斯半径是两件事?内核大小是应用于图像的内核大小(3 * 3、5 * 5等),但是在该内核内部理论上可以存在任何半径的高斯。但是,通常选择内核大小,以便在内核边界上,高斯函数已衰减到大约零。
话虽如此,ImageJ会根据您选择的半径自动为您选择内核,以实现“边界上的高斯衰减到零”的条件。如果将sigma设置为所需的半径并将ksize设置为零,则OpenCV函数也会执行此操作。问题是“他们俩都以同样的方式做吗?”。
ImageJ的实现比您想象的要棘手:“在ImageJ中,实际使用的内核大小取决于精度。
需要:对于sigma = 1,对于16位和浮点图像,内核为9像素
宽(对于2D图像给出9x9),但是对于8位或RGB图像则为
仅7像素宽,因为如果需要,则不需要非常高的精度
只有256个不同的值。对于较大的sigma值,情况更为复杂:对于sigma> = 8,首先对数据进行缩减,然后应用高斯模糊,然后使用插值法将其缩放至原始数据点数。降级和插值算法是专为实现最佳精度而专门设计的。”等(来自“ImageJ论坛”,由于我没有足够的声誉,因此我无法发布链接,但是如果您想要资源)
我不知道OpenCV是否执行了此类操作,或者它对内核大小的计算方式是否不同,从而得出不同的结果。 (在Google中找不到)。
边界(肯定有差异):您可能知道,高斯滤镜会遍历图像中的每个像素,并根据其相邻像素为该像素计算一个新值。但是,高斯核宽于距图像边界的距离的边界附近的像素又如何呢?算法如何处理?通过仔细检查我的图像,我发现OCV实现和IJ实现之间的主要区别在于边界像素。
好吧,事实证明ImageJ和OpenCV处理这些像素的方式有所不同:
ImageJ gaussian,“与ImageJ中的所有卷积运算一样,它假定图像外像素的值等于最近的边缘像素。” (来自与以上相同的ImageJ文档)。
但是,OpenCV允许您选择其他选项,并且在OpenCV调用中,默认选项称为BORDER_DEFAULT
,是BORDER_REFLECT_101
(http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_core/py_basic_ops/py_basic_ops.html)(至少我认为是,这是使用边框的另一种方法的默认边框,所以我认为它是也是高斯的默认边框)。 BORDER_REFLECT_101
类似于“镜像”边界(gfedcb | abcdefgh,请参阅链接)。
要更接近ImageJ(aaaaaaaa | abcdefgh),请使用BORDER_DEFAULT=BORDER_REPLICATE
。有了这个,我在两个实现之间得到了更接近的结果(尽管不完全相同,如果发现更多的线索,我将继续研究和编辑答案)。
[注意:我正在Python2.7(不是C++)和OpenCV 3中工作,但我认为这不会对这个问题产生影响]
关于opencv - imageJ模糊半径与OpenCV高斯模糊sigma之间的关系,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/40254033/