搜档网
当前位置:搜档网 › OpenCV学习笔记之人脸检测的代码分析

OpenCV学习笔记之人脸检测的代码分析

OpenCV学习笔记之人脸检测的代码分析
OpenCV学习笔记之人脸检测的代码分析

/* cascade or tree of stage classifiers */

int flags; /* signature */

int count; /* number of stages */

CvSize orig_window_size; /* original object size (the cascade is trained for) */

/* these two parameters are set by cvSetImagesForHaarClassifierCascade */

CvSize real_window_size; /* current object size */

double scale; /* current scale */

CvHaarStageClassifier* stage_classifier; /* array of stage classifiers */ CvHidHaarClassifierCascade* hid_cascade; /* hidden optimized representation of the cascade, created by cvSetImagesForHaarClassifierCascade */

所有的结构都代表一个级联boosted Haar分类器。级联有下面的等级结构:Cascade:

Stage1:

Classifier11:

Feature11

Classifier12:

Feature12

...

Stage2:

Classifier21:

Feature21

...

...

全部等级可以手农构修,也可以应用函数cvLoadHaarClassifierCascade从已有的磁盘文件或嵌进式基中导进。

特征检测用到的函数:

cvLoadHaarClassifierCascade

从文件中装载练习佳的级联分类器或者从OpenCV中嵌入的分类器数据库中导入

CvHaarClassifierCascade* cvLoadHaarClassifierCascade(

const char* directory,

CvSize orig_window_size );

directory :练习的级联分类器的门路

orig_window_size:级联分类器训练中采取的检测目标的尺寸。由于这个信息没有在级联分类器中存储,所有要共同指出。

函数cvLoadHaarClassifierCascade 用于从文件中装载训练赖的利用海尔特点的级联分类器,或者从OpenCV中嵌入的分类器数据库中导入。分类器的训练可以利用函数haartraining(具体观察opencv/apps/haartraining)

函数已经过期了。当初的目标检测分类器通常存储在XML 或YAML 文件中,而不是通过路径导入。从文件中导入分类器,可以使用函数cvLoad 。cvReleaseHaarClassifierCascade

释放haar classifier cascade。

void cvReleaseHaarClassifierCascade( CvHaarClassifierCascade** cascade ); cascade :单指针类型指针指向要释放的cascade. 指针由函数申明。

函数cvReleaseHaarClassifierCascade 开释cascade的动态内存,其中cascade的动态内存或者是手工创立,或者通过函数cvLoadHaarClassifierCascade 或cvLoad分配。

cvHaarDetectObjects

检测图像中的目标

typedef struct CvAvgComp

{

CvRect rect; /* bounding rectangle for the object (average rectangle of a group) */

int neighbors; /* number of neighbor rectangles in the group */

}

CvAvgComp;

CvSeq* cvHaarDetectObjects( const CvArr* image,

CvHaarClassifierCascade* cascade,

CvMemStorage* storage,

double scale_factor=1.1,

int min_neighbors=3, int flags=0,

CvSize min_size=cvSize(0,【强】看看牛人是怎样用4句话来概括四大名著的!!!,0) );

image 被检图像

cascade harr 分类器级联的内部标识情势

storage 用来存储检测到的一序列候选目的矩形框的内存区域。

scale_factor 在前后两次接踵的扫描中,搜索窗口的比例系数。例如1.1指将搜索窗口顺次扩展10%。

min_neighbors 构成检测目标的相邻矩形的最小个数(缺费-1)。如果组成检测目标的小矩形的个数和小于min_neighbors-1 都会被消除。如果min_neighbors 为0, 则函数不干免何操作就返回所有的被检候选矩形框,这种设定值普通用在用户自定义对检测成果的组折程序上。

flags 操作方法。当前独一能够定义的操作方法是CV_HAAR_DO_CANNY_PRUNING,未满18别入,入了也看不懂。假如被设定,函数应用Canny边沿检测器来消除一些边沿很少或者良多的图像区域,由于这样的区域个别不露被检目的。己脸检测中通过设定阈值应用了这种方式,并因而进步了检测快度。

min_size 检测窗口的最小尺寸。缺省的情形下被设为分类器训练时采取的样利尺寸(我脸检测中缺省大小是~20×20)。

函数cvHaarDetectObjects 使用针对某目标物体练习的级联分类器在图像中找到包括目标物体的矩形区域,并且将这些区域作为一序列的矩形框返回。函数以不同比例大小的扫描窗口对图像进行几回搜寻(观察cvSetImagesForHaarClassifierCascade)。每次都要对图像中的这些重叠区域利用cvRunHaarClassifierCascade进行检测。有时候也会利用某些继续(heuristics)技巧以减少剖析的候选区域,例如利用Canny 裁减(prunning)方式。函数在处置和发集到候选的方框(全体通过级联分类器各层的区域)之后,接着对这些区域进行组合并且返回一系列各个脚够大的组合中的均匀矩形。调节程序中的缺省参数(scale_factor=1.1, min_neighbors=3, flags=0)用于对目标进行更准确同时也是耗时较长的进一步检测。为了能对视频图像进行更钝的名时检测,参数设置通

常是:scale_factor=1.2, min_neighbors=2, flags=CV_HAAR_DO_CANNY_PRUNING, min_size= (例如, 对视频会议的图像区域). cvSetImagesForHaarClassifierCascade

为暗藏的cascade(hidden cascade)指定图像

void cvSetImagesForHaarClassifierCascade( CvHaarClassifierCascade* cascade,

const CvArr* sum, const CvArr* sqsum,

const CvArr* tilted_sum, double scale );

cascade 暗藏Harr 分类器级联(Hidden Haar classifier cascade), 由函数cvCreateHidHaarClassifierCascade天生

sum 32-比特,单通谈图像的积分图像(Integral (sum) 单通说image of 32-比特integer format). 这幅图像以及随后的二幅用于对疾速特点的评估和明度/对照度的回一化。它们皆可以利用函数cvIntegral从8-比特或浮点数单通路的输进图像中得到。

sqsum 单通讲64比特图像的平方和图像

tilted_sum 单通叙32比特整数格局的图像的倾斜和(Tilted sum)

