基于opencv的检测到人脸,便将人脸用骷髅头代替。

工具:


/*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);就会报异常错误;

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值