(一)预备知识
一、滤波、核和卷积
滤波器:指的是一种由一幅图像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
);