简介
连通域
简介
结构元素
getStructuringElement()
函数用于生成常用的矩形结构元素、十字结构元素和椭圆结构元素Mat cv::getStructuringElement(shape, ksize)
shape:生成结构元素的种类,可以选择的参数及其含义如下
标志参数 | 简记 | 作用 |
---|---|---|
MORPH_RECT | 0 | 矩形结构元素,所有元素都为1 |
MORPH_CROSS | 1 | 十字结构元素,中间的列和行元素为1 |
MORPH_ELLIPSE | 2 | 椭圆结构元素,矩形的內接椭圆元素为1 |
ksize:结构元素的尺寸。一般情况下,当结构元素的种类相同时,结构元素的尺寸越大,腐蚀效果越明显
实现
OpenCV提供了用于图像腐蚀的erode()
函数
void cv::erode(src, dst, kernel, anchor, iterations)
getStructuringElement()
函数生成示例代码:
#include <opencv2/opencv.hpp> #include <iostream> using namespace std; using namespace cv; int main() { // 生成用于腐蚀的原图 Mat_<uchar> src = (Mat_<uchar>(6, 6) << 0, 0, 0, 0, 255, 0, 0, 255, 255, 255, 255, 255, 0, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0); Mat kernel; kernel = getStructuringElement(1, Size(3, 3)); // 十字结构元素 Mat_<uchar> erodeSrc; // 存放腐蚀后的图像 erode(src, erodeSrc, kernel); namedWindow("src", WINDOW_GUI_NORMAL); namedWindow("erodeSrc", WINDOW_GUI_NORMAL); imshow("src", src); imshow("erodeSrc", erodeSrc); waitKey(0); destroyAllWindows(); return 0; }
运行结果:
简介
实现
OpenCV提供了用于图像膨胀的dilate()
函数
void cv::dilate(src, dst, kernel, anchor, iterations)
getStructuringElement()
函数生成示例代码:
#include <opencv2/opencv.hpp> #include <iostream> using namespace std; using namespace cv; int main() { // 生成用于膨胀的原图 Mat_<uchar> src = (Mat_<uchar>(6, 6) << 0, 0, 0, 0, 255, 0, 0, 255, 255, 255, 255, 255, 0, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0); Mat kernel; kernel = getStructuringElement(1, Size(3, 3)); // 十字结构元素 Mat_<uchar> dilateSrc; // 存放膨胀后的图像 dilate(src, dilateSrc, kernel); namedWindow("src", WINDOW_GUI_NORMAL); namedWindow("dilateSrc", WINDOW_GUI_NORMAL); imshow("src", src); imshow("dilateSrc", dilateSrc); waitKey(0); destroyAllWindows(); return 0; }
运行结果:
简介
实现
OpenCV提供了图像腐蚀和膨胀运算不同组合形式的morphologyEx()
函数,以实现图像的开运算、闭运算、形态学梯度、顶帽运算、黑帽运算,以及击中击不中变换
void cv::morphologyEx(src, dst, op, kernel, anchor, iterations)
src:输入图像,图像的通道数可以是任意的,但类型必须是CV_8U、CV_16U、CV_16S、CV_32F或CV_64F之一
dst:形态学操作后的输出图像,与输入图像具有相同的尺寸和数据类型
op:形态学操作类型的标志,可以选择的标志及其含义如下
标志参数 | 简记 | 含义 |
---|---|---|
MORPH_DILATE | 1 | 图像膨胀 |
MORPH_OPEN | 2 | 开运算 |
MORPH_CLOSE | 3 | 闭运算 |
MORPH_GRADIENT | 4 | 形态学梯度 |
MORPH_TOPHAT | 5 | 顶帽运算 |
MORPH_BLACKHAT | 6 | 黑帽运算 |
MORPH_HITMISS | 7 | 击中击不中运算 |
kernel:结构元素,可以自己定义,也可以用getStructuringElement()
函数生成
anchor:中心点在结构元素中的位置,默认参数为结构元素的几何中心点
iterations:处理的次数,默认值为1
示例代码:
#include <opencv2/opencv.hpp> using namespace std; using namespace cv; int main() { Mat src = (Mat_<uchar>(9, 12) << 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 255, 255, 255, 0, 255, 255, 255, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); namedWindow("src", WINDOW_NORMAL); // 可以自由调节显示图像的尺寸 imshow("src", src); // 3x3 矩形结构元素 Mat kernel = getStructuringElement(0, Size(3, 3)); // 对二值化矩阵进行开运算 Mat open; morphologyEx(src, open, MORPH_OPEN, kernel); namedWindow("Opening", WINDOW_NORMAL); // 可以自由调节显示图像的尺寸 imshow("Opening", open); waitKey(0); destroyAllWindows(); return 0; }
运行结果:
简介
实现
示例代码:
#include <opencv2/opencv.hpp> #include <iostream> using namespace std; using namespace cv; int main() { Mat src = (Mat_<uchar>(9, 12) << 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 255, 255, 255, 0, 255, 255, 255, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); namedWindow("src", WINDOW_NORMAL); // 可以自由调节显示图像的尺寸 imshow("src", src); // 3x3 矩形结构元素 Mat kernel = getStructuringElement(0, Size(3, 3)); // 对二值化矩阵进行闭运算 Mat close; morphologyEx(src, close, MORPH_CLOSE, kernel); namedWindow("Closing", WINDOW_NORMAL); // 可以自由调节显示图像的尺寸 imshow("Closing", close); waitKey(0); destroyAllWindows(); return 0; }
运行结果:
简介
注,morphologyEx()
函数仅可实现图像的基本梯度,如果需要计算图像的内部梯度或外部梯度,需要自己通过编程实现
实现
示例代码:
#include <opencv2/opencv.hpp> using namespace std; using namespace cv; int main() { Mat src = (Mat_<uchar>(9, 12) << 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 255, 255, 255, 0, 255, 255, 255, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); namedWindow("src", WINDOW_NORMAL); // 可以自由调节显示图像的尺寸 imshow("src", src); // 3x3 矩形结构元素 Mat kernel = getStructuringElement(0, Size(3, 3)); // 对二值化矩阵进行形态学梯度运算 Mat gradient; morphologyEx(src, gradient, MORPH_GRADIENT, kernel); namedWindow("Morphological Gradient", WINDOW_NORMAL); // 可以自由调节显示图像的尺寸 imshow("Morphological Gradient", gradient); waitKey(0); destroyAllWindows(); return 0; }
运行结果:
简介
实现
示例代码:
#include <opencv2/opencv.hpp> using namespace std; using namespace cv; int main() { Mat src = (Mat_<uchar>(9, 12) << 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 255, 255, 255, 0, 255, 255, 255, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); namedWindow("src", WINDOW_NORMAL); // 可以自由调节显示图像的尺寸 imshow("src", src); // 3x3 矩形结构元素 Mat kernel = getStructuringElement(0, Size(3, 3)); // 对二值化矩阵进行顶帽运算 Mat tophat; morphologyEx(src, tophat, MORPH_TOPHAT, kernel); namedWindow("Top Hat", WINDOW_NORMAL); // 可以自由调节显示图像的尺寸 imshow("Top Hat", tophat); waitKey(0); destroyAllWindows(); return 0; }
运行结果:
简介
实现
示例代码:
#include <opencv2/opencv.hpp> using namespace std; using namespace cv; int main() { Mat src = (Mat_<uchar>(9, 12) << 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 255, 255, 255, 0, 255, 255, 255, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); namedWindow("src", WINDOW_NORMAL); // 可以自由调节显示图像的尺寸 imshow("src", src); // 3x3 矩形结构元素 Mat kernel = getStructuringElement(0, Size(3, 3)); // 对二值化矩阵进行黑帽运算 Mat blackhat; morphologyEx(src, blackhat, MORPH_BLACKHAT, kernel); namedWindow("Black Hat", WINDOW_NORMAL); // 可以自由调节显示图像的尺寸 imshow("Black Hat", blackhat); waitKey(0); destroyAllWindows(); return 0; }
简介
PS:在使用矩形结构元素时,击中击不中变换与图像的腐蚀结果相同
实现
示例代码:
#include <opencv2/opencv.hpp> const int rate = 50; using namespace cv; int main() { Mat input_image = (Mat_<uchar>(8, 8) << 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 255, 0, 255, 255, 255, 0, 0, 0, 0, 0, 255, 255, 255, 0, 255, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 255, 255, 0, 0, 255, 0, 255, 0, 0, 255, 0, 0, 255, 255, 255, 0, 0, 0, 0); Mat kernel = (Mat_<int>(3, 3) << 0, 1, 0, 1, -1, 1, 0, 1, 0); Mat output_image; morphologyEx(input_image, output_image, MORPH_HITMISS, kernel); kernel = (kernel + 1) * 127; kernel.convertTo(kernel, CV_8U); resize(kernel, kernel, Size(), rate, rate, INTER_NEAREST); imshow("kernel", kernel); moveWindow("kernel", 0, 0); resize(input_image, input_image, Size(), rate, rate, INTER_NEAREST); imshow("Original", input_image); moveWindow("Original", 0, 200); resize(output_image, output_image, Size(), rate, rate, INTER_NEAREST); imshow("Hit or Miss", output_image); moveWindow("Hit or Miss", 500, 200); waitKey(0); return 0; }
运行结果: