OpenCV图像处理-形态学操作

9 篇文章 0 订阅

前言

本文使用的环境为:Qt5.11 + OpenCV3.4.6
环境安装参考文档:https://blog.csdn.net/z634863434/article/details/89950961
形态学膨胀和腐蚀:https://blog.csdn.net/z634863434/article/details/98584945

形态学API

函数原型:

void cv::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() 
	) 	

作用:图像的开操作

输入参数参数定义
src输入图像
dst输出图像
op形态操作的类型,包括开、闭,梯度,顶帽,黑帽等
kernel结构元素
anchor锚点,(-1,-1)为中心点
iterations应用次数
borderType像素外推方法
borderValue边界值

开操作

开操作本质为先腐蚀后膨胀,其主要作用为可以去除小的对象。

示例:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <opencv2/opencv.hpp>
#include <QtDebug>

using namespace cv;
Mat src,dst;

int element_size = 3;
int max_size = 21;
/*给滑动的回调函数*/
void CallBack_Demo(int,void*)
{
    //设定结构元素的大小与滑动块系统相联系
    int s = element_size * 2 + 1;
    //创建结构元素
    Mat structureElenent = getStructuringElement(MORPH_RECT,Size(s,s));
    //开操作
    morphologyEx(src,dst,MORPH_OPEN,structureElenent);
    //显示画面
    imshow("output Image",dst);
}

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    //读取图像
    src = imread("E:/OpenCV/OpenCVPicture/BlackNode.jpg");
    if(src.empty()){
        qDebug()<<"can not load image...\n";
        return ;
    }
    //显示原始图像
    namedWindow("input Image",CV_WINDOW_AUTOSIZE);
    imshow("input Image",src);
    //创建处理后图像的窗口
    namedWindow("output Image",CV_WINDOW_AUTOSIZE);
    //创建滑动条
    createTrackbar("Element Size:","output Image",&element_size,max_size,CallBack_Demo);
    //调用回调函数
    CallBack_Demo(0,NULL);
 }

输出结果:
在这里插入图片描述

闭操作

闭操作本质为先膨胀后腐蚀,其主要作用为填充小洞(块)。
示例:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <opencv2/opencv.hpp>
#include <QtDebug>

using namespace cv;
Mat src,dst;

int element_size = 3;
int max_size = 21;
/*给滑动的回调函数*/
void CallBack_Demo(int,void*)
{
    //设定结构元素的大小与滑动块系统相联系
    int s = element_size * 2 + 1;
    //创建结构元素
    Mat structureElenent = getStructuringElement(MORPH_RECT,Size(s,s));
    //闭操作
    morphologyEx(src,dst,MORPH_CLOSE,structureElenent);
    //显示画面
    imshow("output Image",dst);
}

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    //读取图像
    src = imread("E:/OpenCV/OpenCVPicture/BlackNode.jpg");
    if(src.empty()){
        qDebug()<<"can not load image...\n";
        return ;
    }
    //显示原始图像
    namedWindow("input Image",CV_WINDOW_AUTOSIZE);
    imshow("input Image",src);
    //创建处理后图像的窗口
    namedWindow("output Image",CV_WINDOW_AUTOSIZE);
    //创建滑动条
    createTrackbar("Element Size:","output Image",&element_size,max_size,CallBack_Demo);
    //调用回调函数
    CallBack_Demo(0,NULL);
 }

输出结果:
在这里插入图片描述

形态学梯度

形态学梯度本质为膨胀减去腐蚀,又称为基本梯度。
示例:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <opencv2/opencv.hpp>
#include <QtDebug>

using namespace cv;
Mat src,dst;

int element_size = 3;
int max_size = 21;
/*给滑动的回调函数*/
void CallBack_Demo(int,void*)
{
    //设定结构元素的大小与滑动块系统相联系
    int s = element_size * 2 + 1;
    //创建结构元素
    Mat structureElenent = getStructuringElement(MORPH_RECT,Size(s,s));
    //梯度操作
    morphologyEx(src,dst,MORPH_GRADIENT,structureElenent);
    //显示画面
    imshow("output Image",dst);
}

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    //读取图像
    src = imread("E:/OpenCV/OpenCVPicture/horse.png");
    if(src.empty()){
        qDebug()<<"can not load image...\n";
        return ;
    }
    //显示原始图像
    namedWindow("input Image",CV_WINDOW_AUTOSIZE);
    imshow("input Image",src);
    //创建处理后图像的窗口
    namedWindow("output Image",CV_WINDOW_AUTOSIZE);
    //创建滑动条
    createTrackbar("Element Size:","output Image",&element_size,max_size,CallBack_Demo);
    //调用回调函数
    CallBack_Demo(0,NULL);
}

输出结果:
原图像
在这里插入图片描述
梯度操作
在这里插入图片描述

顶帽

顶帽操作是指原图像与开操作之间的差值图像
示例:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <opencv2/opencv.hpp>
#include <QtDebug>

