第十章 滤波与卷积

(一)预备知识

一、滤波、核和卷积

滤波器:指的是一种由一幅图像I(x,y)根据像素点x,y附近的区域计算得到一副新图像I‘(x,y)的算法。其中,模板规定了滤波器的形状以及这个区域内像素点值的组成规律,也称“滤波器”或者“核”。本章多为线性滤波器(核)。

二、边界外推核边界处理

OpenCV采用的一种方法是在源图像周围添加虚拟像素。方法:

1、自定义边框:

void cv::copyMakeBorder( 
    const Mat&    src, 
    Mat&          dst,
    int           top, 
    int           bottom, 
    int           left, 
    int           right,
    int           borderType, 
    const cv::Scalar& value = cv::Scalar() 
);

2、自定义外推:

int cv::borderInterpolate(
    int p,
    int len,
    int borderType,
);

(二)阈值化操作

目的与作用:我们已经完成了图像的多层处理步骤并需要做出一个最终决定,或者将高于或低于某一值的像素置零同时其他的像素保持不变。

double cv::threshold(
    cv::InputArray    src,
    cv::OutputArray   dst,
    double            thresh,
    double            maxValue,
    int               thresholdType
);

1、Otsu算法:函数cv::threshold()也可以自动决定最优的阈值,你只需对参数thresh传递值cv::THRESH_OTSU即可。(遍历所有可能的阈值然后对每个阈值结果的两类像素计算方差,这并不是一个相对高效的过程)

2、自适应阈值:这种方法中阈值在整个过程中自动产生变化

void cv::adaptiveThreshold(
    cv::InputArray    src,
    cv::OutputArray   dst,
    double            maxValue,
    int               adaptiveMethod,
    int               thresholdType,
    int               blockSize,
    double            C,
);

(三)平滑

目的与作用:通常是为了减少噪声和伪影;在降低图像分辨率的时候平滑也是十分重要的。

五种不同的平滑操作:

1、简单模糊和方框型滤波器

void cv::blur(
    cv::InputArray    src,
    cv::OutputArray   dst,
    cv::Size          ksize,
    cv::Point         anchor = cv::Point(-1,-1),
    int               borderType = cv::BORDER_DEFAULT
);
void cv::boxFilter(
    cv::InputArray    src,
    cv::OutputArray   dst,
    int               ddepth,
    cv::Size          ksize,
    cv::Point         anchor = cv::Point(-1,-1),
    int               borderType = cv::BORDER_DEFAULT,
    bool              normalize = true,
);

2、中值滤波器

void cv::medianBlur(
    cv::InputArray    src,
    cv::OutputArray   dst,
    cv::Size          ksize,
);

3、高斯滤波器

void cv::GaussianBlur(
    cv::InputArray    src,
    cv::OutputArray   dst,
    cv::Size          ksize,
    double            sigmaX,
    double            sigmaY = 0.0,
    int               borderType = cv::BORDER_DEFAULT
);

4、双边滤波器

void cv::bilateralFilter(
    cv::InputArray    src,
    cv::OutputArray   dst,
    int               d,    //Pixel neighborhood size (max distance)
    double            sigmaColor,
    double            sigmaSpace,
    int               borderType = cv::BORDER_DEFAULT
);

(四)导数和梯度

1、索贝尔导数:用来表示微分的最常用的算子,其可以实现任意阶导数和混合偏导数。

void cv::Sobel(
    cv::InputArray    src,
    cv::OutputArray   dst,
    int               ddepth,
    int               xorder,
    int               yorder,
    cv::Size          ksize = 3,
    double            scale = 1,
    double            delta = 0,
    int               borderType = cv::BORDER_DEFAULT
);

2、Scharr滤波器:调用cv::Sobel()时设置ksize为cv::SCHARR,精度更高。

3、拉普拉斯变换:一种常见的应用就是匹配“斑点”

void cv::Laplacian(
    cv::InputArray    src,
    cv::OutputArray   dst,
    int               ddepth,
    cv::Size          ksize = 3,
    double            scale = 1,
    double            delta = 0,
    int               borderType = cv::BORDER_DEFAULT
);

(五)图像形态学

1、膨胀和腐蚀:它在消除噪声、元素分隔和连接等应用广泛;也可以用于更加复杂的形态学操作,用来定位强度峰值或孔洞、另一种形式的图像梯度等。

 

void cv::erode(
    cv::InputArray    src,
    cv::OutputArray   dst,
    cv::InputArray    element,
    cv::Point         anchor = cv::Point(-1,-1),
    int               interactions = 1,
    int               borderType = cv::BORDER_CONSTANT,
    const cv::Scalar& borderValue = cv::morphologyDefaultBorderValue()
);
void cv::dilate(
    cv::InputArray    src,
    cv::OutputArray   dst,
    cv::InputArray    element,
    cv::Point         anchor = cv::Point(-1,-1),
    int               interactions = 1,
    int               borderType = cv::BORDER_CONSTANT,
    const cv::Scalar& borderValue = cv::morphologyDefaultBorderValue()
);

2、通用形态学函数

void cv::morphologyEx(
    cv::InputArray    src,
    cv::OutputArray   dst,
    int               op,
    cv::InputArray    element,
    cv::Point         anchor = cv::Point(-1,-1),
    int               interactions = 1,
    int               borderType = cv::BORDER_CONSTANT,
    const cv::Scalar& borderValue = cv::morphologyDefaultBorderValue()
);

3、开操作和闭操作:开操作常用于对二值图像中的区域进行计数;闭操作用于复杂连通分支算法中减少无用或噪声驱动的片段。

cv::MOP_OPEN     开操作
cv::MOP_CLOSE    闭操作
cv::MOP_GRADIENT    形态学梯度
cv::MOP_TOPHAT      顶帽操作
cv::MOP_BLACKHAT    底帽操作

4、形态学梯度:形态学梯度通常用于显示明亮区域的边界,然后便可以将他们看作目标或者目标的部分。

5、顶帽和黑帽:分别用于显示与其领域相比更亮或更暗的部分。

6、自定义核

cv::Mat cv::getStructuringElement(
    int        shape,    //Element shap, e.g., cv::MORPH_RECT
    cv::Size   ksize,
    cv::Point  anchor = cv::Point(-1,-1)
);

(六)用任意线性滤波器做卷积

1、用cv::filter2D()做卷积

cv::filter2D(
    cv::InputArray    src,
    cv::OutputArray   dst,
    int               ddepth,
    cv::InputArray    kernel,
    cv::Point         anchor = cv::Point(-1,-1),
    double            delta = 0,
    int               borderType = cv::BORDER_DEFAULT
);

2、通过cv::sepFilter2D使用可分核

cv::sepFilter2D(
    cv::InputArray    src,
    cv::OutputArray   dst,
    int               ddepth,
    cv::InputArray    rowKernel,
    cv::InputArray    columnKernel,
    cv::Point         anchor = cv::Point(-1,-1),
    double            delta = 0,
    int               borderType = cv::BORDER_DEFAULT
);

3、生成卷积核

void cv::getDerivKernels(
    cv::OutputArray   kx,
    cv::OutputArray   ky,
    int               dx,
    int               dy,
    int               ksize,
    bool              normalize = true,
    int               ktype = CV_32F
);

 

你可能感兴趣的:(OpenCV)