scale cascade的窗口比例. 如果scale=1, 就只用原始窗口尺寸检测(只检测同样尺寸大小的目标物体) - 原始窗口尺寸在函数cvLoadHaarClassifierCascade中定义(在""中缺省为24x24), 如果scale=2, 使用的窗口是上面的两倍(在face cascade中缺省值是48x48 )。这样只管可以将检测速度进步四倍,但同时尺寸小于48x48的人脸将不能被检测到。

函数cvSetImagesForHaarClassifierCascade 为hidden classifier cascade 指定图像and/or 窗口比例系数。如果图像指针为空,会持续使用本来的图像(i.e. NULLs 象征这"不转变图像")。比例系数不"protection" 值,然而本来的值可以通过函数cvGetHaarClassifierCascadeScale 重新得到并使用。这个函数用于对特定图像中检测特定目标尺寸的cascade分类器的设定。函数通过cvHaarDetectObjects进行内部调用,但当须要在更低一层的函数cvRunHaarClassifierCascade中使用的时候,用户也可以自行调用。

cvRunHaarClassifierCascade

在给定地位的图像中运言cascade of boosted classifier

int cvRunHaarClassifierCascade( CvHaarClassifierCascade* cascade,

CvPoint pt, int start_stage=0 );

cascade Haar 级联分类器

pt 待检测区域的左上角卧标。待检测区域大小为本始窗口尺寸趁以当前设定的比例系数。当前窗口尺寸可以通过cvGetHaarClassifierCascadeWindowSize从新得到。

start_stage 级联层的初始下标值(从0开端计数)。函数假设后面所有每层的分类器都已通过。这个特征通过函数cvHaarDetectObjects内部调用,用于更美的处理器高速缓冲存储器。

函数cvRunHaarHaarClassifierCascade 用于对单幅图片的检测。在函数调用前首先应用cvSetImagesForHaarClassifierCascade设定积分图和适合的比例系数(=> 窗心尺寸)。当剖析的矩形框全体通过级联分种器每一层的时返回正值(这是一个候选目的),否则返回0或背值。

二、例程剖析:

例子:害用级联的Haar classifiers觅找检测纲标(e.g. faces).

#include "cv.h"

#include "highgui.h"

//读取训练好的分类器。

CvHaarClassifierCascade* load_object_detector( const char* cascade_path )

{

return (CvHaarClassifierCascade*)cvLoad( cascade_path );

}

void detect_and_draw_objects( IplImage* image,

CvHaarClassifierCascade* cascade,

int do_pyramids )

{

IplImage* small_image = image;

CvMemStorage* storage = cvCreateMemStorage(0); //创建动态内存

CvSeq* faces;

int i, scale = 1;

/* if the flag is specified, down-scale the 输入图像to get a

performance boost w/o loosing quality (perhaps) */

if( do_pyramids )

{

small_image = cvCreateImage( cvSize(image->width/2,image->height/2), IPL_DEPTH_8U, 3 );

cvPyrDown( image, small_image, CV_GAUSSIAN_5x5 );//函数cvPyrDown 应用Gaussian 金字塔合成对输入图像向下采样。首先它对输入图像用指定滤波器入行舒积,而后通过谢绝偶数的走取列来下采样图像。

scale = 2;

}

/* use the fastest variant */

faces = cvHaarDetectObjects( small_image, cascade, storage, 1.2, 2, CV_HAAR_DO_CANNY_PRUNING );

/* draw all the rectangles */

for( i = 0; i < faces->total; i++ )

{

/* extract the rectanlges only */

CvRect face_rect = *(CvRect*)cvGetSeqElem( faces, i, 0 );

cvRectangle( image, cvPoint(face_rect.x*scale,face_rect.y*scale),

cvPoint((face_rect.x+face_rect.width)*scale,

(face_rect.y+face_rect.height)*scale),

CV_RGB(255,0,0), 3 );

}

if( small_image != image )

cvReleaseImage( &small_image );

cvReleaseMemStorage( &storage ); //释放动态内存

}

/* takes image filename and cascade path from the command line */

int main( int argc, char** argv )

{

IplImage* image;

if( argc==3 && (image = cvLoadImage( argv[1], 1 )) != 0 )

{

CvHaarClassifierCascade* cascade = load_object_detector(argv[2]);

detect_and_draw_objects( image, cascade, 1 );

cvNamedWindow( "test", 0 );

cvShowImage( "test", image );

cvWaitKey(0);

cvReleaseHaarClassifierCascade( &cascade );

cvReleaseImage( &image );

}

return 0;

}

要害代码很简略,装载分类器,对输入图像进行金字塔采样,然后用cv的函数进行检测目标,最后输出检测到的目标矩形。

一、准备常识:

1、动态内存存储及操作函数

CvMemStorage

typedef struct CvMemStorage

{

struct CvMemBlock* bottom;/* first allocated block */

struct CvMemBlock* top; /* the current memory block - top of the stack */

struct CvMemStorage* parent; /* borrows new blocks from */

int block_size; /* block size */

int free_space; /* free space in the top block (in bytes) */

} 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)并将当块添到列尾上往。于是,存储器(memory storage)就犹如栈(Stack)那样, bottom指向栈顶,(top, free_space)对指向栈顶。栈底可通

过cvSaveMemStoragePos保存,通过cvRestoreMemStoragePos 复原指向,通功cvClearStorage 沉置。

CvMemBlock

内存存储块结构

typedef struct CvMemBlock

{

struct CvMemBlock* prev;

struct CvMemBlock* next;

} CvMemBlock;

CvMemBlock 代表一个独自的内存存储块结构。内存存储块中的理论数据存储在header块之后(即:存在一个头指针head 指向的块header ,该块不存储数据),3.22变态魔兽私服,于是,内存块的第i 个字节可以通过表白式((char*)(mem_block_ptr+1))[i] 失掉。然而,通常没必要直接去获得存储结构的域。CvMemStoragePos

内存存储块地址

typedef struct CvMemStoragePos

{

CvMemBlock* top;

int free_space;

} CvMemStoragePos;

该结构(如以下所说)保留栈顶的地址,栈顶可以通过cvSaveMemStoragePos 保存,也可以通过cvRestoreMemStoragePos 恢复。

________________________________________

cvCreateMemStorage

创立内存块

CvMemStorage* cvCreateMemStorage( int block_size=0 );

