OpenCV图像处理-形态学操作

OpenCV图像处理-形态学操作

    • 前言
    • 形态学API
    • 开操作
    • 闭操作
    • 形态学梯度
    • 顶帽
    • 黑帽
    • 应用-提取水平与垂直直线

前言

本文使用的环境为: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 
#include 

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

输出结果:
OpenCV图像处理-形态学操作_第1张图片

闭操作

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

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include 
#include 

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

输出结果:
OpenCV图像处理-形态学操作_第2张图片

形态学梯度

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

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include 
#include 

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

输出结果:
原图像
OpenCV图像处理-形态学操作_第3张图片
梯度操作
OpenCV图像处理-形态学操作_第4张图片

顶帽

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

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include 
#include 

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

输出结果:
OpenCV图像处理-形态学操作_第5张图片

黑帽

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

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include 
#include 

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

输出结果:
OpenCV图像处理-形态学操作_第6张图片

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

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

代码:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include 
#include 

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

OpenCV图像处理-形态学操作_第7张图片

你可能感兴趣的:(Qt,OpenCV)