目录
一.引言
二.图像处理
目录
2.1 erode腐蚀/侵蚀
2.2 dilate 膨胀/扩张
2.3 open 开操作
2.4 close 闭操作
一.引言:
二 图像处理:
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() |
||
) |
Python: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
cv.morphologyEx( | src, op, kernel[, dst[, anchor[, iterations[, borderType[, borderValue]]]]] | ) -> | dst |
#include
Performs advanced morphological transformations.
The function cv::morphologyEx can perform advanced morphological transformations using an erosion and dilation as basic operations.
Any of the operations can be done in-place. In case of multi-channel images, each channel is processed independently.
Parameters
src | Source image. The number of channels can be arbitrary. The depth should be one of CV_8U, CV_16U, CV_16S, CV_32F or CV_64F. |
dst | Destination image of the same size and type as source image. |
op | Type of a morphological operation, see MorphTypes |
kernel | Structuring element. It can be created using getStructuringElement. |
anchor | Anchor position with the kernel. Negative values mean that the anchor is at the kernel center. |
iterations | Number of times erosion and dilation are applied. |
borderType | Pixel extrapolation method, see BorderTypes. BORDER_WRAP is not supported. |
borderValue | Border value in case of a constant border. The default value has a special meaning. |
See also
dilate, erode, getStructuringElement
Note
The number of iterations is the number of times erosion or dilatation operation will be applied. For instance, an opening operation (MORPH_OPEN) with two iterations is equivalent to apply successively: erode -> erode -> dilate -> dilate (and not erode -> dilate -> erode -> dilate).
Examples:
samples/cpp/tutorial_code/ImgProc/Morphology_2.cpp.
高级形态学变换:
开运算:
先腐蚀,再膨胀,可清除一些小东西(亮的),放大局部低亮度的区域
闭运算:
先膨胀,再腐蚀,可清除小黑点
形态学梯度:
膨胀图与腐蚀图之差,提取物体边缘
顶帽:
原图像-开运算图,突出原图像中比周围亮的区域
黑帽:
闭运算图-原图像,突出原图像中比周围暗的区域
腐蚀用于分割(isolate)独立的图像元素,
膨胀用于连接(join)相邻的元素
腐蚀、膨胀可用于去噪(低尺寸结构元素的腐蚀操作很容易去掉分散的椒盐噪声点),图像轮廓提取、图像分割、寻找图像中的明显的极大值区域或极小值区域等
腐蚀和膨胀是最基本的形态学算子
结构元素
就相当于我们在滤波中所涉及到的模板,也就是说它是一个给定像素的矩阵,这个矩阵可以是任意形状的,
一般情况下都是正方形,圆形或者菱形的但是在结构元素中有一个中心点(也叫做anchor point)。
和模板中心一样,处理后的结果赋值给和这个中心点对齐的像素点。处理的过程也是基本相同。
结构元素和卷积模板的区别在于,膨胀是以集合运算为基础的,卷积是以算数运算为基础的。
(OpenCV里面的腐蚀膨胀都是针对白色目标区域的)
膨胀:用结构元素的中心点对准当前正在遍历的这个像素,
然后取当前结构元素所覆盖下的原图对应区域内的所有像素的最大值,用这个最大值替换当前像素值,给图像中的对象边界添加像素,使二值图像扩大一圈
1. 用结构元素,扫描图像的每一个像素
2. 用结构元素与其覆盖的二值图像做“与”操作
3. 如果都为0,结果图像的该像素为0。否则为1
也就是在结构元素覆盖范围下,只要有一个像素符和结构元素像素相同,那么中心点对应点就为1,否则为0
腐蚀:用结构元素的中心点对准当前正在遍历的这个像素,
然后取当前结构元素所覆盖下的原图对应区域内的所有像素的最小值,用这个最小值替换当前像素值,删除对象边界的某些像素,使二值图像减小一圈
1. 用结构元素,扫描图像的每一个像素
2. 用结构元素与其覆盖的二值图像做“与”操作
3. 如果都为1,结果图像的该像素为1。否则为0
也就是查找被处理图像中能不能找到和结构元素相同的矩阵。如果存在那么中心点所对应的点就为1,否则为0
腐蚀:删除对象边界的某些像素
膨胀:给图像中的对象边界添加像素
从小学开始一直到大学,必不可少的科目就是数学,作为一个程序员,一直没觉得大学学的数学和现在的工作(程序员)有多大的关系,直到接触了openCV后,仿佛从一个黑盒子里面突然走出来的感觉,之前学的线性代数,矩阵Matrix,这里都有,对于我个人而言,这是目前编程和数学结合的最紧密的地方了。
之前公司安排的项目都是简单的视频转码工作,把高分辨率的转成低分辨率的然后推送出去,这中间不需要对视频做任何处理分析什么的。然后最近,领导传递个信息,相对视频做分析处理,比如是否蓝屏没有图像,是否冻屏,是否...等等(PS:我们公司是做交通监控的,简单来说就是,公路上都有很多摄像头,需要把这些摄像头数据统一集中起来管理,我个人是做视频转码这块)。基本上也是未来的方向,属于AI(Artificial Intelligence)人工智能这块吧。还记得最早听过这个词还是大学的时候(大概2005年)一个印度的外教,看他手里包着一本厚厚的书,上面写的就是Artificial Intelligence 。那会应该处于刚起步阶段,实际应用还不是很多。也没多少人知道。但是现在各行各业已经实际应用已经十分普遍了。比如语音识别,OCR 人脸识别,智能检测。指纹识别,生物特诊提取等等。
废话说的比较多,下面来说说实际情况。我也是刚刚接触这块很多都还不是很知道,就按照自己的理解来说吧,需要通过机器学习训练处模型,然后通过各种硬件芯片读取这些训练好的模型数据集,然后对图像各种分析,所谓的分析就是各种数学运算。普通的CPU很慢。所以基本上AI这块都需要专门的硬件芯片来支持不然CPU会累死,还慢吞吞的。光靠cpu根本不可能应用到实际应用中。现在嵌入式芯片的各大厂商推出的很多芯片都是支持AI的。我本人实际做的是海思平台的。
然后硬件这块我们公司用的是寒武纪的MLU270 这个比嵌入式的算力要强大不少。视频转码,神经网络。是其主打的方向。
由于MLU270 目前公司只有一台机器,另一位同事在调试视频转码的工作再用。我暂时还用不了。看了下文档 大概最终是要通过CNStream这块来做。CNStream依赖于EasyDK CNRT,EasyDK依赖于CNCodec。然后还有很多CNCC CNAS CN...又多了很多不熟悉的名词,熟悉起来也要花一些时间。看文档,CNStream也是依赖于OpenCV的 ,然后看了下源码 果然,里面很多都是调用OpenCV 处理的。没有机器的这段时间就打算学习下OpenCV 我的环境是Ubuntu18.04 OpenCV版本是4.5.5. 记录下学习过程,也是督促一下自己。
OpenCV的环境搭建之前的一篇文章已经写了(分为默认的动态库和 便于移植的静态库的编译,点下面链接可以查看)
环境搭建 编译opencv4 静态编译
2.1 erode /dilate 腐蚀/膨胀 操作:先看下效果图:
最上面的是原图
左下角的是erode操作之后的效果 右下角是dilate之后的效果,很直观的是什么感觉?
一个是把杂边什么的加深了,另一种是把杂边去除了对吧?
等等怎么好像和字面意思不一样,明明是erode腐蚀操作,为什么杂边变粗了
相反明明字面意思是dilate膨胀,怎么杂边反而没了?
我们在换一张图片 试试 :
发现了什么 这个是不是正常了 ? 左下角腐蚀 把杂边弄没了
右下角膨胀 咋变确实变粗了 真如字面的意思一样 ,那么这两张照片有啥不一样呢?
发现了吧 一个是白底 一个是 黑底 就这个区别 ,在看下官方的文档说明
看下公式那里,很详细的咱也不是很明白,但是有个min知道是啥意思吧 两个值比较取小的值
白底的RGB值是 255 有颜色的RGB值肯定是小于白色的 所以 腐蚀的时候取小的值 也就是保留下有颜色的部分
再看黑底的 黑的RGB是0 对吧 腐蚀的时候 留下小的 也就是保留黑色 这也就解释了上面的现象
在看下 dilate的公式:
和erode相反 去的是两个值中大的那个值 值更大说明就是取比较亮的那一部分
因此可以得出结论 erode腐蚀操作的效果就是让 暗的更暗
dilate 膨胀的操作就是 让亮的部分更亮 。
个人浅见 erode改成 darker
dilate改成lighter 可能更容易理解
下面贴下代码 :
QMCY那个函数 是自己又封装了一层 因为我的opencv调试时候需要GUI 实际项目中不需要GUI
void QMCY_ErodeDilate(const char* file_path)
{
Mat src_img = cv::imread(file_path);
if(src_img.empty())
{
cout<<"Can not open image!"<
void QMCY_DisplayImg(const String& winname, InputArray mat)
{
#ifndef QMCY_NO_GUI
cv::imshow(winname, mat);
#endif
}
void QMCY_WaitKey(int delay)
{
#ifndef QMCY_NO_GUI
waitKey(delay);
#endif
}