block_size:存储块的大小以字节表现。如果大小是0 byte, 则将该块设置成默认值当前默认大小为64k.

函数cvCreateMemStorage 创建一内存块并返回指向块首的指针。讫始,存储块是空的。头部(即:header)的所有域值都为0,除了block_size 外.

________________________________________

cvCreateChildMemStorage

创建子内存块

CvMemStorage* cvCreateChildMemStorage( CvMemStorage* parent );

parent 父内存块

函数cvCreateChildMemStorage 创建一相似于普通内存块的子内存块,除了内存分配/释放机造不同外。当一个子存储块需要一个新的块参加时,它就试图从parent 那得到这样一个块。如果parent 中还未被盘踞空间的那些块中的第一个块是可取得的,就获弃第一个块(依此类拉),再将该块从parent 那面往除。如果不存在这样的块,则parent 要么分配一个,要么从它本人parent (即:parent 的parent) 那借个过去。换句话说,完整有可能构成一个链或更为庞杂的结构,其中的内存存储块互为child/ parent 关系(父子关系)。当子存储结构被释放或肃清,它就把所有的块还给各自的parent. 在其余方面,子存储结构共一般存储结构一样。

子存储构造在下列情形中是十分有用的。设想一下,如果用户须要处理存储在某个块中的动态数据,再将处置的成果寄存在该块中。在应用了最简略的方式处理后,常设数据作为输入和输没数据被寄存在了统一个存储块中,于是该存储块望上去就相似下点处置后的样子:Dynamic data processing without using child storage. 成果,在存储块中,呈现了垃圾(长期数据)。然而,如果在开端处理数据前就先树立一个子存储块,将暂时数据写入子存储块中并在最后开释子存储块,那么终极在源/目标存储块(source / destination storage) 中就不会涌现垃圾, 于是该存储块瞅上往应当是如下情势:Dynamic data processing using a child storage.

cvReleaseMemStorage

释放内存块

void cvReleaseMemStorage( CvMemStorage** storage );

storage: 指向被释放了的存储块的指针

函数cvReleaseMemStorage 释抬所有的存储(内存)块或将它们返归给各从的parent(假如须要的话)。交下来再开释header块(即:释放头指针head 指向的块= free(head))并扫除指向该块的指针(即:head = NULL)。在释置息为parent 的块之前,先肃清各自的child 块。

cvClearMemStorage

清空内存存储块

void cvClearMemStorage( CvMemStorage* storage );

storage:存贮存储块

函数cvClearMemStorage 将存储块的top 置到存储块的头部(注:清空存储块中的存储内容)。该函数并不释放内存(仅清空内存)。倘若该内存块有一个父内存块(即:存在一内存块与其有父子关系),则函数就将所有的块返回给其parent. cvMemStorageAlloc

在存储块中分配以内存缓冲区

void* cvMemStorageAlloc( CvMemStorage* storage, size_t size );

storage:内存块.

size:缓冲区的大小.

函数cvMemStorageAlloc 在存储块中分配一内存缓冲区。该缓冲区的大小不能超过内存块的大小,否则就会导致运行时过错。缓冲区的地址被调剂为CV_STRUCT_ALIGN 字节(当前为sizeof(double)). cvMemStorageAllocString

在存储块中分配一文标字符串

typedef struct CvString

{

int len;

char* ptr;

}

CvString;

CvString cvMemStorageAllocString( CvMemStorage* storage, const char* ptr, int len=-1 );

storage:存储块

ptr:字符串

len:字符串的长度(不盘算'\0')。如果参数为负数,函数就盘算该字符串的长度。函数cvMemStorageAlloString 在存储块中创立了一字符串的拷贝。它返回一构造,今天,我又想你,该结构包括字符串的长度(该长度或通过用户传递,或通过盘算得到)和指向被拷贝了的字符串的指针。

cvSaveMemStoragePos

保存内存块的位置(地址)

void cvSaveMemStoragePos( const CvMemStorage* storage, CvMemStoragePos* pos );

storage:内存块.

pos:内存块顶部位置。

函数cvSaveMemStoragePos 将存储块确当前位置保留到参数pos 中。函数cvRestoreMemStoragePos 可进一步获与该地位(地址)。cvRestoreMemStoragePos

恢复内存存储块的位置

void cvRestoreMemStoragePos( CvMemStorage* storage, CvMemStoragePos* pos ); storage:内存块.

pos:新的存储块的地位

函数cvRestoreMemStoragePos 通过参数pos 恢复内存块的位置。该函数和函数cvClearMemStorage 是释放被占用内存块的唯一办法。留神:没有什么办法可去释放存储块中被占用的部分内存。

2、分类器结构及操作函数:

CvHaarFeature

#define CV_HAAR_FEATURE_MAX 3

typedef struct CvHaarFeature

{

int tilted;

struct

{

CvRect r;

float weight;

} rect[CV_HAAR_FEATURE_MAX];

}

CvHaarFeature;

一个harr 特点由2-3 个存在相应权重的矩形组成

titled :/* 0 means up-right feature, 1 means 45--rotated feature */

rect[CV_HAAR_FEATURE_MAX]; /* 2-3 rectangles with weights of opposite signs and with absolute values inversely proportional to the areas of the rectangles. if rect[2].weight !=0, then the feature consists of 3 rectangles, otherwise it consists of 2 */

CvHaarClassifier

typedef struct CvHaarClassifier

{

int count;

CvHaarFeature* haar_feature;

float* threshold;

int* left;

int* right;

float* alpha;

}

CvHaarClassifier;

/* a single tree classifier (stump in the simplest case) that returns the response for the feature at the particular image location (i.e. pixel sum over subrectangles of the window) and gives out a value depending on the responce */

int count; /* number of nodes in the decision tree */

/* these are "parallel" arrays. Every index i corresponds to a node of the decision tree (root has 0-th index).

left[i] - index of the left child (or negated index if the left child is a leaf)

right[i] - index of the right child (or negated index if the right child is a leaf) threshold[i] - branch threshold. if feature responce is <= threshold, left branch is chosen, otherwise right branch is chosed.

alpha[i] - output value correponding to the leaf. */

CvHaarStageClassifier

typedef struct CvHaarStageClassifier

