Cascade Classification

本文介绍基于Haar特征的级联分类器用于目标检测的技术原理。该分类器由Viola等人提出并由Lienhart改进,通过训练得到的级联分类器能够有效地识别特定目标(如人脸)。文中详细解释了级联分类器的工作流程、参数设置以及如何使用OpenCV进行目标检测。

转自:http://opencv.willowgarage.com/documentation/c/objdetect_cascade_classification.html

Haar Feature-based Cascade Classifier for Object Detection

The object detector described below has been initially proposed by Paul Viola Viola01 and improved by Rainer Lienhart Lienhart02 . First, a classifier (namely a cascade of boosted classifiers working with haar-like features ) is trained with a few hundred sample views of a particular object (i.e., a face or a car), called positive examples, that are scaled to the same size (say, 20x20), and negative examples - arbitrary images of the same size.

After a classifier is trained, it can be applied to a region of interest (of the same size as used during the training) in an input image. The classifier outputs a “1” if the region is likely to show the object (i.e., face/car), and “0” otherwise. To search for the object in the whole image one can move the search window across the image and check every location using the classifier. The classifier is designed so that it can be easily “resized” in order to be able to find the objects of interest at different sizes, which is more efficient than resizing the image itself. So, to find an object of an unknown size in the image the scan procedure should be done several times at different scales.

The word “cascade” in the classifier name means that the resultant classifier consists of several simpler classifiers ( stages ) that are applied subsequently to a region of interest until at some stage the candidate is rejected or all the stages are passed. The word “boosted” means that the classifiers at every stage of the cascade are complex themselves and they are built out of basic classifiers using one of four different boosting techniques (weighted voting). Currently Discrete Adaboost, Real Adaboost, Gentle Adaboost and Logitboost are supported. The basic classifiers are decision-tree classifiers with at least 2 leaves. Haar-like features are the input to the basic classifers, and are calculated as described below. The current algorithm uses the following Haar-like features:

_images/haarfeatures.png

The feature used in a particular classifier is specified by its shape (1a, 2b etc.), position within the region of interest and the scale (this scale is not the same as the scale used at the detection stage, though these two scales are multiplied). For example, in the case of the third line feature (2c) the response is calculated as the difference between the sum of image pixels under the rectangle covering the whole feature (including the two white stripes and the black stripe in the middle) and the sum of the image pixels under the black stripe multiplied by 3 in order to compensate for the differences in the size of areas. The sums of pixel values over a rectangular regions are calculated rapidly using integral images (see below and the Integral description).

To see the object detector at work, have a look at the HaarFaceDetect demo.

The following reference is for the detection part only. There is a separate application called haartraining that can train a cascade of boosted classifiers from a set of samples. Seeopencv/apps/haartraining for details.

CvHaarFeature, CvHaarClassifier, CvHaarStageClassifier, CvHaarClassifierCascade

Comments from the Wiki

CvHaarFeature, CvHaarClassifier, CvHaarStageClassifier,  CvHaarClassifierCascade

Boosted Haar classifier structures.

#define CV_HAAR_FEATURE_MAX  3

/* a haar feature consists of 2-3 rectangles with appropriate weights */
typedef struct CvHaarFeature
{
    int  tilted;  /* 0 means up-right feature, 1 means 45--rotated feature */

    /* 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 */
    struct
    {
        CvRect r;
        float weight;
    } rect[CV_HAAR_FEATURE_MAX];
}
CvHaarFeature;

/* 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 response */
typedef struct CvHaarClassifier
{
    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 chosen.
       alpha[i] - output value correponding to the leaf. */
    CvHaarFeature* haar_feature;
    float* threshold;
    int* left;
    int* right;
    float* alpha;
}
CvHaarClassifier;

/* a boosted battery of classifiers(=stage classifier):
   the stage classifier returns 1
   if the sum of the classifiers responses
   is greater than ``threshold`` and 0 otherwise */
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;

typedef struct CvHidHaarClassifierCascade CvHidHaarClassifierCascade;

/* cascade or tree of stage classifiers */
typedef struct CvHaarClassifierCascade
{
    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 */
}
CvHaarClassifierCascade;

All the structures are used for representing a cascaded of boosted Haar classifiers. The cascade has the following hierarchical structure:

begin{verbatim} Cascade:

Stage,,1,,:
Classifier,,11,,:
Feature,,11,,
Classifier,,12,,:
Feature,,12,,

...

Stage,,2,,:
Classifier,,21,,:
Feature,,21,,

...

...

