Qt|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 (InputArraysrc, OutputArraydst, intop, InputArraykernel, Pointanchor = Point(-1,-1), intiterations = 1, intborderType = BORDER_CONSTANT, const Scalar &borderValue = https://www.it610.com/article/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 = https://www.it610.com/article/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); }

输出结果:
Qt|OpenCV图像处理-形态学操作
文章图片

闭操作 闭操作本质为先膨胀后腐蚀,其主要作用为填充小洞(块)。
示例:
#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 = https://www.it610.com/article/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); }

【Qt|OpenCV图像处理-形态学操作】输出结果:
Qt|OpenCV图像处理-形态学操作
文章图片

形态学梯度 形态学梯度本质为膨胀减去腐蚀,又称为基本梯度。
示例:
#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 = https://www.it610.com/article/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); }

输出结果:
原图像
Qt|OpenCV图像处理-形态学操作
文章图片

梯度操作
Qt|OpenCV图像处理-形态学操作
文章图片

顶帽 顶帽操作是指原图像与开操作之间的差值图像
示例:
#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 = https://www.it610.com/article/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); }

输出结果:
Qt|OpenCV图像处理-形态学操作
文章图片

黑帽 顶帽操作是指原图像与闭操作之间的差值图像
示例:
#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 = https://www.it610.com/article/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); }

输出结果:
Qt|OpenCV图像处理-形态学操作
文章图片

应用-提取水平与垂直直线 提取思路:输入彩色图像→转化为灰度图像→转化为二值图像→定义结构元素→开操作提取水平与垂直线
代码:
#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 = https://www.it610.com/article/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); }

Qt|OpenCV图像处理-形态学操作
文章图片

    推荐阅读