{

int count; /* number of classifiers in the battery */

float threshold; /* threshold for the boosted classifier */

CvHaarClassifier* classifier; /* array of classifiers */

/* these fields are used for organizing trees of stage classifiers,

rather than just stright cascades */

int next;

int child;

int parent;

}

CvHaarStageClassifier;

/* a boosted battery of classifiers(=stage classifier): the stage classifier returns 1 if the sum of the classifiers' responces is greater than threshold and 0 otherwise */

int count; /* number of classifiers in the battery */

float threshold; /* threshold for the boosted classifier */

CvHaarClassifier* classifier; /* array of classifiers */

/* these fields are used for organizing trees of stage classifiers, rather than just stright cascades */

CvHaarClassifierCascade

typedef struct CvHidHaarClassifierCascade CvHidHaarClassifierCascade;

typedef struct CvHaarClassifierCascade

{

int flags;

int count;

CvSize orig_window_size;

CvSize real_window_size;

double scale;

CvHaarStageClassifier* stage_classifier;

CvHidHaarClassifierCascade* hid_cascade; }

CvHaarClassifierCascade;

基于opencv的人脸识别程序-代码详解

#include "cv.h" #include "highgui.h" #include #ifdef _EiC #define WIN32 #endif static CvMemStorage* storage = 0; static CvHaarClassifierCascade* cascade = 0; void detect_and_draw( IplImage* image ); const char* cascade_name = "haarcascade_frontalface_alt.xml";//人脸检测分类器 int main( int argc, char** argv ) { CvCapture* capture = 0; IplImage *frame, *frame_copy = 0; int optlen = strlen("--cascade="); const char* input_name; if( argc > 1 && strncmp( argv[1], "--cascade=", optlen ) == 0 ) { cascade_name = argv[1] + optlen; input_name = argc > 2 ? argv[2] : 0; } else { cascade_name = "E:\毕业设计\智能机器人动态人脸识别系统\陈建州程序.xml";//分类器路径 input_name = argc > 1 ? argv[1] : 0; } cascade = (CvHaarClassifierCascade*)cvLoad( cascade_name, 0, 0, 0 ); if( !cascade )//如果没有找到分类器,输出以下 { fprintf( stderr, "ERROR: Could not load classifier cascade\n" ); fprintf( stderr, "Usage: facedetect --cascade=\"\" [filename|camera_index]\n" ); return -1;

[作业]OPENCV人脸识别

摘要 人脸检测主要是基于计算机识别的一项数字化技术,用以准确获取人的脸部大小和位置信息,在进行人脸检测时,突出主要的脸部特征,淡化次要的环境、衣着等因素。对于某些情况下,人脸检测也可以计算出人脸,如眼睛,鼻子和嘴等精确的微妙特征。由于在安全检测系统,医学,档案管理,视频会议和人机交互等领域人脸检测系统都有光明的应用前景,因此人脸检测逐渐成为了两个跨学科领域研究的热门话题:人工智能和当前模式识别。本文基于OpenCV视觉库具体的设计并开发了对数字图像中的人脸检测的程序,所采用的人脸检测的原理主要是分类器训练模式(Adaboost算法)提取Haar特征的方法。它在整个软件极其重要的作用,图像中人脸的准确定位和识别都受图像处理好坏的直接影响。本次所设计的软件在图像处理部分所采用的方法是基于Adaboost算法进行Haar特征的提取,在此之上加以通过积分图方法来获取完整的级联分类器结构,进行人脸检测时,OpenCV级联分类器通过Adaboost人脸检测算法进行训练,此后采用不同情况下的实验样本完成精确定位以及检测试验。经过代码的设计和调试,在最后的测试中针对数字图像进行的人脸检测和定位达到了较好的效果,提高了定位和识别的正确率。 关键词:人脸检测,AdaBoost,分类器,OpenCV

Abstract Face detection is mainly based on computer recognition of a digital technology,face size and location information to accurately obtain the person,during face detection, highlight the main facial features,dilute the secondary environment,clothing,and other factors.For some cases,face detection can also calculate a person's face,such as eyes, nose and mouth,and other subtle features accurate.Because in the field of human security detection systems,medical records management,video conferencing,and human-computer interaction face detection system has bright prospects,and therefore face detection is becoming a two interdisciplinary research fields hot topic:artificial intelligence and The current pattern recognition.This article is based.penCV vision library designed and developed specifically for digital image face detection process,the principles used face detection methods are mainly classifier training mode(Adaboost algorithm)to extract Haar features.It is in the vital role of the software,the image of the human face accurately locate and identify all that is good or bad a direct impact on the image processing.This software is designed image processing method used in part based Haar Adaboost algorithm to extract features,on top of this to be to get the full cascade classifier structure by integrating the diagram method for face detection,OpenCV cascade classifier is trained by Adaboost face detection algorithm,then the use of the experimental sample under different circumstances for accurate positioning and testing.Through design and debugging code,face detection and location in the final test for digital images to achieve better results and improve the accuracy of positioning and recognition. Keywords:face detection;AdaBoost;classifier;openCV

基于Opencv的人脸检测源程序(附详细使用说明)

基于Opencv的人脸检测程序 我的电脑上是用visual studio 2015,配置opencv2.4.9,visuanl studio加载opencv的方法百度上可以找到很多,按照要求配置好后以后进行一下操作: 第一步:新建win32应用程序的工程,在该工程以下程序复杂被覆盖win32的几行程序, #include"stdafx.h" #include"opencv2/objdetect.hpp" #include"opencv2/videoio.hpp" #include"opencv2/highgui.hpp" #include"opencv2/imgproc.hpp" #include #include using namespace std; using namespace cv; /** Function Headers */ void detectAndDisplay(Mat frame); /** Global variables */ String face_cascade_name = "haarcascade_frontalface_alt.xml"; String eyes_cascade_name = "haarcascade_eye_tree_eyeglasses.xml"; CascadeClassifier face_cascade; CascadeClassifier eyes_cascade; String window_name = "Capture - Face detection"; /** @function main */ int main(void) { VideoCapture capture; Mat frame; //-- 1. Load the cascades if (!face_cascade.load(face_cascade_name)) { printf("--(!)Error loading face cascade\n"); return -1; }; if (!eyes_cascade.load(eyes_cascade_name)) { printf("--(!)Error loading eyes cascade\n"); return -1; }; //-- 2. Read the video stream capture.open(-1); if (!capture.isOpened()) { printf("--(!)Error opening video capture\n"); return -1; }

