2017-01-30 303 views
2

我注意到C++中filter2D的OpenCV实现与相应内核的直接实现之间的差异。我已阅读了以下问题:filter2D OpenCV函数C++

Opencv - how does the filter2D() method actually work?

这个问题,笔者曾试图让filter2D功能的工作落实。他声称使用规范化版本的过滤器会产生正确的结果。我测试了他的假设,发现只有当所有系数都是正数时,归一化才能给出正确的答案。因此,使用filter2D函数可以成功实现平均滤波器[我们必须对内核进行规格化]。

但是,对于具有负系数的滤波器,例如Sobel,Laplacian和任何边缘检测滤波器,情况并非如此。这个问题的作者遇到了和我一样的问题。

https://stackoverflow.com/users/2669614/bovaz

上面提到的用户回答的链接的问题。他声称,如果内核的系数总和等于零,filter2D可能会修改它的实现。是这样吗?为什么在C +中实现filter2D会给直接实现带来不同的结果?我已经在Python中检查了filter2D,并且直接在C++中实现相应的内核,结果相同。

回答

0

这主要是因为缩放和溢出问题。 filter2D的文档没有提及(至少我没有找到)溢出值是否被剪切或适当缩放到最小 - 最大范围。 这对于方向滤波器更为重要,其中系数为正数和负数,代数后 上面的链接中显示的函数'myfilter2D'没有缩放到最小最大范围,应该是这种情况。

如果您可以发布示例代码,那么它会更容易帮助。

我的建议是将矩阵转换为浮点数(并进行缩放)并执行代数运算,因为这往往会保留结果值并且值不会由于溢出或饱和而丢失。 im2double() - >“执行代数运算” - > im2uchar()用于显示

void im2uchar(Mat & src, Mat & dest){ 
    double minVal, maxVal; 
    minMaxLoc(src, &minVal, &maxVal); //find minimum and maximum intensities 
    src.convertTo(dest, CV_8U, 255.0/(maxVal - minVal), -minVal * 255.0/(maxVal - minVal)); 
    } 

void im2float(Mat & src, Mat & dest){ 
    double minVal, maxVal; 
    minMaxLoc(src, &minVal, &maxVal); //find minimum and maximum intensities 
    src.convertTo(dest, CV_32F, 1.0/(maxVal - minVal), -minVal * 1.0/(maxVal - minVal)); 
    }