加载图像 cv::imread;
修改图像 cv::cvtColor;
保存图片 cv::imwrite;
kernel = getStructuringElement(MORPH_RECT, Size(5, 5));
//getStructuringElement函数会返回指定形状和尺寸的结构元素(int shape, Size esize, Point anchor = Point(-1, -1))
//这个函数的第一个参数表示内核的形状,有三种形状可以选择。
//矩形:MORPH_RECT;
//交叉形:MORPH_CORSS;
//椭圆形:MORPH_ELLIPSE;
//第二和第三个参数分别是内核的尺寸以及锚点的位置。
//一般在调用erode以及dilate函数之前,先定义一个Mat类型的变量来获得getStructuringElement函数的返回值。
//对于锚点的位置,有默认值Point(-1,-1),表示锚点位于中心点。
//element形状唯一依赖锚点位置,其他情况下,锚点只是影响了形态学运算结果的偏移
inRange(frame, Scalar(0, 80, 80), Scalar(50, 255, 255), dst);
//开操作
//可实现二值化功能(这点类似threshold()函数),更关键的是可以同时针对多通道进行操作,使用起来非常方便!
//参数1:输入要处理的图像,可以为单通道或多通道。
//参数2:包含下边界的数组或标量。
//参数3:包含上边界数组或标量。
//参数4:输出图像,与输入图像src 尺寸相同且为CV_8U 类型。
高级形态学变换:
开运算:
先腐蚀,再膨胀,可清除一些小东西(亮的),放大局部低亮度的区域
闭运算:
先膨胀,再腐蚀,可清除小黑点
形态学梯度:
膨胀图与腐蚀图之差,提取物体边缘
顶帽:
原图像-开运算图,突出原图像中比周围亮的区域
黑帽:
闭运算图-原图像,突出原图像中比周围暗的区域
腐蚀用于分割(isolate)独立的图像元素,
膨胀用于连接(join)相邻的元素
腐蚀、膨胀可用于去噪(低尺寸结构元素的腐蚀操作很容易去掉分散的椒盐噪声点),
图像轮廓提取、图像分割、寻找图像中的明显的极大值区域或极小值区域等
腐蚀和膨胀是最基本的形态学算子
结构元素
就相当于我们在滤波中所涉及到的模板,也就是说它是一个给定像素的矩阵,这个矩阵可以是任意形状的,
一般情况下都是正方形,圆形或者菱形的但是在结构元素中有一个中心点(也叫做anchor point)。
和模板中心一样,处理后的结果赋值给和这个中心点对齐的像素点。处理的过程也是基本相同。
结构元素和卷积模板的区别在于,膨胀是以集合运算为基础的,卷积是以算数运算为基础的。
(OpenCV里面的腐蚀膨胀都是针对白色目标区域的)
膨胀:用结构元素的中心点对准当前正在遍历的这个像素,
然后取当前结构元素所覆盖下的原图对应区域内的所有像素的最大值,用这个最大值替换当前像素值,给图像中的对象边界添加像素,使二值图像扩大一圈
1. 用结构元素,扫描图像的每一个像素
2. 用结构元素与其覆盖的二值图像做“与”操作
3. 如果都为0,结果图像的该像素为0。否则为1
也就是在结构元素覆盖范围下,只要有一个像素符和结构元素像素相同,那么中心点对应点就为1,否则为0
腐蚀:用结构元素的中心点对准当前正在遍历的这个像素,
然后取当前结构元素所覆盖下的原图对应区域内的所有像素的最小值,用这个最小值替换当前像素值,删除对象边界的某些像素,使二值图像减小一圈
1. 用结构元素,扫描图像的每一个像素
2. 用结构元素与其覆盖的二值图像做“与”操作
3. 如果都为1,结果图像的该像素为1。否则为0
也就是查找被处理图像中能不能找到和结构元素相同的矩阵。如果存在那么中心点所对应的点就为1,否则为0
腐蚀:删除对象边界的某些像素
膨胀:给图像中的对象边界添加像素
//! 侵蚀图像(应用局部最小算子)
CV_EXPORTS_W void erode( InputArray src, OutputArray dst, InputArray kernel,
Point anchor=Point(-1,-1), int iterations=1,
int borderType=BORDER_CONSTANT,
const Scalar& borderValue=morphologyDefaultBorderValue() );
src
原图像
dst
结果输出图像
kernel
结构元素
anchor
结构元素的原点
iterations
迭代次数
//! 膨胀图像(应用局部最大算子)
CV_EXPORTS_W void dilate( InputArray src, OutputArray dst, InputArray kernel,
Point anchor=Point(-1,-1), int iterations=1,
int borderType=BORDER_CONSTANT,
const Scalar& borderValue=morphologyDefaultBorderValue() );
src
原图像
dst
结果输出图像
kernel
结构元素
anchor
结构元素的原点
iterations
迭代次数
常用的结构元素的形状:
矩形(包括线形)、椭圆(包括圆形)及十字形。
MORPH_RECT
MORPH_ELLIPSE
MORPH_CROSS
//! 返回指定形状和大小的结构化元素
CV_EXPORTS_W Mat getStructuringElement(int shape, Size ksize, Point anchor=Point(-1,-1));
取结构元素(内核矩阵),包括结构元素的大小及形状:
shape
内核的形状: MORPH_RECT、MORPH_ELLIPSE、MORPH_CROSS
ksize
内核的尺寸
anchor
锚点的位置, Point(-1,-1)锚点位于中心
//! 对图像应用高级形态操作
CV_EXPORTS_W void 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() );
morphologyEx函数利用基本的膨胀和腐蚀技术,来执行更加高级形态学变换
MORPH_OPEN – 开运算(Opening operation)
MORPH_CLOSE – 闭运算(Closing operation)
MORPH_GRADIENT - 形态学梯度(Morphological gradient)
MORPH_TOPHAT - 顶帽(Top hat)
MORPH_BLACKHAT - 黑帽(Black hat)
kernel
形态学运算的内核。为NULL,使用参考点位于中心3x3的核。一般使用函数getStructuringElement配合这个参数的使用,
kernel参数填保存getStructuringElement返回值的Mat类型变量。
anchor
锚的位置,其有默认值(-1,-1),表示锚位于中心。
iterations
迭代使用函数的次数,默认值为1。
borderType
用于推断图像外部像素的某种边界模式。注意它有默认值BORDER_CONSTANT。
borderValue
当边界为常数时的边界值,有默认值morphologyDefaultBorderValue(),
opencv中提供findContours()函数来寻找图像中物体的轮廓,并结合drawContours()函数将找到的轮廓绘制出。
首先看一下findContours(),opencv中提供了两种定义形式
//找轮廓
findContours()
void cv::findContours ( InputOutputArray image,
OutputArrayOfArrays contours,
OutputArray hierarchy,
int mode,
int method,
Point offset = Point()
)
image:输入图像
contours:检测到的轮廓,每个轮廓都是以点向量的形式进行存储即使用point类型的vector表示
hierarchy:可选的输出向量(std::vector),包含了图像的拓扑信息,作为轮廓数量的表示hierarchy包含了很多元素,
每个轮廓contours[i]对应hierarchy中hierarchy[i][0]~hierarchy[i][3],分别表示后一个轮廓,前一个轮廓,父轮廓,内嵌轮廓的索引,如果没有对应项,则相应的hierarchy[i]设置为负数。
mode:轮廓检索模式
{
RETR_EXTERNAL:表示只检测最外层轮廓,对所有轮廓设置hierarchy[i][2]=hierarchy[i][3]=-1
RETR_LIST:提取所有轮廓,并放置在list中,检测的轮廓不建立等级关系
RETR_CCOMP:提取所有轮廓,并将轮廓组织成双层结构(two-level hierarchy),顶层为连通域的外围边界,次层位内层边界
RETR_TREE:提取所有轮廓并重新建立网状轮廓结构
RETR_FLOODFILL:官网没有介绍,应该是洪水填充法
}
method:轮廓近似方法
{
CHAIN_APPROX_NONE:获取每个轮廓的每个像素,相邻的两个点的像素位置差不超过1
CHAIN_APPROX_SIMPLE:压缩水平方向,垂直方向,对角线方向的元素,值保留该方向的重点坐标,如果一个矩形轮廓只需4个点来保存轮廓信息
CHAIN_APPROX_TC89_L1和CHAIN_APPROX_TC89_KCOS使用Teh-Chinl链逼近算法中的一种
}
//画轮廓
drawContours()
void cv::drawContours ( InputOutputArray image,
InputArrayOfArrays contours,
int contourIdx,
const Scalar & color,
int thickness = 1,
int lineType = LINE_8,
InputArray hierarchy = noArray(),
int maxLevel = INT_MAX,
Point offset = Point()
)
image:输入输出图像,Mat类型即可
contours:使用findContours检测到的轮廓数据,每个轮廓以点向量的形式存储,point类型的vector
contourIdx:绘制轮廓的只是变量,如果为负值则绘制所有输入轮廓
color:轮廓颜色
thickness:绘制轮廓所用线条粗细度,如果值为负值,则在轮廓内部绘制
lineTpye:线条类型,有默认值LINE_8,有如下可选类型
{
hierarchy:可选层次结构信息
maxLevel:用于绘制轮廓的最大等级
offset:可选轮廓便宜参数,用制定偏移量offset=(dx, dy)给出绘制轮廓的偏移量
}