基于Opencv的视频人脸检测程序源代码(可运行)

1.打开Microsoft Visual Studio 2008,新建一个Win32控制台项目; 2.配置好项目的包含文件和库文件; 3.将……\OpenCV\data\haarcascades中的haarcascade_frontalface_alt.xml拷贝到所建项目的文件夹中; 4.然后添加代码: #include"stdafx.h" #include"cv.h" #include"highgui.h" #include int_tmain(int argc, _TCHAR* argv[]) { CvCapture* capture=0; /*初始化一个视频捕获操作。告诉底层的捕获api我想从Capture1.avi中捕获图片,底层api将检测并选择相应的解码器并做好准备工作*/ capture = cvCaptureFromFile( "F:\\1.avi"); //设置要读的视频(avi格式) static CvMemStorage* storage = 0; static CvHaarClassifierCascade* cascade = 0; cascade = (CvHaarClassifierCascade*)cvLoad("haarcascade_frontalface_alt.xml",0,0,0); if( !cascade || !capture ) return -1; storage = cvCreateMemStorage(0); /*创建一个窗口,用“Video”作为窗口的标识符*/ cvNamedWindow( "Video",1); /*如果初始化失败,那么capture为空指针,程序停止,否则进入捕获循环*/ if( capture ) { for(;;) { IplImage* frame = cvQueryFrame( capture ); IplImage* img = NULL; CvSeq* faces; if( !frame ) break; img = cvCloneImage(frame);

基于OpenCV的视频人脸识别系统的设计与实现

摘要 基于生物特征识别的身份认证方法和系统研究一直以来都是计算机图形学和模式识别领域研究的热点,其中,由于人脸的稳定性和可见性,针对人脸识别的算法研究和系统应用最为广泛,本文针对校园内实验室和宿舍安全管理需求,设计和实现了一套针对监控视频的基于OpenCV的人脸识别原型系统,开发语言选用C++,全文内容包括: (1)构建了基于OpenCV的视频人脸识别的技术框架。针对实验室和宿舍安全管理需要,构建了基于OpenCV的视频人脸识别的技术框架,能够完成基于视频的实时人脸识别和身份认定; (2)设计了基于OpenCV的视频人脸快速检测算法。人脸检测是人脸识别的前提,本文采用基于OpenCV的快速人脸检测算法实现视频图像中人脸的快速定位和提取; (3)设计了基于AdaBoost算法的视频人脸识别方法。应用AdaBoost算法实现了针对视频流的快速人脸定位和身份识别,能够实现实时身份认定。 系统基于.NET平台设计,使用C++语言进行实现,完成了基于视频的实时人脸身份认定。 关键词:人脸检测; OpenCV;人脸识别; C++; 1

Abstract Based on the research of identity authentication method and system of biometric recognition has been a hot research field of computer graphics, pattern recognition and the stability and visibility, the face, the algorithm research and system applications of face recognition is the most widely, according to the laboratory and dormitory safety management needs of the campus, designed and implemented. A face recognition system based on OpenCV in surveillance video, development language is C++, the main content of this thesis includes: (1)Constructed the technical framework for video based face recognition based on OpenCV. According to the laboratory and the dormitory safety management needs, establishes a framework for video based face recognition based on OpenCV, which can complete real-time face recognition and identity based on video identification; (2)Design of a fast face detection algorithm in video based on OpenCV. Face detection is the precondition of face recognition, this paper uses OpenCV fast face detection algorithm to locate face in video image and extraction based on;The design use application of OpenCV to provide strong support, based https://www.sodocs.net/doc/bb13383511.html, platform design. (3)Design of video based face recognition method based on AdaBoost algorithm. Application of AdaBoost algorithm for fast face location and recognition of video stream, which can realize real-time identification. System based https://www.sodocs.net/doc/bb13383511.html, platform design, implementation is carried out using C++ language, completed the real-time face identity recognition based on video Key word:Face detection;OpenCV;Face recognition;C++;

基于opencv的人脸检测界面开发

摘要 人脸检测(Face Detection)是一种在任意数字图像中找到人脸的位置和大小的计算机技术。它可以检测出面部特征,并忽略诸如建筑物、身体和其他任何东西。人脸检测技术不仅仅是人脸跟踪、人脸识别、表情识别等技术的重要条件,同时在人机交互、模式识别、视频检索、智能监控等领域也引起了广泛的重视。 在通过对人脸检测相关知识进行学习的基础上,本文首先对国内外的人脸检测发展进行了相关分析,阐述了本课题的研究背景及意义;第二章介绍基于Opencv实现人脸检测的相关方法和检测原理;第三章指出了基于QT平台,人脸检测界面如何开发,需要用到的相关技术知识和操作流程。第四章设计了基于opencv的人脸检测程序,采用了QT开发工具并结合opencv技术对程序界面进行设计实现。 关键词:人脸检测;QT开发;Opencv;

Abstract Face detection is a computer technology that identifies human faces in digital images. It can detect facial features and ignore something like buildings,bodies and any other things.Face detection technology is not just an important condition for face recognition, also attracting wide attention in the human-computer interaction, pattern recognition, video retrieval, intelligent monitoring and other fields. Firstly in this paper, through the study of relevant technology of face detection recognition, and face detection to identify relevant experience in the domestic and abroad are analyzed,indicating the background and the significance of the topic.Based on opencv,the second chapter introduces how to realize the design.Then the third chapter points out how to develop face detection’s interface based on the QT platform; The fourth chapter based on opencv face detection procedures, using opencv, the QT development tools,achieve the design. Key Words:Face detection; QT development; Opencv;

基于OpenCV的人脸检测算法研究

