使用Adaboost训练车牌定位——(3)

简介

1.准备训练样本图片,包括正例及反例样本

2.生成样本描述文件

3.训练样本

4.目标识别

生成了xml接下来,开始识别了!!!
目标识别,也即利用前面训练出来的分类器文件(.xml文件)对图片中的物体进行识别,并在图中框出在该物体。由于逻辑比较简单,这里直接上代码:

// ConsoleApplication2.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <opencv2\opencv.hpp>

using namespace std;
using namespace cv;

void detect_and_draw(IplImage* img);
CvHaarClassifierCascade* cascade;
CvMemStorage* storage;
//CascadeClassifier cascade;与CvHaarClassifierCascade* 区别?

int _tmain(int argc, _TCHAR* argv[])
{

    char* cascade_name = "F:\\objectmarker\\haarcascade_plate.xml"; //上文最终生成的xml文件命名为"haarcascade_plate.xml"
    cascade = (CvHaarClassifierCascade*)cvLoad(cascade_name, 0, 0, 0); //加载xml文件

    if (!cascade)
    {
        fprintf(stderr, "ERROR: Could not load classifier cascade\n");
        system("pause");
        return -1;
    }
    storage = cvCreateMemStorage(0);
    cvNamedWindow("result", 1);

    const char* filename = "test04.jpg";
    IplImage* image = cvLoadImage(filename, 1);

    if (image)
    {
        detect_and_draw(image); //函数见下方
        cvWaitKey(0);
        cvReleaseImage(&image);//因为使用了IplImage,所以要释放资源
    }
    cvDestroyWindow("result");
    return 0;


}

void detect_and_draw(IplImage* img)
{
    double scale = 1.2;
    static CvScalar colors[] = {
        { { 0, 0, 255 } }, { { 0, 128, 255 } }, { { 0, 255, 255 } }, { { 0, 255, 0 } },
        { { 255, 128, 0 } }, { { 255, 255, 0 } }, { { 255, 0, 0 } }, { { 255, 0, 255 } }
    };//Just some pretty colors to draw with

    //Image Preparation 
    // 
    IplImage* gray = cvCreateImage(cvSize(img->width, img->height), 8, 1);
    IplImage* small_img = cvCreateImage(cvSize(cvRound(img->width / scale), cvRound(img->height / scale)), 8, 1);
    cvCvtColor(img, gray, CV_BGR2GRAY);
    cvResize(gray, small_img, CV_INTER_LINEAR);

    cvEqualizeHist(small_img, small_img); //直方图均衡

    //Detect objects if any 
    // 
    cvClearMemStorage(storage);
    double t = (double)cvGetTickCount();//计时开始
    CvSeq* objects = cvHaarDetectObjects(small_img,
        cascade,
        storage,
        1.1,
        2,
        0/*CV_HAAR_DO_CANNY_PRUNING*/,
        cvSize(40, 20));

    t = (double)cvGetTickCount() - t;//计时结束
    printf("detection time = %gms\n", t / ((double)cvGetTickFrequency()*1000.));

    //Loop through found objects and draw boxes around them 
    for (int i = 0; i<(objects ? objects->total : 0); ++i)
    {
        CvRect* r = (CvRect*)cvGetSeqElem(objects, i);//draw Rectangle
        cvRectangle(img, cvPoint(r->x*scale, r->y*scale), cvPoint((r->x + r->width)*scale, (r->y + r->height)*scale), colors[i % 8]);//choose color
    }
    for (int i = 0; i < (objects ? objects->total : 0); i++)
    {
        CvRect* r = (CvRect*)cvGetSeqElem(objects, i);//draw radius
        CvPoint center;
        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);
        cvCircle(img, center, radius, colors[i % 8], 3, 8, 0);
    }

    cvShowImage("result", img);
    cvReleaseImage(&gray);
    cvReleaseImage(&small_img);
}

这里写图片描述

OpenCV2圆形detection:

#include "stdafx.h"
#include <opencv2\highgui\highgui.hpp>
#include <opencv2\imgproc\imgproc.hpp>
#include <opencv2\objdetect\objdetect.hpp>
#include <iostream>
#include <stdio.h>

using namespace std;
using namespace cv;




void detectAndDisplay(Mat frame);

//--------------------------------【全局变量声明】----------------------------------------------
//      描述:声明全局变量
//-------------------------------------------------------------------------------------------------
//注意,需要把"F:\\objectmarker\\haarcascade_plate.xml"这个文件复制到工程路径下
String face_cascade_name = "F:\\objectmarker\\haarcascade_plate.xml";
CascadeClassifier face_cascade;
string window_name = "Capture - Plate detection";
RNG rng(12345);


//--------------------------------【help( )函数】----------------------------------------------
//      描述:输出帮助信息
//-------------------------------------------------------------------------------------------------
static void ShowHelpText()
{
    //输出欢迎信息和OpenCV版本
    cout << "\n\n\t\t\t非常感谢购买《OpenCV3编程入门》一书!\n"
        << "\n\n\t\t\t此为本书OpenCV2版的第11个配套示例程序\n"
        << "\n\n\t\t\t   当前使用的OpenCV版本为:" << CV_VERSION
        << "\n\n  ----------------------------------------------------------------------------";
}


