opencv轮廓处理函数详细
ApproxChains
用多边形曲线逼近 Freeman 链
CvSeq* cvApproxChains( CvSeq* src_seq, CvMemStorage* storage, int method=CV_CHAIN_APPROX_SIMPLE, double parameter=0, int minimal_perimeter=0, int recursive=0 );
- src_seq
- 涉及其它链的链指针
- storage
- 存储多边形线段位置的缓存
- method
- 逼近方法 (见函数 cvFindContours的描述).
- parameter
- 方法参数(现在不用).
- minimal_perimeter
- 仅逼近周长大于
minimal_perimeter
轮廓。其它的链从结果中除去。 - recursive
- 如果非 0, 函数从
src_seq
中利用h_next
和v_next links
连接逼近所有可访问的链。如果为 0, 则仅逼近单链。
这是一个单独的逼近程序。 对同样的逼近标识,函数 cvApproxChains 与 cvFindContours 的工作方式一模一样。它返回发现的第一个轮廓的指针。其它的逼近模块,可以用返回结构中的 v_next
和 v_next
域来访问
StartReadChainPoints
初始化链读取
void cvStartReadChainPoints( CvChain* chain, CvChainPtReader* reader );
- chain
链的指针
reader
链的读取状态
函数 cvStartReadChainPoints 初始化一个特殊的读取器 (参考 Dynamic Data Structures以获得关于集合与序列的更多内容).
ReadChainPoint
得到下一个链的点
CvPoint cvReadChainPoint( CvChainPtReader* reader );
- reader
- 链的读取状态
函数 cvReadChainPoint返回当前链的点,并且更新读取位置。
ApproxPoly
用指定精度逼近多边形曲线
CvSeq* cvApproxPoly( const void* src_seq, int header_size, CvMemStorage* storage, int method, double parameter, int parameter2=0 );
- src_seq
- 点集数组序列
- header_size
- 逼近曲线的头尺寸
- storage
- 逼近轮廓的容器。如果为 NULL, 则使用输入的序列
- method
- 逼近方法。目前仅支持
CV_POLY_APPROX_DP
, 对应 Douglas-Peucker 算法. - parameter
- 方法相关参数。对
CV_POLY_APPROX_DP
它是指定的逼近精度 - parameter2
- 如果
src_seq
是序列,它表示要么逼近单个序列,要么在src_seq
的同一个或低级层次上逼近所有序列 (参考 cvFindContours 中对轮廓继承结构的描述). 如果src_seq
是点集的数组 (CvMat*) , 参数指定曲线是闭合 (parameter2
!=0) 还是非闭合 (parameter2
=0).
函数 cvApproxPoly逼近一个或多个曲线,并返回逼近结果。对多个曲线的逼近,生成的树将与输入的具有同样的结构。(1:1 的对应关系).
BoundingRect
计算点集的最外面(up-right)矩形边界
CvRect cvBoundingRect( CvArr* points, int update=0 );
- points
- 二维点集,点的序列或向量 (
CvMat
) - update
- 更新标识。下面是轮廓类型和标识的一些可能组合:
- update=0, contour ~ CvContour*: 不计算矩形边界,但直接由轮廓头的
rect
域得到。 - update=1, contour ~ CvContour*: 计算矩形边界,而且将结果写入到轮廓头的
rect
域中 header. - update=0, contour ~ CvSeq* or CvMat*: 计算并返回边界矩形
- update=1, contour ~ CvSeq* or CvMat*: 产生运行错误 (runtime error is raised)
- update=0, contour ~ CvContour*: 不计算矩形边界,但直接由轮廓头的
函数 cvBoundingRect返回二维点集的最外面 (up-right)矩形边界。
ContourArea
计算整个轮廓或部分轮廓的面积
double cvContourArea( const CvArr* contour, CvSlice slice=CV_WHOLE_SEQ );
- contour
- 轮廓 (定点的序列或数组).
- slice
- 感兴趣轮廓部分的起始点,缺省是计算整个轮廓的面积。
函数 cvContourArea计算整个轮廓或部分轮廓的面积。 对后面的情况,面积表示轮廓部分和起始点连线构成的封闭部分的面积。如下图所示:
NOTE: 轮廓的方向影响面积的符号。因此函数也许会返回负的结果。应用函数 fabs()
得到面积的绝对值。
ArcLength
计算轮廓周长或曲线长度
double cvArcLength( const void* curve, CvSlice slice=CV_WHOLE_SEQ, int is_closed=-1 );
- curve
- 曲线点集序列或数组
- slice
- 曲线的起始点,缺省是计算整个曲线的长度
- is_closed
- 表示曲线是否闭合,有三种情况:
- is_closed=0 - 假设曲线不闭合
- is_closed>0 - 假设曲线闭合
- is_closed<0 - 若曲线是序列,检查 ((CvSeq*)curve)->flags 中的标识 CV_SEQ_FLAG_CLOSED 来确定曲线是否闭合。否则 (曲线由点集的数组 (CvMat*) 表示) 假设曲线不闭合。
函数 cvArcLength通过依次计算序列点之间的线段长度,并求和来得到曲线的长度。
CreateContourTree
创建轮廓的继承表示形式
CvContourTree* cvCreateContourTree( const CvSeq* contour, CvMemStorage* storage, double threshold );
- contour
- 输入的轮廓
- storage
- 输出树的容器
- threshold
- 逼近精度
函数 cvCreateContourTree 为输入轮廓 contour
创建一个二叉树,并返回树根的指针。如果参数 threshold
小于或等于 0 ,则函数创建一个完整的二叉树。如果 threshold
大于 0 , 函数用 threshold
指定的精度创建二叉树:如果基线的截断区域顶点小于threshold,该数就停止生长并作为函数的最终结果返回。
ContourFromContourTree
由树恢复轮廓
CvSeq* cvContourFromContourTree( const CvContourTree* tree, CvMemStorage* storage, CvTermCriteria criteria );
- tree
- 轮廓树
- storage
- 重构的轮廓容器
- criteria
- 停止重构的准则
函数 cvContourFromContourTree 从二叉树恢复轮廓。参数 criteria
决定了重构的精度和使用树的数目及层次。所以它可建立逼近的轮廓。 函数返回重构的轮廓。
MatchContourTrees
用树的形式比较两个轮廓
double cvMatchContourTrees( const CvContourTree* tree1, const CvContourTree* tree2, int method, double threshold );
- tree1
- 第一个轮廓树
- tree2
- 第二个轮廓树
- method
- 相似度。仅支持
CV_CONTOUR_TREES_MATCH_I1
。 - threshold
- 相似度阈值
函数 cvMatchContourTrees 计算两个轮廓树的匹配值。从树根开始通过逐层比较来计算相似度。如果某层的相似度小于 threshold
, 则中断比较过程,且返回当前的差值。
计算几何
MaxRect
对两个给定矩形,寻找矩形边界
CvRect cvMaxRect( const CvRect* rect1, const CvRect* rect2 );
- rect1
- 第一个矩形
- rect2
- 第二个矩形
函数 cvMaxRect寻找包含两个输入矩形的具有最小面积的矩形边界。
CvBox2D
旋转的二维盒子
typedef struct CvBox2D { CvPoint2D32f center; CvSize2D32f size; float angle; } CvBox2D;
BoxPoints
寻找盒子的顶点
void cvBoxPoints( CvBox2D box, CvPoint2D32f pt[4] );
- box
- 盒子
- pt
- 顶点数组
函数 cvBoxPoints计算输入的二维盒子的定点。下面是函数代码:
void cvBoxPoints( CvBox2D box, CvPoint2D32f pt[] ) {
float a = (float)cos(box.angle)*0.5f;
float b = (float)sin(box.angle)*0.5f;
pt[].x = box.center.x - a*box.size.height - b*box.size.width; pt[].y = box.center.y + b*box.size.height - a*box.size.width; pt[].x = box.center.x + a*box.size.height - b*box.size.width; pt[].y = box.center.y - b*box.size.height - a*box.size.width; pt[].x = *box.center.x - pt[].x; pt[].y = *box.center.y - pt[].y;
pt[].x = *box.center.x - pt[].x;
pt[].y = *box.center.y - pt[].y;
}
FitEllipse
二维点集的椭圆拟合
CvBox2D cvFitEllipse2( const CvArr* points );
- points
- 点集的序列或数组
函数 cvFitEllipse 对给定的一组二维点集作椭圆的最佳拟合(最小二乘意义上的)。返回的结构与 cvEllipse 中的意义类似,除了 size
表示椭圆轴的整个长度,而不是一半长度。
FitLine
2D 或 3D 点集的直线拟合
void cvFitLine( const CvArr* points, int dist_type, double param, double reps, double aeps, float* line );
- points
- 2D 或 3D 点集,32-比特整数或浮点数坐标
- dist_type
- 拟合的距离类型 (见讨论).
- param
- 对某些距离的数字参数,如果是 0, 则选择某些最优值
- reps, aeps
- 半径 (坐标原点到直线的距离) 和角度的精度,一般设为0.01。
- line
- 输出的直线参数。2D 拟合情况下,它是包含 4 个浮点数的数组
(vx, vy, x0, y0),其中
(vx, vy)
是线的单位向量而(x0, y0)
是线上的某个点. 对 3D 拟合,它是包含 6 个浮点数的数组(vx, vy, vz, x0, y0, z0),
其中(vx, vy, vz)
是线的单位向量,而(x0, y0, z0)
是线上某点。
函数 cvFitLine 通过求 sumiρ(ri) 的最小值方法,用 2D 或 3D 点集拟合直线,其中 ri是第 i 个点到直线的距离, ρ(r) 是下面的距离函数之一:
dist_type=CV_DIST_L2 (L
2
): ρ(r)=r
2
/2 (最简单和最快的最小二乘法) dist_type=CV_DIST_L1 (L
1
): ρ(r)=r dist_type=CV_DIST_L12 (L
1
-L
2
): ρ(r)=2•[sqrt(1+r
2
/2) - 1] dist_type=CV_DIST_FAIR (Fair): ρ(r)=C
2
•[r/C - log(1 + r/C)], C=1.3998 dist_type=CV_DIST_WELSCH (Welsch): ρ(r)=C
2
/2•[1 - exp(-(r/C)
2
)], C=2.9846 dist_type=CV_DIST_HUBER (Huber): ρ(r)= r
2
/2, if r < C C•(r-C/2), otherwise; C=1.345
ConvexHull2
发现点集的凸外形
CvSeq* cvConvexHull2( const CvArr* input, void* hull_storage=NULL, int orientation=CV_CLOCKWISE, int return_points=0 );
- points
- 2D 点集的序列或数组,32-比特整数或浮点数坐标
- hull_storage
- 输出的数组(CvMat*) 或内存缓存 (CvMemStorage*),用以存储凸外形。 如果是数组,则它应该是一维的,而且与输入的数组/序列具有同样数目的元素。输出时修改头使得数组裁减到外形的尺寸。输出时,通过修改头结构将数组裁减到凸外形的尺寸。
- orientation
- 凸外形的旋转方向: 逆时针或顺时针 (
CV_CLOCKWISE
orCV_COUNTER_CLOCKWISE
) - return_points
- 如果非零,点集将以外形 (hull) 存储,而不是
hull_storage
为数组情况下的顶点形式 (indices) 以及hull_storag
为内存存储模式下的点集形式(points)。
函数 cvConvexHull2 使用 Sklansky 算法计算 2D 点集的凸外形。如果 hull_storage
是内存存储仓, 函数根据 return_points
的值,创建一个包含外形的点集或指向这些点的指针的序列。
例子. 由点集序列或数组创建凸外形
#include "cv.h"
#include "highgui.h"
#include <stdlib.h>
#define ARRAY 0
void main( int argc, char** argv ) {
IplImage* img = cvCreateImage( cvSize( , ), , ); cvNamedWindow( "hull", );
#if !ARRAY
CvMemStorage* storage = cvCreateMemStorage();
#endif
for(;;) {
int i, count = rand() + , hullcount;
CvPoint pt0;
#if !ARRAY
CvSeq* ptseq = cvCreateSeq( CV_SEQ_KIND_GENERIC|CV_32SC2, sizeof(CvContour), sizeof(CvPoint), storage );
CvSeq* hull;
for( i = ; i < count; i++ ) {
pt0.x = rand() % (img->width/) + img->width/;
pt0.y = rand() % (img->height/) + img->height/; cvSeqPush( ptseq, &pt0 );
}
hull = cvConvexHull2( ptseq, , CV_CLOCKWISE, ); hullcount = hull->total;
#else
CvPoint* points = (CvPoint*)malloc( count * sizeof(points[])); int* hull = (int*)malloc( count * sizeof(hull[]));
CvMat point_mat = cvMat( , count, CV_32SC2, points ); CvMat hull_mat = cvMat( , count, CV_32SC1, hull );
for( i = ; i < count; i++ ) {
pt0.x = rand() % (img->width/) + img->width/; pt0.y = rand() % (img->height/) + img->height/; points[i] = pt0;
}
cvConvexHull2( &point_mat, &hull_mat, CV_CLOCKWISE, ); hullcount = hull_mat.cols;
#endif cvZero( img );
for( i = ; i < count; i++ ) {
#if !ARRAY
pt0 = *CV_GET_SEQ_ELEM( CvPoint, ptseq, i );
#else
pt0 = points[i];
#endif
cvCircle( img, pt0, , CV_RGB( , , ), CV_FILLED );
}
#if !ARRAY
pt0 = **CV_GET_SEQ_ELEM( CvPoint*, hull, hullcount - ); #else
pt0 = points[hull[hullcount-]];
#endif
for( i = ; i < hullcount; i++ ) {
#if !ARRAY
CvPoint pt = **CV_GET_SEQ_ELEM( CvPoint*, hull, i );
#else
CvPoint pt = points[hull[i]];
#endif
cvLine( img, pt0, pt, CV_RGB( , , ));
pt0 = pt;
}
cvShowImage( "hull", img );
int key = cvWaitKey();
if( key == ) // 'ESC'
break;
#if !ARRAY
cvClearMemStorage( storage );
#else
free( points );
free( hull );
#endif
}
}
CheckContourConvexity
测试轮廓的凸性
int cvCheckContourConvexity( const CvArr* contour );
- contour
- 被测试轮廓 (点序列或数组).
函数 cvCheckContourConvexity输入的轮廓是否为凸的。必须是简单轮廓,比如没有自交叉。
CvConvexityDefect
用来描述一个简单轮廓凸性缺陷的结构体
typedef struct CvConvexityDefect { CvPoint* start; CvPoint* end; CvPoint* depth_point; float depth; } CvConvexityDefect;
Picture. Convexity defects of hand contour.
ConvexityDefects
发现轮廓凸形缺陷
CvSeq* cvConvexityDefects( const CvArr* contour, const CvArr* convexhull, CvMemStorage* storage=NULL );
- contour
- 输入轮廓
- convexhull
- 用 cvConvexHull2 得到的凸外形,它应该包含轮廓的定点或下标,而不是外形点的本身,即cvConvexHull2 中的参数
return_points
应该设置为 0. - storage
- 凸性缺陷的输出序列容器。如果为 NULL, 使用轮廓或外形的存储仓。
函数 cvConvexityDefects 发现输入轮廓的所有凸性缺陷,并且返回 CvConvexityDefect结构序列。
MinAreaRect2
对给定的 2D 点集,寻找最小面积的包围矩形
CvBox2D cvMinAreaRect2( const CvArr* points, CvMemStorage* storage=NULL );
- points
- 点序列或点集数组
- storage
- 可选的临时存储仓
函数 cvMinAreaRect2通过建立凸外形并且旋转外形以寻找给定 2D 点集的最小面积的包围矩形.
Picture. Minimal-area bounding rectangle for contour
MinEnclosingCircle
对给定的 2D 点集,寻找最小面积的包围圆形
int cvMinEnclosingCircle( const CvArr* points, CvPoint2D32f* center, float* radius );
- points
- 点序列或点集数组
- center
- 输出参数:圆心
- radius
- 输出参数:半径
函数 cvMinEnclosingCircle对给定的 2D 点集迭代寻找最小面积的包围圆形。如果产生的圆包含所有点,返回非零。否则返回零(算法失败)。
CalcPGH
计算轮廓的 pair-wise 几何直方图
void cvCalcPGH( const CvSeq* contour, CvHistogram* hist );
- contour
- 输入轮廓,当前仅仅支持具有整数坐标的点集
- hist
- 计算出的直方图,必须是两维的。
函数 cvCalcPGH 计算轮廓的 2D pair-wise(Hunnish: 不知如何翻译,只好保留) 几何直方图 (pair-wise geometrical histogram :PGH), 算法描述见 [Iivarinen97]. 算法考虑的每一对轮廓边缘。计算每一对边缘之间的夹角以及最大最小距离。具体做法是,轮流考虑每一个边缘做为基准,函数循环遍历所有边缘。在考虑基准边缘和其它边缘的时候, 选择非基准线上的点到基准线上的最大和最小距离。边缘之间的角度定义了直方图的行,而在其中增加对应计算出来的最大和最小距离的所有直方块, (即直方图是 [Iivarninen97] 定义中的转置). 该直方图用来做轮廓匹配。
opencv轮廓处理函数详细的更多相关文章
- 图像边缘检測--OpenCV之cvCanny函数
图像边缘检測--OpenCV之cvCanny函数 分类: C/C++ void cvCanny( const CvArr* image, CvArr* edges, double threshold1 ...
- OpenCV 轮廓基本特征
http://blog.csdn.net/tiemaxiaosu/article/details/51360499 OpenCV 轮廓基本特征 2016-05-10 10:26 556人阅读 评论( ...
- 【转载】openCV轮廓操作
声明:非原创,转载自互联网,有问题联系博主 1.轮廓的提取 从图片中将目标提取出来,常常用到的是提取目标的轮廓. OpenCV里提取目标轮廓的函数是findContours(), 它的输入图像是一幅二 ...
- 图像边缘检测--OpenCV之cvCanny函数
图像边缘检测--OpenCV之cvCanny函数 分类: C/C++ void cvCanny( const CvArr* image, CvArr* edges, double threshold1 ...
- 常用的OpenCV 2.0函数速查
OpenCV 2.0函数释义列表 1.cvLoadImage:将图像文件加载至内存: 2.cvNamedWindow:在屏幕上创建一个窗口: 3.cvShowImage:在一个已创建好的窗口中显示图像 ...
- 由lib引发的血案(opencv找不函数问题)
在使用opencv中的函数时,连续两次遇到函数找不到的问题,第一次查时按照他人说的包含进一个头文件后,果真还真解决了:然而第二次在调用cvInpaint函数时包含进对应头文件,编译通过但运行不成功还是 ...
- (原)使用opencv的warpAffine函数对图像进行旋转
转载请注明出处: http://www.cnblogs.com/darkknightzh/p/5070576.html 参考网址: http://stackoverflow.com/questions ...
- Signal ()函数详细介绍 Linux函数
http://blog.csdn.net/ta893115871/article/details/7475095 Signal ()函数详细介绍 Linux函数 signal()函数理解 在<s ...
- Signal ()函数详细介绍 Linux函数(转)
Signal ()函数详细介绍 Linux函数 收藏人:紫火神兵 2012-09-27 | 阅:5659 转:22 | 来源 | 分享 signa ...
随机推荐
- PL SQL Developer报错框乱码
在系统变量里设置 变量名:NLS_LANG 变量值设为:SIMPLIFIED CHINESE_CHINA.ZHS16GBK
- 【实验室笔记】C#以本地时间创建txt文件
前段时间做的一个小项目,要求上位机在打开时候,以打开软件的系统时间的建立一个txt文件来存储下位机发送来的数据. 在第一版上位机上,取名的办法太弱了,先是读取系统时间,然后截取字符串,太笨拙.昨天,查 ...
- C# 委托的三种调用示例(同步调用 异步调用 异步回调)
首先,通过代码定义一个委托和下面三个示例将要调用的方法: 复制代码 代码如下: public delegate int AddHandler(int a,int b); public class ...
- log4j.properties 的使用详解
一.log4j.properties 的使用详解 1.输出级别的种类 ERROR.WARN.INFO.DEBUGERROR 为严重错误 主要是程序的错误WARN 为一般警告,比如session丢失IN ...
- 代码块(Block)回调一般阐述
本章教程主要对代码块回调模式进行讲解,已经分析其他回调的各种优缺点和适合的使用场景. 代码块机制 Block变量类型 Block代码封装及调用 Block变量对普通变量作用域的影响 Block回调接口 ...
- screen实现关闭ssh之后继续运行代码
本文基于Ubuntu 14.04 使用SSH连接远程服务器,启动服务,退出SSH后,服务也就终止了,使用Screen可以解决这个问题. 1.安装Screen apt-get install scree ...
- 第六十五,html嵌入元素
html嵌入元素 学习要点: 1.嵌入元素总汇 2.嵌入元素解析 本章主要探讨HTML5中嵌入元素,嵌入元素主要功能是把外部的一些资源插入到HTML中. 一.嵌入元素总汇 ...
- JS复习:第二十三章
一.Cookie的构成: 1.名称:一个唯一确定cookie的名称.cookie名称不区分大小写,必须是经过URL编码的. 2.值:存储在cookie中的字符串值,必须被URL编码. 3.域:cook ...
- apache动态添加模块
Apache已经安装完毕并投入运行,但是后来却发现部分模块没有加载,当然有两个方法: 1. 一是完全重新编译Apache, 再安装 2. 编译模块为SO文件,使用LoadModule指令加载扩展模块. ...
- HDU 3404&POJ 3533 Nim积(二维&三维)
(Nim积相关资料来自论文曹钦翔<从"k倍动态减法游戏"出发探究一类组合游戏问题>) 关于Nim积计算的两个函数流程: 代码实现如下: ][]={,,,}; int N ...