第8卷第3期 2009年8月  淮阴师范学院学报(自然科学版)JOURNA L OF HUAIYIN TE ACHERS CO LLEGE (NAT URA L SCIE NCE E DITION ) V ol 18N o 13Aug.2009 基于OpenCV 的人脸检测算法研究 齐金山 (淮阴师范学院计算机科学与技术学院,江苏淮安 223300) 摘 要:介绍了一种开放源代码的计算机视觉类库OpenCv ,阐述了该软件的特点及结构,并对 其在Visual C ++2005开发环境下的配置作了详细的说明.然后提出了一个基于OpenCv 的人 脸检测算法.实验结果表明,该算法具有识别效果、实时性好,检测速度快的特点. 关键词:OpenC V ;人脸检测;I pIImage 中图分类号:TP391.41 文献标识码:A 文章编号:167126876(2009)0320216205  收稿日期:2009205222  作者简介:齐金山(19772),男,湖南株洲人,讲师,硕士,研究方向为数字图像处理. 0 引言 人脸的检测是一类具有很大挑战性的问题[1] ,其主要难点在于:人脸是一类高度非刚性的目标,存在相貌、表情、肤色等差异;人脸上可能会存在一些附属物如眼镜、胡须等;人脸的姿态变化万化,并且可能存在遮挡物;待检测图像性质的差异,比如:待检图像的分辨率、摄录器材的质量等.针对以上难点,各国的科研人员作了很多的研究,每年在国际国内的相关期刊和会议上都有大量的关于人脸检测的论文, 如Chellappa 、Zhao 等人分别于1995和2003年发表的两篇人脸识别的综述论文[2,3].人脸检测的算法也 很多,Boosting 算法[4]是其中的一种,但Boosting 算法十分复杂.本文提出了基于OpenC V 进行人脸检测 将比较容易实现,实验结果表明该算法具有识别效果好、实时性好、检测速度快的特点.1 OpenCv 简介 OpenC V (Open S ource C om puter Vision Library )是指Intel 计算机视觉库[5].它由一系列C 函数和少量 C ++类构成,实现了图像处理和计算机视觉方面的很多通用算法.OpenC V 主要用于对图像进行一些高级处理,比如说特征检测与跟踪、运动分析、目标分割与识别以及3 D 重建等.由于OpenCv 的源代码是完全开放的,而且源代码的编写简洁而高效,特别是其中大部分的函数都已经通过汇编最优化,以使之能高效而充分地利用英特尔系列处理芯片的设计体系,对于Pentium M MX 、Pentium 、Pentium HI 及Pentium 4这些处理器而言,OpenCv 的代码执行效率是非常高的,所以近年来在国外的图像处理相关领域中被广泛地使用,成为一种流行的图像处理软件. 111 OpenCv 的特点 相对于MAT LAB 等其它常用的图像处理软件来说,OpenCv 有其显著的不可比拟的优点,主要体现在如下几个方面: 1)OpenCv 是一个包含了超过300个C 函数的应用编程接口,它不依赖于外部库,既可以独立运行,也可在运行时使用其它外部库. 2)高性能:OpenCv 中所有的算法都是基于封装于IP L 的具有很高灵活性的动态数据结构,而且其中有一半以上的函数在设计及汇编时被Intel 公司针对其所生产的处理器优化. 3)提供了一些与诸如E iC 、Ch 、MAT LAB 等其它语言或环境的接口,这些接口在其安装完之后位于安装目录opener/interfaces 下. 4)开放性:不管对于商业的还是非商业的用途,OpenCv 都是完全免费的,其源代码完全开放,开发

《基于 OpenCV的人脸识别系统》

西安电子科技大学 人工智能学院暑期夏令营科研实践《基于OpenCV的人脸识别系统》 实践报告 姓名:XXX 学校:XXXX 院系班级:XXXXXXXXX 联系方式:XXXX

目录 1 项目背景 (1) 2 项目目标 (1) 3 项目方案 (2) 3.1 人脸采集 (2) 3.2 人脸训练 (3) 3.3 人脸识别 (4) 4 项目调试 (6) 4.1 采集调试 (6) 4.2 训练调试 (6) 4.3 识别调试 (7) 5实践总结 (8)

如何创造一个安全的、数字现代化的、智能化的宿舍门禁系统有着十分重要的意义。然而,在日常管理中我们经常会碰到这样的问题:外来人员混入宿舍带来的安全隐患、夏天未带校园卡而在公寓楼前苦等、宿舍出入口必须有人盯守、晚归被困公寓楼外等等。 在当今计算机普及与急剧增长的状况下,应该实施一些高效率的系统,不仅省钱,省事,而且便捷,针对以上情况,十分有必要建立一个全面、高效、人性化、智能的高校宿舍出入管理系统。 因此,做一个人脸识别系统就非常地有必要! 2 项目目标 本项目拟完成人脸采集、人脸训练和人脸检测与识别的功能。 人脸采集程序主要完成以下功能: 1. 建立新的文件夹:用户根据提示输入自己姓名的简称,程序会在工程目录下建立该用户的文件夹,用以存放拍摄的照片; 2. 打开摄像头和写入图像:调用笔记本摄像头,当P键按下时,显示当前帧的图像,经处理后,保存图像;当q键按下时,立即退出采集程序 3. 人脸检测与裁剪:在当前帧识别出人脸后将其裁剪至ORL人脸数据 库大小即92x112。 人脸训练程序主要完成以下功能: 1. CSV文件读取:CSV文件对应的图像数据和对应的标签; 2. 样本训练:包括ORL人脸数据库的样本和自己的样本。 人脸训练样本取自ORL人脸数据库,共40个人,每人10张照片。照片在不同时间、不同表情(睁眼闭眼、笑或者不笑)、不同人脸细节(戴眼镜或者不戴眼镜)下采集,所有的图像都在一个黑暗均匀的背景下采集的,正面竖直人脸(有些有轻微旋转)。此外,增加自己的样本,并以相同尺寸拍摄20张左右图像。 人脸识别与检测程序主要完成以下功能: 1. 人脸检测:识别出当前帧是否有人脸; 2. 人脸预测:根据训练结果判断当前帧中人脸是否属于样本集; 3. 姓名显示:若属于样本集则显示姓名缩写,否则,显示“0”。

基于OpenCV的人脸识别设计方案

