opencv学习 级联分类器检测运动车辆 demo

使用haar+adaboost训练出分类器文件xml,简单写了个检测demo,具体的检测判定还要修改,已经较好的识别出车辆框,后面的博客再贴训练过程、样本及训练好的文件吧(其实还是懒233

//car detection by using haar-featrue and adaboost classifier 
//Author: Ruby
#include 
#include 
#include 
#include 
#include 
#include 
#include 

using namespace std;
using namespace cv;

static CvMemStorage* storage = 0;
String car_detection = "C:\\Users\\Ruby\\Documents\\Visual Studio 2013\\Projects\\test1\\test1\\output.xml";

void detection(IplImage* img, CascadeClassifier& cascade, double scale);

int main(int argc, const char** argv)
{
    CvCapture *capture = 0;
    IplImage *frame, *frame_copy = 0;
    Mat image;
    CascadeClassifier cascade;
    double scale = 4;
    if (!cascade.load(car_detection)){
        cerr << "ERROR: Could not load classifier cascade" << endl;
        return 0;
    }

    storage = cvCreateMemStorage(0);
    cvNamedWindow("result", 1);

    //检测视频
    capture = cvCaptureFromFile("C:\\Users\\Ruby\\Desktop\\A2.avi");
    if (capture){
        for (;;){
            if (!cvGrabFrame(capture))
                break;
            frame = cvRetrieveFrame(capture);
            if (!frame)
                break;
            if (!frame_copy)
                frame_copy = cvCreateImage(cvSize(frame->width, frame->height), IPL_DEPTH_8U, frame->nChannels);
            if (frame->origin == IPL_ORIGIN_TL)
                cvCopy(frame, frame_copy, 0);
            else
                cvFlip(frame, frame_copy, 0);
            IplImage *equ = cvCreateImage(cvGetSize(frame_copy), 8, 1);
            IplImage *gray = cvCreateImage(cvGetSize(frame_copy), 8, 1);
            cvCvtColor(frame_copy, gray, CV_BGR2GRAY);
            cvEqualizeHist(gray, equ);
            detection(frame_copy, cascade, scale);
            if (cvWaitKey(10) >= 0)
                break;

        }
        cvReleaseImage(&frame_copy);
        cvReleaseCapture(&capture);

    }

    cvWaitKey(-1);
    return 0;
}

void detection(IplImage *img1, CascadeClassifier& cascade, double scale){
    Mat img = cvarrToMat(img1);
    int i = 0;
    double t = 0;
    vector cars;
    Mat gray, smallImg(cvRound(img.rows / scale), cvRound(img.cols / scale), CV_8UC1);//缩小图片,加快检测速度
    const static Scalar colors[] = { CV_RGB(0, 0, 255),
        CV_RGB(0, 128, 255),
        CV_RGB(0, 255, 255),
        CV_RGB(0, 255, 0),
        CV_RGB(255, 128, 0),
        CV_RGB(255, 255, 0),
        CV_RGB(255, 0, 0),
        CV_RGB(255, 0, 255) };//不同的颜色框表示不同的车辆

    cvtColor(img, gray, CV_BGR2GRAY);//由于使用的是haar特征,所以都是基于灰度图像的,转换成灰度图像
    resize(gray, smallImg, smallImg.size(), 0, 0, INTER_LINEAR);//将尺寸缩小至1/scale,用线性插值
    equalizeHist(smallImg, smallImg);//直方图均衡

    t = (double)cvGetTickCount();//计算算法执行时间
    //检测车辆
    //detectMultiScale函数中samllImg表示的是要检测的输入图像为smallImg,cars表示检测到的车辆目标序列
    //1.1表示每次图像尺寸减少的比例为1.1, 2表示没一个目标至少要被检测到3次才算是真的目标(因为周围的像素和不同的窗口大小都可以检测到人脸)
    //CV_HAAR_SCALE_IMAGE表示不是缩放分类器来检测,而是缩放的图像,Size(20,20)为目标的最小尺寸
    cascade.detectMultiScale(smallImg, cars,
        1.1, 2, 0
        | CV_HAAR_SCALE_IMAGE
        ,
        Size(20, 20));
    t = (double)cvGetTickCount() - t;//相减得算法执行时间
    printf("detection time = %g ms\n", t / ((double)cvGetTickFrequency()*1000.));
    for (vector::const_iterator r = cars.begin(); r != cars.end(); r++, i++){
        Mat smallImgROI;
        Point center;
        Scalar color = colors[i % 8];
        /*int radius;
        center.x = cvRound((r->x + r->width*0.5)*scale);//还原成原来的大小
        center.y = cvRound((r->y + r->height*0.5)*scale);
        radius = cvRound((r->width + r->height)*0.25*scale);
        circle(img, center, radius, color, 3, 8, 0); */

        rectangle(img, cvPoint(cvRound(r->x*scale),
            cvRound(r->y*scale)),
            cvPoint(cvRound((r->x + r->width - 1)*scale),
            cvRound((r->y + r->height - 1)*scale)),
            color, 3, 8, 0);

    }

    cv::imshow("result", img);
}

上面使用的是detectMultiScale()函数,可以对多种特征进行计算处理;

下面再贴一种只针对haar特征的检测吧,使用的是cvHaarDetectObjects()函数,理论上两个函数运算速度差不多,主要在调参。

//car detection by using haar-featrue and adaboost classifier 
//Author: Ruby
#include 
#include 
#include 
#include 
#include 
#include 
#include 

using namespace std;
using namespace cv;

static CvMemStorage* storage = 0;
static CvHaarClassifierCascade* cascade = 0;
const char* cascade_name = "C:\\Users\\Ruby\\Documents\\Visual Studio 2013\\Projects\\test1\\test1\\output.xml";

void detection(IplImage* image);

int main(int argc, const char** argv)
{
    CvCapture *capture = 0;
    IplImage *frame, *frame_copy = 0;
    cascade = (CvHaarClassifierCascade*)cvLoad(cascade_name, 0, 0, 0);
    double scale = 4;
    if (!cascade){
        fprintf(stderr, "ERROR: Could not load classifier cascade\n");
        return -1;
    }
    storage = cvCreateMemStorage(0);
    cvNamedWindow("result", 1);

    //检测视频
    capture = cvCaptureFromFile("C:\\Users\\Ruby\\Desktop\\A2.avi");
    if (capture){
        for (;;){
            if (!cvGrabFrame(capture))
                break;
            frame = cvRetrieveFrame(capture);
            if (!frame)
                break;
            if (!frame_copy)
                frame_copy = cvCreateImage(cvSize(frame->width, frame->height), IPL_DEPTH_8U, frame->nChannels);
            if (frame->origin == IPL_ORIGIN_TL)
                cvCopy(frame, frame_copy, 0);
            else
                cvFlip(frame, frame_copy, 0);
            detection(frame_copy);
            if (cvWaitKey(10) >= 0)
                break;

        }
        cvReleaseImage(&frame_copy);
        cvReleaseCapture(&capture);

    }
    cvWaitKey(-1);
    cvDestroyWindow("result");
    return 0;
}

void detection(IplImage *img){
    int scale=1.3;
    IplImage* temp = cvCreateImage(cvSize(img->width / scale, img->height / scale), 8, 3);
    CvPoint pt1, pt2;
    int i;

    cvClearMemStorage(storage);
    if (cascade){
        //第四个参数scale_factor值不同影响流畅度
        CvSeq* cars = cvHaarDetectObjects(img, cascade, storage,
                                          1.3,3,CV_HAAR_DO_CANNY_PRUNING,
                                          cvSize(20,20));
        for (int i = 0; i < (cars ? cars->total : 0); i++){
            CvRect* r = (CvRect*)cvGetSeqElem(cars, i);
            pt1.x = r->x*scale;
            pt2.x = (r->x + r->width)*scale;
            pt1.y = r->y*scale;
            pt2.y = (r->y + r->height)*scale;
            cvRectangle(img, pt1, pt2, CV_RGB(255, 0, 0), 3, 8, 0);
        }
    }


    cvShowImage("result", img);
    cvReleaseImage(&temp);
}

训练后的xml文件及效果展示视频见链接,不好意思拖了这么久,十分抱歉!

你可能感兴趣的:(opencv,级联分类器,车辆识别)