//-----------------------------------【main( )函数】--------------------------------------------
//      描述:控制台应用程序的入口函数,我们的程序从这里开始
//-------------------------------------------------------------------------------------------------
int main(void)
{
    VideoCapture capture;
    Mat frame;


    //-- 1. 加载级联(cascades)
    if (!face_cascade.load(face_cascade_name)){ printf("--(!)Error loading\n"); return -1; };

    //-- 2. 读取视频
    capture.open(0);
    ShowHelpText();
    if (capture.isOpened())
    {
        for (;;)
        {
            capture >> frame;

            //-- 3. 对当前帧使用分类器(Apply the classifier to the frame)
            if (!frame.empty())
            {
                detectAndDisplay(frame);
            }
            else
            {
                printf(" --(!) No captured frame -- Break!"); break;
            }

            int c = waitKey(1);
            if ((char)c == 'c') { break; }

        }
    }
    return 0;
}


void detectAndDisplay(Mat frame)
{
    std::vector<Rect> faces;
    Mat frame_gray;

    cvtColor(frame, frame_gray, COLOR_BGR2GRAY);
    equalizeHist(frame_gray, frame_gray);
    //-- 车牌检测
    face_cascade.detectMultiScale(frame_gray, faces, 1.1, 2, 0 | CV_HAAR_SCALE_IMAGE, Size(40, 20));

    for (size_t i = 0; i < faces.size(); i++)
    {
        Point center(faces[i].x + faces[i].width / 2, faces[i].y + faces[i].height / 2);
        ellipse(frame, center, Size(faces[i].width / 2, faces[i].height / 2), 0, 0, 360, Scalar(255, 0, 255), 2, 8, 0);

        Mat faceROI = frame_gray(faces[i]);

    }
    //-- 显示最终效果图
    imshow(window_name, frame);
}

OpenCV2方形detection:

#include "stdafx.h"
#include <opencv2\highgui\highgui.hpp>
#include <opencv2\imgproc\imgproc.hpp>
#include <opencv2\objdetect\objdetect.hpp>
#include <iostream>
#include <stdio.h>

using namespace std;
using namespace cv;




void detectAndDisplay(Mat frame);

//--------------------------------【全局变量声明】----------------------------------------------
//      描述:声明全局变量
//-------------------------------------------------------------------------------------------------
//注意,需要把"F:\\objectmarker\\haarcascade_plate.xml"这个文件复制到工程路径下
String face_cascade_name = "F:\\objectmarker\\haarcascade_plate.xml";
CascadeClassifier face_cascade;
string window_name = "Capture - Plate detection";
RNG rng(12345);


//--------------------------------【help( )函数】----------------------------------------------
//      描述:输出帮助信息
//-------------------------------------------------------------------------------------------------
static void ShowHelpText()
{
    //输出欢迎信息和OpenCV版本
    cout << "\n\n\t\t\t非常感谢购买《OpenCV3编程入门》一书!\n"
        << "\n\n\t\t\t此为本书OpenCV2版的第11个配套示例程序\n"
        << "\n\n\t\t\t   当前使用的OpenCV版本为:" << CV_VERSION
        << "\n\n  ----------------------------------------------------------------------------";
}


//-----------------------------------【main( )函数】--------------------------------------------
//      描述:控制台应用程序的入口函数,我们的程序从这里开始
//-------------------------------------------------------------------------------------------------
int main(void)
{
    VideoCapture capture;
    Mat frame;


    //-- 1. 加载级联(cascades)
    if (!face_cascade.load(face_cascade_name)){ printf("--(!)Error loading\n"); return -1; };

    //-- 2. 读取视频
    capture.open(0);
    ShowHelpText();
    if (capture.isOpened())
    {
        for (;;)
        {
            capture >> frame;

            //-- 3. 对当前帧使用分类器(Apply the classifier to the frame)
            if (!frame.empty())
            {
                detectAndDisplay(frame);
            }
            else
            {
                printf(" --(!) No captured frame -- Break!"); break;
            }

            int c = waitKey(1);
            if ((char)c == 'c') { break; }

        }
    }
    return 0;
}


void detectAndDisplay(Mat frame)
{
    std::vector<Rect> faces;
    Mat frame_gray;
    Rect select;//声明矩形 

    cvtColor(frame, frame_gray, COLOR_BGR2GRAY);
    equalizeHist(frame_gray, frame_gray);
    //-- 车牌检测
    face_cascade.detectMultiScale(frame_gray, faces, 2.1, 2, 0 | CV_HAAR_SCALE_IMAGE, Size(40, 20));

    for (size_t i = 0; i < faces.size(); i++)
    {
        select.x = faces[i].x;
        select.y = faces[i].y;
        select.width = faces[i].width;
        select.height = faces[i].height;
        rectangle(frame, select, Scalar(255, 0, 255), 2, 8, 0);//用矩形画矩形窗

        Mat faceROI = frame_gray(faces[i]);

    }
    //-- 显示最终效果图
    imshow(window_name, frame);
}

这里写图片描述

参考

【1】对OpenCV中Haar特征CvHaarClassifierCascade等结构理解 - PAK FA T-50 - 博客园
http://www.cnblogs.com/pakfahome/p/3611303.html
【2】训练自己haar-like特征分类器并识别物体(2) - 罗索实验室
http://www.rosoo.net/a/201504/17273.html
【3】如何利用OpenCV自带的haar training程序训练分类器 - 计算机视觉小菜鸟的专栏 - CSDN博客
http://blog.csdn.net/carson2005/article/details/8171571
【4】使用Adaboost训练手掌检测器 - xbcReal的博客 - CSDN博客
http://blog.csdn.net/xbcreal/article/details/77994719

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

何以问天涯

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值