基于OpenCV的人脸识别设计方案 导读: 本文提出了一种在Linux 平台下开发脸识别系统的方案,通过QT 来开发用户界面,调用OpenCV 图像处理库对相机进行采集和处理采集图像, 从而实现了人脸检测、身份识别、简单表情识别的功能。 人脸识别的研究可以追溯到上个世纪六、七十年代,经过几十年的曲折发展 已日趋成熟,构建人脸识别系统需要用到一系列相关技术,包括人脸图像采集、人脸定位、人脸识别预处理、身份确认以及身份查找等。而人脸识别在基于 内容的检索、数字视频处理、视频检测等方面有着重要的应用价值,可广泛应 用于各类监控场合,因此具有广泛的应用前景。OpenCV 是Intel 公司支持的开 源计算机视觉库。它轻量级而且高效--由一系列 C 函数和少量C++ 类构成, 实现了图像处理和计算机视觉方面的很多通用算法,作为一个基本的计算机视觉、图像处理和模式识别的开源项目,OpenCV 可以直接应用于很多领域,其 中就包括很多可以应用于人脸识别的算法实现,是作为第二次开发的理想工具。 1 系统组成 本文的人脸识别系统在Linux 操作系统下利用QT 库来开发图形界面,以OpenCV 图像处理库为基础,利用库中提供的相关功能函数进行各种处理:通 过相机对图像数据进行采集,人脸检测主要是调用已训练好的Haar 分类器来 对采集的图像进行模式匹配,检测结果利用PCA 算法可进行人脸图像训练与 身份识别,而人脸表情识别则利用了Camshift 跟踪算法和Lucas–Kanade 光流算法。 2 搭建开发环境 采用德国Basler acA640-100gc 相机,PC 机上的操作系统是Fedora 10,并

基于OpenCV的人脸识别算法研究

基于OpenCV的人脸识别算法研究 摘要:通过对基于Adaboost人脸检测算法的研究,利用该算法与计算机视觉类库openCV进行人脸检测系统的设计,实现了对出现在视频或图像中的人脸检测。此外,在VC++6.0环境下实现了对一个简单的人脸检测系统软件的界面开发,该系统对人脸检测的速度较快,检测结果较为准确,可以作为其他人脸检测或人脸模式识别的系统的开发基础。 关键词:人脸检测;openCV;Adaboost;系统 Face detection system design based on openCV Abstract: According to the research of Adaboost algorithm of Face Detection,people made use of the algorithms and computer vision class library openCV for the design of face detection system and achieved the target of detecting faces showing up in videos and pictures. What’s more,in the environment of VC++6.0,it achieved the development of simple Face Detection. The speed of Face Detection is very fast and the test results are accurate. It can be used as the development foundation of other face detection or face pattern recognition system. Key words: face detection;openCV;Adaboost;system 1.引言 随着计算机与数字信号处理技术的高速发展,人脸检测技术在众多领域得到广泛应用。人脸检测技术是指在视频或图像中检测出现人脸位置、大小的过程。作为人脸信息处理中的一项关键技术,人脸检测技术已经超出了其它人脸识别模式的应用范畴,在视频处理、图像处理、身份验证、安全监测等方面有着重要的应用价值。随着计算机语言算法的发展,近年来出现了大量的人脸检测的算法,其中能够较好的解决人脸的检测速度与检测效果的算法,是在2001年由Paul Viola和Michael Jones首先提出的Adaboost算法。openCV是由Intel 提供的一系列包括C与C++的提供计算机视觉和图像处理的开源软件包,它为视频或图像处理搭建了很好的软件平台。本系统就是基于openCV利用Adaboost算法设计的一个简单的人脸检测系统#该系统能够快速&准确的检测到图像或视频中的人脸。 2.AdaBoost人脸检测算法 对人脸检测的研究最初可以追溯到20世纪70年代,早期的研究方向与现在的研究方向与方法不同。目前在实际中应用的人脸检测方法较为普遍的是基于Adaboost算法的方法。 Viola的人脸检测方法是一种基于积分图、级联分类检测器和Adaboost算法的方法,方法框架可以分为以下3大步骤: 1)使用Haar-like特征表示人脸,使用“积分图”实现特征数值的快速计算; 2)使用Adaboost算法挑选出一些最能代表人脸的矩形特征(弱分类器),按照加权投票的方式将弱分类器构造为一个强分类器; 3)将得到的若干强分类器串联组成一个级联结构的层叠分类器,训练得到的强级联结构能有效地提高分类器的检测速度。

怎样使用OpenCV进行人脸识别

