小记:静默处之,安之若素
1. opencv中膨胀和腐蚀
膨胀和腐蚀是图像形态学的最基础变换方式,在消除噪声,元素分割和连接等方面都有应用。
- 膨胀
膨胀是一种卷积操作,它将目标像素的值替换为卷积核覆盖区域的局部最大值,也可以说是“最大化”操作,使明亮区域扩张并联通。
opencv函数定义:
void cv::dilate(
cv::InputArray src,//Input image
cv::OutputArray dst, //result image
cv::InputArray element, // Structuring, a cv::Mat()
cv::Point anchor = cv::Point(-1, -1), //Location of anchor point
int iterations = 1, //Number of times to apply
int borderType = cv::BORDER_CONSTANT //Border extrapolation
const cv::Scalar& borderValue = cv::morphologyDefaultBorderValue()
)
示例程序
1 #include <opencv2/opencv.hpp>
2 #include <iostream>
3 #include <math.h>
4 using namespace std;
5 using namespace cv;
6
7 int main(int argc, char *argv[])
8 {
9 cv::Mat dresult, eresult;
10 cv::Mat src = cv::imread("1.png");
11 cv::imshow("input", src);
12 cv::Mat src1 = src.clone();
15 Mat se = getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1));
16 dilate(src1, dresult, se, Point(-1, -1), 1, 0);
19 cv::Mat orgin2dilate;
20 cv::hconcat(src, dresult, orgin2dilate);
21 imshow("dilate", orgin2dilate);
26 cv::waitKey(0);
27 return 0;
28
29 }
~
运行结果:
2. 腐蚀
腐蚀操作是与膨胀操作相反,腐蚀操作计算的是核覆盖范围内的局部最小值,准确的说是将目标图像中的值设为核覆盖范围内的最小值。腐蚀还可以说是“最小化”操作:即明亮的区域被隔离并收缩。
opencv函数定义:
void cv::enrode(
cv::InputArray src,//Input image
cv::OutputArray dst, //result image
cv::InputArray element, // Structuring, a cv::Mat()
cv::Point anchor = cv::Point(-1, -1), //Location of anchor point
int iterations = 1, //Number of times to apply
int borderType = cv::BORDER_CONSTANT //Border extrapolation
const cv::Scalar& borderValue = cv::morphologyDefaultBorderValue()
)
示例程序
1 #include <opencv2/opencv.hpp>
2 #include <iostream>
3 #include <math.h>
4 using namespace std;
5 using namespace cv;
6
7 int main(int argc, char *argv[])
8 {
9 cv::Mat dresult, eresult;
10 cv::Mat src = cv::imread("1.png");
11 cv::imshow("input", src);
13 cv::Mat src2 = src.clone();
15 Mat se = getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1));
17 erode(src2, eresult, se, Point(-1, -1), 1, 0);
23 cv::Mat origin2erode;
24 cv::hconcat(src, eresult, origin2erode);
25 imshow("erode", origin2erode);
26 cv::waitKey(0);
27 return 0;
28
29 }
运行结果:
3. 总结
1)膨胀就是扩张了明亮区域,腐蚀缩减了明亮区域;
2)膨胀填充凹面,腐蚀消除凸起。
详细介绍
2. 开操作和闭操作
开操作和闭操作实际上是腐蚀和膨胀操作非常简单的结合。
- 开操作
开操作就是先将图像腐蚀,然后对腐蚀结果进行膨胀。其常作用于对二值图像中的区域进行计数。
eg:
在对显微镜载玻片中的细胞进行计数时,需要采用开操作将相互靠的很近的细胞分开。 - 闭操作
闭操作是先将图像进行膨胀,然后对膨胀的结果进行腐蚀。其常作用于复杂连通分支算法中减少无用或噪声驱动的片段。 - opencv中函数原型:
opencv中可以采用cv::morphologyEx()函数来对图像进行开操作和闭操作处理。在调用该函数时需要通过改变区中op参数来实现开操作和闭操作的使用,后续介绍的顶帽和底帽操作也通过该函数来实现。
void cv::morphologyEx
(
InputArray src,//Input image
OutputArray dst,//Result image
int op,//Operator(eg: cv::MOP_OPEN(开操作))
InputArray kernel,//Structuring element.
Point anchor = Point(-1,-1),//Anchor position with the kernel.
int iterations = 1,//
int borderType = BORDER_CONSTANT,//Number of times erosion and dilation are applied.
const Scalar & borderValue = morphologyDefaultBorderValue() //Border value in case of a constant border.
)
op说明:
| 操作符 | 形态学操作 |
|cv::MOP_OPEN | 开操作 |
|cv::MOP_CLOSE | 闭操作 |
|cv::MOP_GRADIENT| 形态学操作 |
|cv::MOP_TOPHAT | 顶帽操作 |
|cv::MOP_BLACKHAT| 底帽操作 |
- 示例程序
1 #include <opencv2/opencv.hpp>
2 #include <iostream>
3 #include <math.h>
4 using namespace std;
5 using namespace cv;
6
7 int main(int argc, char *argv[])
8 {
9 cv::Mat Op_result, Cl_result;
10 cv::Mat src = cv::imread("opencv_logo.jpg");
11 cv::imshow("input", src);
12 cv::Mat src1 = src.clone();
13 cv::Mat src2 = src.clone();
14
15 cv::Mat gray1, gray2;
16 cv::Mat binary1, binary2;
17 Mat se = getStructuringElement(MORPH_RECT, Size(5, 5), Point(-1, -1));//kernel
18
19 //开操作
20 cv::cvtColor(src1, gray1, cv::COLOR_BGR2GRAY);
21 GaussianBlur(gray1, gray1, Size(9, 9), 0, 0);
22 adaptiveThreshold(gray1, binary1, 255, ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY_INV, 45, 15);
23 imshow("binary1", binary1);
24 cv::cvtColor(src2, gray2, cv::COLOR_BGR2GRAY);
25
26 cv::morphologyEx(gray1, Op_result, cv::MORPH_OPEN, se);
27 imshow("Open", Op_result);
28
29 //闭操作
30 cv::cvtColor(src2, gray2, cv::COLOR_BGR2GRAY);
31 GaussianBlur(gray2, gray2, Size(9, 9), 0, 0);
32 adaptiveThreshold(gray2, binary2, 255, ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY_INV, 45, 15);
33 imshow("binary2", binary2);
34
35 cv::morphologyEx(gray2, Cl_result, cv::MORPH_CLOSE, se);
36 imshow("Close", Cl_result);
37 cv::waitKey(0);
38 return 0;
39
40 }
- 总结
1)闭操作最明显的效果就是消除值小于领域内的点的孤立异常值;
2)开操作就是消除大于领域内点的孤立值。
3.顶帽和底帽
顶帽操作和顶帽操作分别用于显示与其领域相比更亮或更暗的部分,当试图根据物体的亮度变化分离依附于物体的某些部分时,就会用到这些方法
- 顶帽操作就是用源图像减去其开操作后的结果
- 底帽操作就是用闭操作减去其源图像的结果
- 程序示例
1 #include <opencv2/opencv.hpp>
2 #include <iostream>
3 #include <math.h>
4 using namespace std;
5 using namespace cv;
6
7 int main(int argc, char *argv[])
8 {
9 cv::Mat Op_result, Cl_result;
10 cv::Mat src = cv::imread("1.png");
11 cv::imshow("input", src);
12 cv::Mat src1 = src.clone();
13 cv::Mat src2 = src.clone();
14
15 cv::Mat gray1, gray2;
16 cv::Mat binary1, binary2;
17 Mat se = getStructuringElement(MORPH_RECT, Size(5, 5), Point(-1, -1));//kernel
18
19 //顶帽操作
20 cv::cvtColor(src1, gray1, cv::COLOR_BGR2GRAY);
21 cv::threshold(gray1, binary1, 0, 255, cv::THRESH_BINARY | cv::THRESH_OTSU);
22 imshow("binary1", binary1);
23 cv::cvtColor(src2, gray2, cv::COLOR_BGR2GRAY);
24
25 cv::morphologyEx(gray1, Op_result, cv::MORPH_TOPHAT, se);
26 imshow("TOPHAT", Op_result);
27
28 //底帽操作
29 cv::cvtColor(src2, gray2, cv::COLOR_BGR2GRAY);
30 GaussianBlur(gray2, gray2, Size(9, 9), 0, 0);
31 adaptiveThreshold(gray2, binary2, 255, ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY_INV, 45, 15);
32 imshow("binary2", binary2);
33
34 cv::morphologyEx(gray2, Cl_result, cv::MORPH_BLACKHAT, se);
35 imshow("BLACKHAT", Cl_result);
36 cv::waitKey(0);
37 return 0;
38
39 }