using namespace cv;
Mat src,dst;

int element_size = 3;
int max_size = 21;
/*给滑动的回调函数*/
void CallBack_Demo(int,void*)
{
    //设定结构元素的大小与滑动块系统相联系
    int s = element_size * 2 + 1;
    //创建结构元素
    Mat structureElenent = getStructuringElement(MORPH_RECT,Size(s,s));
    //顶帽操作
    morphologyEx(src,dst,MORPH_TOPHAT,structureElenent);
    //显示画面
    imshow("output Image",dst);
}

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    //读取图像
    src = imread("E:/OpenCV/OpenCVPicture/BlackNode.jpg");
    if(src.empty()){
        qDebug()<<"can not load image...\n";
        return ;
    }
    //显示原始图像
    namedWindow("input Image",CV_WINDOW_AUTOSIZE);
    imshow("input Image",src);
    //创建处理后图像的窗口
    namedWindow("output Image",CV_WINDOW_AUTOSIZE);
    //创建滑动条
    createTrackbar("Element Size:","output Image",&element_size,max_size,CallBack_Demo);
    //调用回调函数
    CallBack_Demo(0,NULL);
}

输出结果:
在这里插入图片描述

黑帽

顶帽操作是指原图像与闭操作之间的差值图像
示例:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <opencv2/opencv.hpp>
#include <QtDebug>

using namespace cv;
Mat src,dst;

int element_size = 3;
int max_size = 21;
/*给滑动的回调函数*/
void CallBack_Demo(int,void*)
{
    //设定结构元素的大小与滑动块系统相联系
    int s = element_size * 2 + 1;
    //创建结构元素
    Mat structureElenent = getStructuringElement(MORPH_RECT,Size(s,s));
    //顶帽操作
    morphologyEx(src,dst,MORPH_BLACKHAT,structureElenent);
    //显示画面
    imshow("output Image",dst);
}

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    //读取图像
    src = imread("E:/OpenCV/OpenCVPicture/BlackNode.jpg");
    if(src.empty()){
        qDebug()<<"can not load image...\n";
        return ;
    }
    //显示原始图像
    namedWindow("input Image",CV_WINDOW_AUTOSIZE);
    imshow("input Image",src);
    //创建处理后图像的窗口
    namedWindow("output Image",CV_WINDOW_AUTOSIZE);
    //创建滑动条
    createTrackbar("Element Size:","output Image",&element_size,max_size,CallBack_Demo);
    //调用回调函数
    CallBack_Demo(0,NULL);
}

输出结果:
在这里插入图片描述

应用-提取水平与垂直直线

提取思路:输入彩色图像→转化为灰度图像→转化为二值图像→定义结构元素→开操作提取水平与垂直线

代码:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <opencv2/opencv.hpp>
#include <QtDebug>

using namespace cv;


MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    Mat src,hdst,vdst,gray_src,bin_src,hline,vline,temp;
    //读取图像
    src = imread("E:/OpenCV/OpenCVPicture/line.PNG");
    if(src.empty()){
        qDebug()<<"can not load image...\n";
        return ;
    }
    //显示原始图像
    namedWindow("input Image",CV_WINDOW_AUTOSIZE);
    imshow("input Image",src);
    //创建处理后图像的窗口(横线)
    namedWindow("output Image_h",CV_WINDOW_AUTOSIZE);
    //创建处理后图像的窗口(竖线)
    namedWindow("output Image_v",CV_WINDOW_AUTOSIZE);
    //创建原始图像的灰度图像窗口
    namedWindow("gray_src Image",CV_WINDOW_AUTOSIZE);
    //创建灰度图像的二值图像窗口
    namedWindow("bin_src Image",CV_WINDOW_AUTOSIZE);
    //转化原始图像为灰度图像
    cvtColor(src,gray_src,CV_BGR2GRAY);
    //显示原始图像的灰度图像
    imshow("gray_src Image",gray_src);
    //将灰度图像转化为二值图像
    adaptiveThreshold(~gray_src,bin_src,255,ADAPTIVE_THRESH_MEAN_C,THRESH_BINARY,15,-2);
    //显示二值图像
    imshow("bin_src Image",bin_src);
    //创建结构元素(横线)
    hline = getStructuringElement(MORPH_RECT,Size(src.cols/16,1),Point(-1,-1));
    //创建结构元素(竖线)
    vline = getStructuringElement(MORPH_RECT,Size(1,src.rows/16),Point(-1,-1));
    //开操作
    morphologyEx(bin_src,hdst,MORPH_OPEN,hline);
    morphologyEx(bin_src,vdst,MORPH_OPEN,vline);
    //取反色
    bitwise_not(hdst,hdst);
    bitwise_not(vdst,vdst);
    //平滑图片,模糊
    blur(hdst,hdst,Size(3,3));
    blur(vdst,vdst,Size(3,3));
    //显示处理结果
    imshow("output Image_h",hdst);
    imshow("output Image_v",vdst);
 }

在这里插入图片描述

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值