::返回OpenCV算子速查表
OpenCV getStructuringElement
- 1. 函数
- 1.1 getStructuringElement
- 1.2 morphologyEx
- 1.3 erode
- 1.4 dilate
- 2. 例程
- 2.1 图像处理效果
- 原图
- 二值化图像
- 对二值化图像进行腐蚀、膨胀、开操作、闭操作
- 梯度图
- 顶帽和黑帽
- 击中击不中
- 2.2 代码
1. 函数
1.1 getStructuringElement
OpenCV官方文档getStructuringElement链接
- getStructuringElement 是为了给形态学操作算子返回指定大小和形状的结构元素。
- 当然你也可以自己构造一个任意的二进制掩码,并将其用作形态学处理函数的结构元素。
Mat getStructuringElement(
int shape, //形状
Size ksize, //尺寸
Point anchor = Point(-1, -1) //锚点
);
- 参数 shape 是枚举变量 enum cv::MorphShapes
1.2 morphologyEx
OpenCV官方文档morphologyEx链接
- 这其实是一个非常强大的函数,它可以通过调整参数 op 完成八种操作:腐蚀、膨胀、开运算、闭运算、顶帽、黑帽、梯度、击中击不中。
void morphologyEx(
InputArray src,
OutputArray dst,
int op,
InputArray kernel,
Point anchor = Point(-1, -1),
int iterations = 1,
int borderType = BORDER_CONSTANT,
const Scalar& borderValue = morphologyDefaultBorderValue()
);
- 参数 op 是枚举变量 enum cv::MorphTypes
- 对于腐蚀和膨胀,OpenCV还有专门的函数 erode 和 dialte,它们和 morphologyEx 使用 MORPH_ERODE 或 MORPH_DILATE 是完全相同的。
- 所有操作都支持就地调用。对于多通道图像,每个通道是被独立处理的。
- borderType :不支持BORDER_WRAP
- 《学习OpenCV3》有这样的描述:尽管开和闭操作的效果与腐蚀相近,但这些新操作在保持连通域的精度上更加可靠。
1.3 erode
void erode(
InputArray src,
OutputArray dst,
InputArray kernel,
Point anchor = Point(-1, -1),
int iterations = 1,
int borderType = BORDER_CONSTANT,
const Scalar& borderValue = morphologyDefaultBorderValue()
);
1.4 dilate
void dilate(
InputArray src,
OutputArray dst,
InputArray kernel,
Point anchor = Point(-1, -1),
int iterations = 1,
int borderType = BORDER_CONSTANT,
const Scalar& borderValue = morphologyDefaultBorderValue()
);
2. 例程
2.1 图像处理效果
原图
二值化图像
对二值化图像进行腐蚀、膨胀、开操作、闭操作
- 开操作和闭操作实际上就是腐蚀和膨胀的简单组合。
- 开操作是先腐蚀后膨胀,常用于对二值图像中的区域进行计数。
- 闭操作是先膨胀后腐蚀,作用于复杂连通分支算法中减少无用或噪声驱动的片段。对于连通分支,通常先进行腐蚀或闭操作消除噪声,然后通过开操作连接相互靠近的大型区域。
- 尽管开和闭操作的效果与腐蚀相近,但这些新操作在保持连通域的精度上更加可靠。
梯度图
- 形态学梯度 是 膨胀操作的结果(扩张亮域)减 腐蚀操作的结果(缩减亮域) ,这就是边缘。
- 对于灰度图,其结果就是计算明暗变换的趋势。形态学梯度通常用于显示明亮区域的边界,然后便可以将他们看做目标或者目标的部分。用扩张的图像减去了收缩的图像,如此一来就找出了完整的边界。这与计算梯度不同,它不会关注某一个物体的周围。
顶帽和黑帽
- 这两种操作分别用于显示与其邻域相比更亮或更暗的部分。当试图根据物体的亮度变化分离依附于物体的某些部分时,就会用到这些方法。
- 顶帽作用源图像减去其开操作后的图像。开操作的效果是放大裂缝和局部小洞。因此用源图像减去开操作后的图像得到了比源图像更亮的环绕部分。
- 黑帽操作显示的是比源图像更暗的环绕部分。
击中击不中
2.2 代码
#include "stdafx.h"
#include <opencv.hpp>
using namespace cv;
int main()
{
Mat m_SrcImg = imread("./1.jpg", IMREAD_GRAYSCALE);
imshow("原图", m_SrcImg);
//阈值化操作
Mat m_SrcImg2;
threshold(m_SrcImg, m_SrcImg2, 100, 255, THRESH_BINARY_INV);
imshow("原图2", m_SrcImg2);
Mat m_DstImg;
Mat elementRect = getStructuringElement(MORPH_RECT, Size(5, 5), Point(-1, -1));
Mat elementEllipse = getStructuringElement(MORPH_ELLIPSE, Size(5, 5), Point(-1, -1));
int m_nIterations = 1;
//腐蚀
morphologyEx(m_SrcImg2, m_DstImg, MORPH_ERODE, elementEllipse, Point(-1, -1), m_nIterations);
imshow("MORPH_ERODE", m_DstImg);
//膨胀
morphologyEx(m_SrcImg2, m_DstImg, MORPH_DILATE, elementEllipse, Point(-1, -1), m_nIterations);
imshow("MORPH_DILATE", m_DstImg);
//开操作
morphologyEx(m_SrcImg2, m_DstImg, MORPH_OPEN, elementEllipse, Point(-1, -1), m_nIterations);
imshow("MORPH_OPEN", m_DstImg);
//闭操作
morphologyEx(m_SrcImg2, m_DstImg, MORPH_CLOSE, elementEllipse, Point(-1, -1), m_nIterations);
imshow("MORPH_CLOSE", m_DstImg);
//梯度 如果是空的Mat,则会被默认为是3×3的核
morphologyEx(m_SrcImg2, m_DstImg, MORPH_GRADIENT, Mat(), Point(-1, -1), m_nIterations);
imshow("MORPH_GRADIENT", m_DstImg);
//顶帽 这里我使用了一个Mat的构造函数,自行创建了掩码,同样也可以作为形态学操作函数的结构化元素来使用
morphologyEx(m_SrcImg, m_DstImg, MORPH_TOPHAT, Mat(Size(11, 11), m_SrcImg.type()), Point(-1, -1), m_nIterations);
imshow("MORPH_TOPHAT", m_DstImg);
//黑帽
morphologyEx(m_SrcImg, m_DstImg, MORPH_BLACKHAT, Mat(Size(11, 11), m_SrcImg.type()), Point(-1, -1), m_nIterations);
imshow("MORPH_BLACKHAT", m_DstImg);
//击中击不中
morphologyEx(m_SrcImg2, m_DstImg, MORPH_HITMISS, elementEllipse, Point(-1, -1), 1);
imshow("MORPH_HITMISS", m_DstImg);
waitKey(0);
return 0;
}