使用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文件及效果展示视频见链接,不好意思拖了这么久,十分抱歉!