《OpenCV3编程入门》学习笔记番外篇之图像形态学处理

关于图像形态学在《OpenCV3编程入门》学习笔记六:图像处理 中涉及到过,但给的例程不是特别好。这里再给出一个比较直观的例子。
源码:

#include<opencv2/opencv.hpp>
#include<iostream>
using namespace cv;
using namespace std;

Mat g_srcImage, g_dstImage;  //原始图和效果图
int g_nElementShape = MORPH_RECT;  //元素结构的形状
//变量接受的Trackbar位置参数
int g_nMaxIterationNum = 10;  
int g_nOpenCloseNum = 0;
int g_nErodeDilateNum = 0;
int g_nTopBlackHatNum = 0;
//全局函数
static void on_OpenClose(int, void*);
static void on_ErodeDilate(int, void*);
static void on_TopBlackHat(int, void*);

int main()
{
    g_srcImage = imread("poster_geometry.jpg");
    namedWindow("【原始图】");
    imshow("【原始图】", g_srcImage);
    //创建三个窗口
    namedWindow("【开运算/闭运算】");
    namedWindow("【腐蚀/膨胀】");
    namedWindow("【顶帽/黑帽】");
    //参数赋值
    g_nOpenCloseNum = 9;
    g_nErodeDilateNum = 9;
    g_nTopBlackHatNum = 9;
    //分别为三个窗口创建滚动条
    createTrackbar("迭代值", "【开运算/闭运算】", &g_nOpenCloseNum, g_nMaxIterationNum*2+1, on_OpenClose);
    createTrackbar("迭代值", "【腐蚀/膨胀】", &g_nErodeDilateNum, g_nMaxIterationNum * 2 + 1, on_ErodeDilate);
    createTrackbar("迭代值", "【顶帽/黑帽】", &g_nTopBlackHatNum, g_nMaxIterationNum * 2 + 1, on_TopBlackHat);
    //轮询获取按键信息
    while (1) {
        int c;
        //执行回调函数
        on_OpenClose(g_nOpenCloseNum, 0);
        on_ErodeDilate(g_nErodeDilateNum, 0);
        on_TopBlackHat(g_nTopBlackHatNum, 0);
        //获取按键
        c = waitKey(1);
        if ((char)c == 'q' || (char)c == 27) //按下键盘按键q或ESC,程序退出
            break;
        else if ((char)c == '1') //按下键盘按键1,使用椭圆结构元素MORPH_ELLIPSE
            g_nElementShape = MORPH_ELLIPSE;
        else if ((char)c == '2') //按下键盘按键2,使用矩形结构元素MORPH_RECT
            g_nElementShape = MORPH_RECT;
        else if ((char)c == '3') //按下键盘按键3,使用十字形结构元素MORPH_CROSS
            g_nElementShape = MORPH_CROSS;
        else if ((char)c == ' ') //按下键盘按键space,在矩形、椭圆、十字形结构元素中循环
            g_nElementShape = (g_nElementShape+1)%3;
    }
    return 0;
}

static void on_OpenClose(int, void*)
{
    int offset = g_nOpenCloseNum - g_nMaxIterationNum;  //偏移量:负为开运算,正为闭运算
    int Absolute_offset = offset > 0 ? offset : -offset;  //偏移量的绝对值,核的大小
    Mat element = getStructuringElement(g_nElementShape, Size(Absolute_offset *2+1, Absolute_offset *2+1));//自定义核
    if (offset < 0)
        morphologyEx(g_srcImage, g_dstImage, MORPH_OPEN, element);
    else
        morphologyEx(g_srcImage, g_dstImage, MORPH_CLOSE, element);
    imshow("【开运算/闭运算】", g_dstImage);
}

static void on_ErodeDilate(int, void*)
{
    int offset = g_nErodeDilateNum - g_nMaxIterationNum;  //偏移量:负为开运算,正为闭运算
    int Absolute_offset = offset > 0 ? offset : -offset;  //偏移量的绝对值,核的大小
    Mat element = getStructuringElement(g_nElementShape, Size(Absolute_offset * 2 + 1, Absolute_offset * 2 + 1));//自定义核
    if (offset < 0)
        morphologyEx(g_srcImage, g_dstImage, MORPH_ERODE, element);
    else
        morphologyEx(g_srcImage, g_dstImage, MORPH_DILATE, element);
    imshow("【腐蚀/膨胀】", g_dstImage);
}
/*
顶帽:原图像与开运算结果之差
黑帽:原图像与闭运算结果之差
*/
static void on_TopBlackHat(int, void*)
{
    int offset = g_nTopBlackHatNum - g_nMaxIterationNum;  //偏移量:负为开运算,正为闭运算
    int Absolute_offset = offset > 0 ? offset : -offset;  //偏移量的绝对值,核的大小
    Mat element = getStructuringElement(g_nElementShape, Size(Absolute_offset * 2 + 1, Absolute_offset * 2 + 1));//自定义核
    if (offset < 0)
        morphologyEx(g_srcImage, g_dstImage, MORPH_TOPHAT, element);
    else
        morphologyEx(g_srcImage, g_dstImage, MORPH_BLACKHAT, element);
    imshow("【顶帽/黑帽】", g_dstImage);
}

素材:
这里写图片描述
效果图:
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
提示:
关于图像形态学部分,左飞的《数字图像处理 原理与实践(MATLAB版)》第5章图像的形态学处理介绍的比较详细。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值