工具:
/*Result window title*/
#define WND_RESULT "result"
static CvMemStorage* storage = 0;
static CvHaarClassifierCascade* cascade ;
const char* cascade_name ;
/*skull image*/
IplImage *g_skullImage;
/*Tarckbar initial value*/
int g_trackbar_value=5;
/*Trackbar total value*/
int g_trackbar_total = 10;
/*Alpha blend' alpha*/
double g_alpha = 0;
/*Trackba callback fuction*/
void switch_callback(int pos) {
cout << "Trackbar event. pos:" << pos << endl;
g_alpha = (double)pos / g_trackbar_total;
}
void detect_and_draw(IplImage* img)
{
double scale = 1.2;
//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(30, 30));
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);
CvRect r_scale = cvRect(r->x * scale, r->y * scale, r->width * scale, r->height * scale);
// 改變骷髏頭圖像大小
IplImage * skullResize = cvCreateImage(
cvSize(r_scale.width, r_scale.height),g_skullImage->depth, g_skullImage->nChannels);
cvResize(g_skullImage, skullResize, CV_INTER_LINEAR);
// 將人臉檢測區域用骷髏頭圖像代替
cvSetImageROI(img, r_scale);
printf("Alpha: %f\t", g_alpha);
cvAddWeighted(img, g_alpha, skullResize, 1.0 - g_alpha, 0.0, img);
cvResetImageROI(img);
cvReleaseImage(&skullResize);
}
cvShowImage(WND_RESULT, img);
cvReleaseImage(&gray);
cvReleaseImage(&small_img);
}
應用層:
void opencv_4_3::ans_8() {
//獲取攝像頭
VideoCapture capture(0);
cascade_name = "E:\\opencv\\sources\\data\\haarcascades_cuda\\haarcascade_frontalface_alt2.xml";
cascade = (CvHaarClassifierCascade*)cvLoad(cascade_name, 0, 0, 0);
if (!cascade) {
cout << "Error:Could not load classifier cascade" << endl;
return;
}
storage = cvCreateMemStorage(0);
cvNamedWindow(WND_RESULT, CV_WINDOW_AUTOSIZE);
Mat frame;
capture >> frame;
IplImage * frame_c;
frame_c = &IplImage(frame);
IplImage *skullImage = cvLoadImage("..//..//skull.jpg");
g_skullImage = cvCreateImage(cvGetSize(skullImage), 8, 3);
skullImage->nChannels != 3 ? cvCvtColor(skullImage, g_skullImage, CV_GRAY2BGR) : cvCopy(skullImage, g_skullImage);
cvCreateTrackbar("Switch", WND_RESULT, &g_trackbar_value,
g_trackbar_total, switch_callback);
g_alpha = (double)g_trackbar_value/ g_trackbar_total;
char c;
while (1) {
capture >> frame;
frame_c = &IplImage(frame);
if (!frame_c) {
return ;
}
detect_and_draw(frame_c);
c = cvWaitKey(50);
if (c == 27)
break;
}
cvDestroyWindow(WND_RESULT);
cvReleaseImage(&frame_c);
//cvReleaseCapture(&capture);
cvReleaseImage(&skullImage);
cvReleaseImage(&g_skullImage);
}
碰到的麻煩:
原來我是用cvCreateCameraCapture獲取的攝像頭視頻,結果總是攝像頭燈亮,但是載入不了視頻。
於是參考了博友的這段:
VideoCapture capture(0);
//0或-1表示筆記本內置攝像頭
Mat frame;
while(1)
{
capture >> frame;
imshow("讀取視頻", frame);
char c=cvWaitKey(33);
if(c==27)break;
//等待按鍵ESC
}
後來就是這段:
cascade_name = "E:\\opencv\\sources\\data\\haarcascades_cuda\\haarcascade_frontalface_alt2.xml";
cascade = (CvHaarClassifierCascade*)cvLoad(cascade_name, 0, 0, 0);
原先的路勁是E:\\opencv\\sources\\data\\haarcascades\\haarcascade_frontalface_alt2.xml;
那麼(CvHaarClassifierCascade*)cvLoad(cascade_name, 0, 0, 0);就會報異常錯誤;