其他分享
首页 > 其他分享> > 形态学操作

形态学操作

作者:互联网

形态学操作

简介

连通域

腐蚀(Erosion)

简介

结构元素

Mat cv::getStructuringElement(shape, ksize)

实现

OpenCV提供了用于图像腐蚀的erode()函数

void cv::erode(src, dst, kernel, anchor, iterations)

示例代码:

#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;
}

运行结果:

膨胀(Dilation)

简介

实现

OpenCV提供了用于图像膨胀的dilate()函数

void cv::dilate(src, dst, kernel, anchor, iterations)

示例代码:

#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;
}

运行结果:

开运算(Opening)

简介

实现

OpenCV提供了图像腐蚀和膨胀运算不同组合形式的morphologyEx()函数,以实现图像的开运算、闭运算、形态学梯度、顶帽运算、黑帽运算,以及击中击不中变换

void cv::morphologyEx(src, dst, op, kernel, anchor, iterations)

示例代码:

#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;
}

运行结果:

闭运算(Closing)

简介

实现

示例代码:

#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;
}

运行结果:

形态学梯度(Morphological Gradient)

简介

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;
}

运行结果:

顶帽运算(Top Hat)

简介

实现

示例代码:

#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;
}

运行结果:

黑帽运算(Black Hat)

简介

实现

示例代码:

#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;
}

击中不击中变换(Hit-or-Miss)

简介

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;
}

运行结果:

标签:src,运算,元素,形态学,腐蚀,图像,操作,Mat
来源: https://www.cnblogs.com/TNTksals/p/15835309.html