end{verbatim} The whole hierarchy can be constructed manually or loaded from a file or an embedded base using the function LoadHaarClassifierCascade .

LoadHaarClassifierCascade

Comments from the Wiki

CvHaarClassifierCascadecvLoadHaarClassifierCascade (const char*  directoryCvSize  orig_window_size )

Loads a trained cascade classifier from a file or the classifier database embedded in OpenCV.

Parameters:
  • directory – Name of the directory containing the description of a trained cascade classifier
  • orig_window_size – Original size of the objects the cascade has been trained on. Note that it is not stored in the cascade and therefore must be specified separately

The function loads a trained cascade of haar classifiers from a file or the classifier database embedded in OpenCV. The base can be trained using the haartraining application (see opencv/apps/haartraining for details).

The function is obsolete . Nowadays object detection classifiers are stored in XML or YAML files, rather than in directories. To load a cascade from a file, use the Load function.

HaarDetectObjects

Comments from the Wiki

..
CvSeqcvHaarDetectObjects (const  CvArr*  imageCvHaarClassifierCascade*  cascadeCvMemStorage*  storage, double  scaleFactor=1.1, int  minNeighbors=3, int  flags=0CvSize  minSize=cvSize(0, 0), CvSize  maxSize=cvSize(0, 0) )
Detects objects in the image.

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;

param image:Image to detect objects in
param cascade:Haar classifier cascade in internal representation
param storage:Memory storage to store the resultant sequence of the object candidate rectangles
param scaleFactor:
 The factor by which the search window is scaled between the subsequent scans, 1.1 means increasing window by 10 %
param minNeighbors:
 Minimum number (minus 1) of neighbor rectangles that makes up an object. All the groups of a smaller number of rectangles than min_neighbors -1 are rejected. If minNeighbors is 0, the function does not any grouping at all and returns all the detected candidate rectangles, which may be useful if the user wants to apply a customized grouping procedure
param flags:Mode of operation. Currently the only flag that may be specified is CV_HAAR_DO_CANNY_PRUNING . If it is set, the function uses Canny edge detector to reject some image regions that contain too few or too much edges and thus can not contain the searched object. The particular threshold values are tuned for face detection and in this case the pruning speeds up the processing
param minSize:Minimum window size. By default, it is set to the size of samples the classifier has been trained on ( \sim 20\times 20 for face detection)
param maxSize:Maximum window size to use. By default, it is set to the size of the image.

The function finds rectangular regions in the given image that are likely to contain objects the cascade has been trained for and returns those regions as a sequence of rectangles. The function scans the image several times at different scales (see SetImagesForHaarClassifierCascade ). Each time it considers overlapping regions in the image and applies the classifiers to the regions usingRunHaarClassifierCascade . It may also apply some heuristics to reduce number of analyzed regions, such as Canny prunning. After it has proceeded and collected the candidate rectangles (regions that passed the classifier cascade), it groups them and returns a sequence of average rectangles for each large enough group. The default parameters ( scale_factor =1.1, min_neighbors =3, flags =0) are tuned for accurate yet slow object detection. For a faster operation on real video images the settings are: scale_factor =1.2, min_neighbors =2, flags = CV_HAAR_DO_CANNY_PRUNING , min_size = minimum possible face size (for example, \sim 1/4 to 1/16 of the image area in the case of video conferencing).

#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 input image 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 );
        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 );
        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;
}

SetImagesForHaarClassifierCascade

Comments from the Wiki

void  cvSetImagesForHaarClassifierCascade ( CvHaarClassifierCascade*  cascade, const  CvArr*  sum, const  CvArr*  sqsum, const  CvArr*  tilted_sum, double  scale )

Assigns images to the hidden cascade.

Parameters:
  • cascade – Hidden Haar classifier cascade, created by CreateHidHaarClassifierCascade
  • sum – Integral (sum) single-channel image of 32-bit integer format. This image as well as the two subsequent images are used for fast feature evaluation and brightness/contrast normalization. They all can be retrieved from input 8-bit or floating point single-channel image using the function Integral
  • sqsum – Square sum single-channel image of 64-bit floating-point format
  • tilted_sum – Tilted sum single-channel image of 32-bit integer format
  • scale – Window scale for the cascade. If scale =1, the original window size is used (objects of that size are searched) - the same size as specified in LoadHaarClassifierCascade(24x24 in the case of default_face_cascade ), if scale =2, a two times larger window is used (48x48 in the case of default face cascade). While this will speed-up search about four times, faces smaller than 48x48 cannot be detected