怎样使用OpenCV进行人脸识别 本文大部分来自OpenCV官网上的Face Reconition with OpenCV这节内容 (https://www.sodocs.net/doc/bb13383511.html,/modules/contrib/doc/facerec/facerec_tutorial.html),小弟我尝试翻译一些重要内容。这部分内容是Philipp Wagner写的,他的github:https://https://www.sodocs.net/doc/bb13383511.html,/bytefish,他的网站http://www.bytefish.de/,应该是个德国人。下面应该是他的照片。 友情提示,要看懂代码前,你得先知道OpenCV的安装和配置,会用C++,用过一些OpenCV函数。基本的图像处理和矩阵知识也是需要的。[gm:我是箫鸣的注释]由于我仅仅是翻译,对于六级才过的我,肯定有一些翻译错的或者不当的地方,所以请大家纠错。 1.1.介绍Introduction 从OpenCV2.4开始,加入了新的类FaceRecognizer,我们可以使用它便捷地进行人脸识别实验。本文既介绍代码使用,又介绍算法原理。(他写的源代码,我们可以在OpenCV的 opencv\modules\contrib\doc\facerec\src下找到,当然也可以在他的github中找到,如果你想研究源码,自然可以去看看,不复杂) 目前支持的算法有 Eigenfaces特征脸createEigenFaceRecognizer() Fisherfaces createFisherFaceRecognizer() Local Binary Patterns Histograms局部二值直方图createLBPHFaceRecognizer() 下面所有的例子中的代码在OpenCV安装目录下的samples/cpp下面都能找到,所有的代码商用或者学习都是免费的。

毕业设计:基于OpenCV的人脸识别算法(终稿)-精品

安徽工业大工商学院 毕业学士论文 基于OpenCV的人脸识别算法 姓名:陈滔 申请学位级别:学士专业:测控技术与仪器 指导教师:方挺

摘要 人脸在社会交往中扮演着十分重要的角色,是人类在确定一个人身份时所采用的最普通的生物特征,研究人脸跟踪识别及其相关技术具有十分重要的理论价值和应用价值。彩色图像序列的人脸检测、跟踪与识别技术是随着计算机技术的高速发展和视频监控等应用的需要在近几年才逐渐成为一个研究热点。本文着重构建一套人脸跟踪识别系统,致力于精确实时地对彩色视频中的人脸图像检测跟踪,并可以将跟踪到的人脸图片传输到识别端进行身份识别。系统分为客户端和服务器两部分。针对传统Camshifl跟踪算法进行形态学处理、分配多个跟踪器等改进后的算法应用于客户端进行多人脸的跟踪。服务器端首先将人脸图像按其主要特征进行分块,再对分块图执行Eigenface算法实现人脸身份的识别。这套系统完成了对多人脸的跟踪效果,可广泛的应用于各种安防系统之中如:ATM机监控系统,门禁系统等。

Abstract Human face is 0111"primary focus of attention in social intercourse playingamajor rolei conveying dentity and emotion.Researchonthe face tracking,recognition technology has great theoreticaland practical value.This paper focusesOilbuildingasetofhumanface recognition and trackingsystem tocommitted toaccurate and real-timecolorvideoimages,andcalltransmit the tracked human face image to the recognition part to identify the person’S status.Thesystem is divided into client and server parts.Thetracking algorithm whichcarrieson morphology processing after traditional track algorithm Camshifl and assignments severaltrackingdevices is applied to the client for duplex facetracking.Theserver—side first divides the person face image into blocksaccording to its chief feature,then the blocksuses the Eigenfacealgorithm separately to realize the person’S status recognition.The system implementation for multiple face trackingcallbe widelyused among the various security systems,suchas:ATM machine monitoring system,accesscontrol system.Keywords:Face DetectionFace TrackingFace Recognition Eigenface Camshift

基于OPENCV的人脸识别程序 代码详解

#include"cv.h" #include"highgui.h" #include #ifdef_EiC #define WIN32 #endif static CvMemStorage*storage=0; static CvHaarClassifierCascade*cascade=0; void detect_and_draw(IplImage*image); const char*cascade_name= "haarcascade_frontalface_alt.xml";//人脸检测分类器 int main(int argc,char**argv) { CvCapture*capture=0; IplImage*frame,*frame_copy=0; int optlen=strlen("--cascade="); const char*input_name; if(argc>1&&strncmp(argv[1],"--cascade=",optlen)==0) { cascade_name=argv[1]+optlen; input_name=argc>2?argv[2]:0; } else { cascade_name="E:\毕业设计\智能机器人动态人脸识别系统\陈建州程序.xml";//分类器路径 input_name=argc>1?argv[1]:0; } cascade=(CvHaarClassifierCascade*)cvLoad(cascade_name,0,0,0); if(!cascade)//如果没有找到分类器,输出以下 { fprintf(stderr,"ERROR:Could not load classifier cascade\n"); fprintf(stderr, "Usage:facedetect--cascade=\"\"[filename|camera_index]\n"); return-1;

OpenCV利用摄像头人脸识别

?Introduction 网上存在很多人脸识别的文章,这篇文章是我的一个作业,重在通过摄像头实时采集人脸信息,进行人脸检测和人脸识别,并将识别结果显示在左上角。 利用OpenCV 实现一个实时的人脸识别系统,人脸库采用ORL FaceDatabase (网上下载) ,另外在数据库中增加了作业中自带的20张照片和自己利用摄像头采集到的10张照片,系统利用摄像头实时的采集到场景图像,从中检测出人脸用方框标出,并利用提供的数据库进行人脸识别,并在图像左上角显示相匹配的数据库图片。 ?Method 算法流程分两步,分别是人脸检测和人脸识别。人脸检测使用的是ViolaJones 人脸检测方法,利用样本的Haar-like 特征进行分类器训练,得到级联boosted 分类器,加载训练好的人脸分类器,利用分类器在视频帧中查找人脸区域;人脸识别利用了局部二进制模式直方图。 ?Haar-like 特征 Haar-like 特征如下图所示 图1 Haar-like 特征 ?LBPH 人脸识别常用的方法有三种,Eigenfaces、Fisherfaces 和LBPH;对于高维的图像空间,我们首先应该进行降维操作。LBP 不把图像看做高维的矢量,而是通过物体的局部特征来描述。 将每个像素和其相邻像素对比形成局部的结构,把该像素看做中心,并以该值对邻接像素做阈值处理,如果临界像素的亮度大于该像素则为 1 否则为0,这样每个像素点都可以用一个二进制数来表示,比如一个使用3*3 临界点的LBP 操作如下图所示: 图2 LBP

?Implementation ?识别训练 利用准备好的数据库进行识别训练:首先我们利用Opencv安装文件中的python脚本 create_csv.py建立CSV文件,文件中每条记录如:orl/s13/2.pgm;12,分号之前是图片所存路径,而分号之后是图片的标签号,每一组图片对应着唯一的标签号;之后利用代码中的train_data和read_csv函数对数据集进行训练。使用到的OpenCV 类和函数有: FaceRecognizer,createLBPHFaceRecognizer ?人脸检测 运用Opencv安装文件中的haarcascade_frontalface_alt.xml文件,使用分类器在视频帧中查找人脸区域,并用绿色方框标出。用到的OpenCV 类和函数有: CascadeClassifier,detectMultiScale。 ?人脸识别 读取训练好的yaml文件,对每个监测到的区域的图像分类,并在视频帧人脸区域上方显示分类结果(分类结果显示为标签和可信度),在左上角显示缩略图。用到的OpenCV 函数主要有:predict. ?Code 1/*头文件:*/ 2 #include "opencv2/core/core.hpp" 3 #include "opencv2/contrib/contrib.hpp" 4 #include "opencv2/highgui/highgui.hpp" 5 #include "opencv2/imgproc/imgproc.hpp" 6 #include "opencv2/objdetect/objdetect.hpp" 7 8 #include 9 #include 10 #include 11 #include 12 13char *FACES_TXT_PATH = "face.txt"; 14char *HARR_XML_PATH = "haarcascade_frontalface_alt.xml"; 15char *FACES_MODEL = "face.yaml"; 16char *POTRAITS ="potraits.jpg"; 17int DEVICE_ID = 0; 18 19/*主文件*/ 20 #include "config.h" 21

相关主题