博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【opencv学习笔记】013之形态学操作应用(trackbar应用)
阅读量:4075 次
发布时间:2019-05-25

本文共 3357 字,大约阅读时间需要 11 分钟。

一、前言

继续填坑。

如果想看其他有关于OpenCV学习方法介绍、学习教程、代码实战、常见报错及解决方案等相关内容,可以直接看我的OpenCV分类:

如果你想了解更多有关于计算机视觉、OpenCV、机器学习、深度学习等相关技术的内容,想与更多大佬一起沟通,那就扫描下方二维码加入我们吧!

 

二、形态学操作

1、回顾

首先我们先回顾一下形态学操作。

首先我们学习了形态学的两个基本操作,分别是:膨胀和腐蚀。

(1)膨胀:跟卷积操作类似,假设有图像A和结构元素B,结构元素B在A上面移动,其中B定义其中心为锚点,计算B覆盖下A的最大像素值用来替换锚点的像素,其中B作为结构体可以是任意形状。

因为是最大像素,所以对于二值图像来说,膨胀就是可以让白色区域膨胀扩大。

(2)腐蚀:腐蚀跟膨胀操作的过程类似,唯一不同的是以最小值替换锚点重叠下图像的像素值。

因为是最小像素,所以对于二值图像来说,辅食就是黑色腐蚀区域扩大。

接下来我们学习了5个形态学操作,分别如下:

(1)开操作:先腐蚀后膨胀,可以去掉小的对象。

(2)闭操作:先膨胀后腐蚀,可以填充小对象。

(3)形态学梯度:膨胀减去腐蚀。

(4)顶帽:顶帽是原图像与开操作图像之间的差值图像。

(5)黑帽:黑帽是闭操作图像与原图像之间的差值图像。

今天我们来学习一下形态学两个非常重要的应用。

三、OpenCV中的形态学应用-滑动条应用

1、滑动条用于核

之前,我们每次使用形态学操作,需要设置核,核的大小需要我们自己设置,每次想要调整,都是需要不断停止运行,修改代码,然后再执行,这样太慢了,我们能不能运行的过程中,通过调整滑动条,让它自动调整核的大小呢?

opencv提供了trackbar功能。我们可以创建一个trackbar来动态调整核的大小,这样,我们就不用每次都重新修改代码,重新编译了。

创建trackbar的API是createTrackbar()

1.API

int createTrackbar(    const String& trackbarname,     const String& winname,    int* value,     int count,    TrackbarCallback onChange = 0,    void* userdata = 0);

函数参数含义如下:

(1)String类型的trackbarname,滑动条轨迹名。

(2)string类型的winname,用作创建的轨迹栏父窗口的名称。即滑动条依附的窗口名。

(3)int类型的指针value,指向整数变量的可选指针,其值反映滑块的位置。创建时,滑块位置由该变量定义,滑块初始位置就是这个变量当前的值。

(4)int类型的count,滑块的最大位置。最小位置总是0。

(5)TrackbarCallback类型的onChange:指向每次滑块更改位置时要调用的函数的指针。此函数的原型应为

void Foo(int,void\*);

其中第一个参数是trackbar位置,第二个参数是用户数据(请参阅下一个参数)。如果回调是空指针,则不调用回调,但只更新值。

(6)void类型的userdata:按原样传递给回调的用户数据,默认为0。它可以用来处理trackbar事件而不使用全局变量。如果第三个值为全局变量,忽略这个值。

 

2.代码展示

讲完API,我们讲一个具体的例子,我们学习了形态学操作,我们希望可以滑动滑动条来控制核大小。

#include
#include
using namespace std;using namespace cv;Mat src, dst;char inimg[] = "【inputImage】";char outimg[] = "【outputImage】";void changeTrackbar(int pos, void*usrdata) { Mat kernel = getStructuringElement(MORPH_RECT, Size(2*pos+1, 2 * pos + 1), Point(-1, -1)); morphologyEx(src, dst, 0, kernel); imshow(outimg, dst);}int main(){ src = imread("E:/image/girl2.png"); if (!src.data) { cout << "could not load image !"; return -1; } namedWindow(inimg,CV_WINDOW_AUTOSIZE); namedWindow(outimg,CV_WINDOW_AUTOSIZE); imshow(inimg, src); int initValue = 2; int maxSize = 10; createTrackbar("kernel", outimg, &initValue, maxSize, changeTrackbar); waitKey(0); return 0;}

3.执行结果

原图

下图为pos为1时,1*2+1 = 3,size为(3*3)

Size = (3,3)

下图为pos为9时,9*2+1 = 19,size为(19*19)  

Size = (19,19)

2、滑动条用于类型

我们通过设置。滑动条,还可以调整形态学操作的类型。

大家应该还记得形态学操作类型会对应到不同的数字:

enum MorphTypes{    MORPH_ERODE    = 0,  //腐蚀    MORPH_DILATE   = 1,  //膨胀    MORPH_OPEN     = 2,  //开操作    MORPH_CLOSE    = 3,  //闭操作    MORPH_GRADIENT = 4,  //梯度操作    MORPH_TOPHAT   = 5,  //顶帽操作    MORPH_BLACKHAT = 6,  //黑帽操作};

所以我们可以通过滑动条来控制不同的类型。这次滑动条的最大值为6。

2.代码展示

讲完API,我们讲一个具体的例子,我们学习了形态学操作,我们希望可以滑动滑动条来控制核大小。

#include
#include
using namespace std;using namespace cv;Mat src, dst;char inimg[] = "【inputImage】";char outimg[] = "【outputImage】";void changeTrackbar(int pos, void*usrdata) { Mat kernel = getStructuringElement(MORPH_RECT, Size(5, 5), Point(-1, -1)); morphologyEx(src, dst, pos, kernel); imshow(outimg, dst);}int main(){ src = imread("E:/image/girl2.png"); if (!src.data) { cout << "could not load image !"; return -1; } namedWindow(inimg,CV_WINDOW_AUTOSIZE); namedWindow(outimg,CV_WINDOW_AUTOSIZE); imshow(inimg, src); int initValue = 2; int maxSize = 6; createTrackbar("kernel", outimg, &initValue, maxSize, changeTrackbar); waitKey(0); return 0;}

3.执行结果

原图

其他的大家自己做一下测试,今天的内容就讲到这里啦,希望大家能够多多练习,才能真正学懂啊!

转载地址:http://xzyni.baihongyu.com/

你可能感兴趣的文章
linux内核内存管理(zone_dma zone_normal zone_highmem)
查看>>
将file文件内容转成字符串
查看>>
循环队列---数据结构和算法
查看>>
优先级队列-数据结构和算法
查看>>
链接点--数据结构和算法
查看>>
servlet中请求转发(forword)与重定向(sendredirect)的区别
查看>>
Spring4的IoC和DI的区别
查看>>
springcloud 的eureka服务注册demo
查看>>
eureka-client.properties文件配置
查看>>
MODULE_DEVICE_TABLE的理解
查看>>
platform_device与platform_driver
查看>>
platform_driver平台驱动注册和注销过程(下)
查看>>
.net强制退出主窗口的方法——Application.Exit()方法和Environment.Exit(0)方法
查看>>
c# 如何调用win8自带的屏幕键盘(非osk.exe)
查看>>
build/envsetup.sh 简介
查看>>
Android framework中修改或者添加资源无变化或编译不通过问题详解
查看>>
linux怎么切换到root里面?
查看>>
linux串口操作及设置详解
查看>>
安装alien,DEB与RPM互换
查看>>
编译Android4.0源码时常见错误及解决办法
查看>>