The function assigns images and/or window scale to the hidden classifier cascade. If image pointers are NULL, the previously set images are used further (i.e. NULLs mean “do not change images”). Scale parameter has no such a “protection” value, but the previous value can be retrieved by the GetHaarClassifierCascadeScale function and reused again. The function is used to prepare cascade for detecting object of the particular size in the particular image. The function is called internally by HaarDetectObjects , but it can be called by the user if they are using the lower-level functionRunHaarClassifierCascade .

ReleaseHaarClassifierCascade

Comments from the Wiki

void  cvReleaseHaarClassifierCascade ( CvHaarClassifierCascade**  cascade )

Releases the haar classifier cascade.

Parameter:cascade – Double pointer to the released cascade. The pointer is cleared by the function

The function deallocates the cascade that has been created manually or loaded using LoadHaarClassifierCascade or Load .

RunHaarClassifierCascade

Comments from the Wiki

int  cvRunHaarClassifierCascade ( CvHaarClassifierCascade*  cascadeCvPoint  pt, int  start_stage=0 )

Runs a cascade of boosted classifiers at the given image location.

Parameters:
  • cascade – Haar classifier cascade
  • pt – Top-left corner of the analyzed region. Size of the region is a original window size scaled by the currenly set scale. The current window size may be retrieved using theGetHaarClassifierCascadeWindowSize function
  • start_stage – Initial zero-based index of the cascade stage to start from. The function assumes that all the previous stages are passed. This feature is used internally byHaarDetectObjects for better processor cache utilization

The function runs the Haar classifier cascade at a single image location. Before using this function the integral images and the appropriate scale (window size) should be set usingSetImagesForHaarClassifierCascade . The function returns a positive value if the analyzed rectangle passed all the classifier stages (it is a candidate) and a zero or negative value otherwise.

Easy Ensemble和Balance Cascade是两种集成学习算法,用于解决不平衡数据集的问题。在Python中,可以使用imblearn库来实现这两种算法。 1. Easy Ensemble Easy Ensemble是一种基于Bagging的集成学习算法,它通过随机采样生成多个子集,在每个子集上训练一个分类器,最后将多个分类器的预测结果进行投票,得到最终的分类结果。与传统的Bagging不同的是,Easy Ensemble是针对不平衡数据集进行优化的,它通过对少数类样本进行重采样,使得每个子集中的少数类样本占比更高,从而提高分类器对少数类样本的识别能力。 在Python中,可以使用imblearn.ensemble模块中的EasyEnsembleClassifier类来实现Easy Ensemble算法。下面是一个简单的例子: ```python from imblearn.ensemble import EasyEnsembleClassifier from sklearn.datasets import make_classification from sklearn.model_selection import train_test_split from sklearn.metrics import classification_report # 生成不平衡数据集 X, y = make_classification(n_classes=2, class_sep=2, weights=[0.1, 0.9], n_informative=3, n_redundant=1, flip_y=0, n_features=20, n_clusters_per_class=1, n_samples=1000, random_state=10) # 划分训练集和测试集 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=10) # 定义Easy Ensemble分类器 ee = EasyEnsembleClassifier(n_estimators=50) # 训练模型 ee.fit(X_train, y_train) # 预测测试集 y_pred = ee.predict(X_test) # 输出分类报告 print(classification_report(y_test, y_pred)) ``` 2. Balance Cascade Balance Cascade是一种基于Boosting的集成学习算法,它通过迭代地训练多个分类器,每次训练都将前一轮分类器错误分类的少数类样本加入训练集中,从而逐步增加少数类样本的比例,提高分类器的识别能力。 在Python中,可以使用imblearn.ensemble模块中的BalanceCascade类来实现Balance Cascade算法。下面是一个简单的例子: ```python from imblearn.ensemble import BalanceCascade from sklearn.datasets import make_classification from sklearn.model_selection import train_test_split from sklearn.metrics import classification_report # 生成不平衡数据集 X, y = make_classification(n_classes=2, class_sep=2, weights=[0.1, 0.9], n_informative=3, n_redundant=1, flip_y=0, n_features=20, n_clusters_per_class=1, n_samples=1000, random_state=10) # 划分训练集和测试集 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=10) # 定义Balance Cascade分类器 bc = BalanceCascade(n_estimators=50) # 训练模型 bc.fit(X_train, y_train) # 预测测试集 y_pred = bc.predict(X_test) # 输出分类报告 print(classification_report(y_test, y_pred)) ``` 以上是两种不平衡数据集处理方法的Python实现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值