OpenCV学习笔记.docx
- 文档编号:9388260
- 上传时间:2023-05-18
- 格式:DOCX
- 页数:15
- 大小:24.13KB
OpenCV学习笔记.docx
《OpenCV学习笔记.docx》由会员分享,可在线阅读,更多相关《OpenCV学习笔记.docx(15页珍藏版)》请在冰点文库上搜索。
OpenCV学习笔记
OpenCV学习笔记(三)人脸检测的代码分析
一、预备知识:
1、动态内存存储及操作函数
CvMemStorage
1.typedef struct CvMemStorage
2.{
3. struct CvMemBlock* bottom;/* first allocated block */
4. struct CvMemBlock* top; /* the current memory block-top of the stack*/
5. struct CvMemStorage* parent; /* borrows new blocks from */
6. int block_size; /* block size */
7. int free_space; /* free space in the top block (in bytes) */
8.} CvMemStorage;
内存存储器是一个可用来存储诸如序列,轮廓,图形,子划分等动态增长数据结构的底层结构。
它是由一系列以同等大小的内存块构成,呈列表型---bottom域指的是列首,top域指的是当前指向的块但未必是列尾.在bottom和top之间所有的块(包括bottom,不包括top)被完全占据了空间;在top和列尾之间所有的块(包括块尾,不包括top)则是空的;而top块本身则被占据了部分空间--free_space指的是top块剩余的空字节数。
新分配的内存缓冲区(或显示的通过cvMemStorageAlloc函数分配,或隐示的通过cvSeqPush,cvGraphAddEdge等高级函数分配)总是起始于当前块(即top块)的剩余那部分,如果剩余那部分能满足要求(够分配的大小)。
分配后,free_space就减少了新分配的那部分内存大小,外加一些用来保存适当列型的附加大小。
当top块的剩余空间无法满足被分配的块(缓冲区)大小时,top块的下一个存储块被置为当前块(新的top块)-- free_space被置为先前分配的整个块的大小。
如果已经不存在空的存储块(即:
top块已是列尾),则必须再分配一个新的块(或从parent那继承,见cvCreateChildMemStorage)并将该块加到列尾上去。
于是,存储器(memorystorage)就如同栈(Stack)那样,bottom指向栈底,(top,free_space)对指向栈顶。
栈顶可通过cvSaveMemStoragePos保存,通过cvRestoreMemStoragePos恢复指向,通过cvClearStorage重置。
CvMemBlock
内存存储块结构
typedefstructCvMemBlock
{
structCvMemBlock*prev;
structCvMemBlock*next;
}CvMemBlock;
CvMemBlock代表一个单独的内存存储块结构。
内存存储块中的实际数据存储在header块之后(即:
存在一个头指针head指向的块header,该块不存储数据),于是,内存块的第i个字节可以通过表达式((char*)(mem_block_ptr+1))[i]获得。
然而,通常没必要直接去获得存储结构的域。
CvMemStoragePos
内存存储块地址
typedefstructCvMemStoragePos
{
CvMemBlock*top;
intfree_space;
}CvMemStoragePos;
该结构(如以下所说)保存栈顶的地址,栈顶可以通过cvSaveMemStoragePos保存,也可以通过cvRestoreMemStoragePos恢复。
________________________________________
cvCreateMemStorage
创建内存块
CvMemStorage*cvCreateMemStorage(intblock_size=0);
block_size:
存储块的大小以字节表示。
如果大小是0byte,则将该块设置成默认值 当前默认大小为64k.
函数cvCreateMemStorage创建一内存块并返回指向块首的指针。
起初,存储块是空的。
头部(即:
header)的所有域值都为0,除了block_size外.
________________________________________
cvCreateChildMemStorage
创建子内存块
CvMemStorage*cvCreateChildMemStorage(CvMemStorage*parent);
parent 父内存块
函数cvCreateChildMemStorage创建一类似于普通内存块的子内存块,除了内存分配/释放机制不同外。
当一个子存储块需要一个新的块加入时,它就试图从parent那得到这样一个块。
如果parent中还未被占据空间的那些块中的第一个块是可获得的,就获取第一个块(依此类推),再将该块从parent 那里去除。
如果不存在这样的块,则parent要么分配一个,要么从它自己parent(即:
parent的parent)那借个过来。
换句话说,完全有可能形成一个链或更为复杂的结构,其中的内存存储块互为child/parent关系(父子关系)。
当子存储结构被释放或清除,它就把所有的块还给各自的parent.在其他方面,子存储结构同普通存储结构一样。
子存储结构在下列情况中是非常有用的。
想象一下,如果用户需要处理存储在某个块中的动态数据,再将处理的结果存放在该块中。
在使用了最简单的方法处理后,临时数据作为输入和输出数据被存放在了同一个存储块中,于是该存储块看上去就类似下面处理后的样子:
Dynamicdataprocessingwithoutusingchildstorage.结果,在存储块中,出现了垃圾(临时数据)。
然而,如果在开始处理数据前就先建立一个子存储块,将临时数据写入子存储块中并在最后释放子存储块,那么最终在源/目的存储块(source/destinationstorage)中就不会出现垃圾,于是该存储块看上去应该是如下形式:
Dynamicdataprocessingusingachildstorage.
cvReleaseMemStorage
释放内存块
voidcvReleaseMemStorage(CvMemStorage**storage);
storage:
指向被释放了的存储块的指针
函数cvReleaseMemStorage释放所有的存储(内存)块或者将它们返回给各自的parent(如果需要的话)。
接下来再释放header块(即:
释放头指针head指向的块=free(head))并清除指向该块的指针(即:
head=NULL)。
在释放作为parent的块之前,先清除各自的child块。
cvClearMemStorage
清空内存存储块
voidcvClearMemStorage(CvMemStorage*storage);
storage:
存储存储块
函数cvClearMemStorage将存储块的top置到存储块的头部(注:
清空存储块中的存储内容)。
该函数并不释放内存(仅清空内存)。
假使该内存块有一个父内存块(即:
存在一内存块与其有父子关系),则函数就将所有的块返回给其parent.
cvMemStorageAlloc
在存储块中分配以内存缓冲区
void*cvMemStorageAlloc(CvMemStorage*storage,size_tsize);
storage:
内存块.
size:
缓冲区的大小.
函数cvMemStorageAlloc在存储块中分配一内存缓冲区。
该缓冲区的大小不能超过内存块的大小,否则就会导致运行时错误。
缓冲区的地址被调整为CV_STRUCT_ALIGN字节(当前为sizeof(double)).
cvMemStorageAllocString
在存储块中分配一文本字符串
typedefstructCvString
{
intlen;
char*ptr;
}
CvString;
CvStringcvMemStorageAllocString(CvMemStorage*storage,constchar*ptr,intlen=-1);
storage:
存储块
ptr:
字符串
len:
字符串的长度(不计算'\0')。
如果参数为负数,函数就计算该字符串的长度。
函数cvMemStorageAlloString在存储块中创建了一字符串的拷贝。
它返回一结构,该结构包含字符串的长度(该长度或通过用户传递,或通过计算得到)和指向被拷贝了的字符串的指针。
cvSaveMemStoragePos
保存内存块的位置(地址)
voidcvSaveMemStoragePos(constCvMemStorage*storage,CvMemStoragePos*pos);
storage:
内存块.
pos:
内存块顶部位置。
函数cvSaveMemStoragePos将存储块的当前位置保存到参数pos中。
函数cvRestoreMemStoragePos可进一步获取该位置(地址)。
cvRestoreMemStoragePos
恢复内存存储块的位置
voidcvRestoreMemStoragePos(CvMemStorage*storage,CvMemStoragePos*pos);
storage:
内存块.
pos:
新的存储块的位置
函数cvRestoreMemStoragePos通过参数pos恢复内存块的位置。
该函数和函数cvClearMemStorage是释放被占用内存块的唯一方法。
注意:
没有什么方法可去释放存储块中被占用的部分内存。
2、分类器结构及操作函数:
CvHaarFeature
1.#define CV_HAAR_FEATURE_MAX 3
2.typedef struct CvHaarFeature
3.{
4. int tilted;
5. struct
6. {
7. CvRect r;
8. float weight;
9.} rect[CV_HAAR_FEATURE_MAX];
10.
11.}
CvHaarFeature;
一个harr特征由2-3个具有相应权重的矩形组成
titled:
/*0meansup-rightfeature,1means45--rotatedfeature*/
rect[CV_HAAR_FEATURE_MAX];
/*2-3rectangleswithweightsofoppositesignsand withabsolute
valuesinverselyproportionaltotheareasoftherectangles.
ifrect[2].weight!
=0,then thefeatureconsistsof3rectangles,
otherwiseitconsistsof2*/
CvHaarClassifier
1.typedef struct CvHaarClassifier
2.{
3. int count;
4. CvHaarFeature* haar_feature;
5. float* threshold;
6. int* left;
7. int* right;
8. float* alpha;
9.}CvHaarClassifier;
/*asingletreeclassifier(stumpinthesimplestcase)thatreturnstheresponse
forthefeature attheparticularimagelocation(i.e.pixelsumoversubrectangles
ofthewindow)andgivesoutavaluedependingontheresponce*/
intcount; /*numberofnodesinthedecisiontree*/
/*theseare"parallel"arrays.Everyindexicorrespondstoanodeofthedecisiontree(roothas0-thindex).
left[i]-indexoftheleftchild(ornegatedindexiftheleftchildisaleaf)
right[i]-indexoftherightchild(ornegatedindexiftherightchildisaleaf)
threshold[i]-branchthreshold.iffeatureresponceis<=threshold,leftbranch
ischosen,otherwiserightbranchischosed.
alpha[i]-outputvaluecorrepondingtotheleaf.*/
CvHaarStageClassifier
1.typedef struct CvHaarStageClassifier
2.{
3. int count; /* number of classifiers in the battery */
4. float threshold; /* threshold for the boosted classifier */
5. CvHaarClassifier* classifier; /* array of classifiers */
6. /* these fields are used for organizing trees of stage classifiers,
7. rather than just stright cascades */
8. int next;
9. int child;
10. int parent;
11.}
12.CvHaarStageClassifier;
/*aboostedbatteryofclassifiers(=stageclassifier):
thestageclassifierreturns1ifthesumoftheclassifiers'responcesisgreaterthanthresholdand0otherwise*/
int count; /*numberofclassifiersinthebattery*/
floatthreshold;/*thresholdfortheboostedclassifier*/
CvHaarClassifier*classifier;/*arrayofclassifiers*/
/*thesefieldsareusedfororganizingtreesofstageclassifiers,ratherthanjuststrightcascades*/
CvHaarClassifierCascade
1.typedef struct CvHidHaarClassifierCascade CvHidHaarClassifierCascade;
2.typedef struct CvHaarClassifierCascade
3.{
4. int flags;
5. int count;
6. CvSize orig_window_size;
7. CvSize real_window_size;
8. double scale;
9. CvHaarStageClassifier* stage_classifier;
10. CvHidHaarClassifierCascade* hid_cascade;
11.}
12.CvHaarClassifierCascade;
13.
14./* cascade or tree of stage classifiers */
15.int flags; /* signature */
16.int count; /* number of stages */
17.CvSize orig_window_size; /* original object size (the cascade is trained for) */
18./* these two parameters are set by cvSetImagesForHaarClassifierCascade */
19.CvSize real_window_size; /* current object size */
20.double scale; /* current scale */
21.CvHaarStageClassifier* stage_classifier; /* array of stage classifiers */
22.CvHidHaarClassifierCascade* hid_cascade;
23./* hidden optimized representation of the cascade,
24. created by cvSetImagesForHaarClassifierCascade */
所有的结构都代表一个级联boostedHaar分类器。
级联有下面的等级结构:
Cascade:
Stage1:
Classifier11:
Feature11
Classifier12:
Feature12
...
Stage2:
Classifier21:
Feature21
...
...
整个等级可以手工构建,也可以利用函数cvLoadHaarClassifierCascade从已有的磁盘文件或嵌入式基中导入。
特征检测用到的函数:
cvLoadHaarClassifierCascade
从文件中装载训练好的级联分类器或者从OpenCV中嵌入的分类器数据库中导入
CvHaarClassifierCascade*cvLoadHaarClassifierCascade(
constchar*directory,
CvSizeorig_window_size);
directory:
训练好的级联分类器的路径
orig_window_size:
级联分类器训练中采用的检测目标的尺寸。
因为这个信息没有在级联分类器中存储,所有要单独指出。
函数cvLoadHaarClassifierCascade用于从文件中装载训练好的利用海尔特征的级联分类器,或者从OpenCV中嵌入的分类器数据库中导入。
分类器的训练可以应用函数haartraining(详细察看opencv/apps/haartraining)
函数已经过时了。
现在的目标检测分类器通常存储在 XML或YAML文件中,而不是通过路径导入。
从文件中导入分类器,可以使用函数cvLoad。
cvReleaseHaarClassifierCascade
释放haarclassifiercascade。
voidcvReleaseHaarClassifierCascade(CvHaarClassifierCascade**cascade);
cascade:
双指针类型指针指向要释放的cascade.指针由函数声明。
函数cvReleaseHaarClassifierCascade释放cascade的动态内存,其中cascade的动态内存或者是手工创建,或者通过函数cvLoadHaarClassifierCascade或cvLoad分配。
cvHaarDetectObjects
检测图像中的目标
1.typedef struct CvAvgComp
2.{
3.CvRect rect; /* bounding rectangle for the object (average rectangle of a group) */
4.int neighbors; /* number of neighbor rectangles in the group */
5.}
6.CvAvgComp;
7.CvSeq* cvHaarDetectObjects( const CvArr* image,
8.CvHaarClassifierCascade* cascade,
9.CvMemStorage* storage,
10.double scale_factor=1.1,
11.int min_neighbors=3, int flags=0,
12.CvSize min_size=cvSize(0,0) );
image被检图像
cascadeharr分类器级联的内部标识形式
storage用来存储检测到的一序列候选目标矩形框的内存区域。
scale_factor在前后两次相继的扫描中,搜索窗口的比例系数。
例如1.1指将搜索窗口依次扩大10%。
min_neighbors构成检测目标的相邻矩形的最小个数(缺省-1)。
如果组成检测目标的小矩形的个数和小于min_neighbors-1都会被排除。
如果min_neighbors为0,则函数不做任何操作就返回所有的被检候选矩形框,这种
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- OpenCV 学习 笔记
![提示](https://static.bingdoc.com/images/bang_tan.gif)