OpenCV之在实时视频中覆盖太阳镜(四)

int main(int argc, char* argv[])
{
	string faceCascadeName = argv[1];
	string eyeCascadeName = argv[2];
	CascadeClassifier faceCascade, eyeCascade;

	if (!faceCascade.load(faceCascadeName)) {
		cerr << "Error loading face cascade file. Exiting!" << endl;
		return -1;
	}
	//Mat eyeMask = imread("../images/glasses.jpg");
	Mat eyeMask = imread(argv[3]);
	if (!eyeMask.data) {
		cerr << "Error loading mask image. Exiting!" << endl;
	}

	//Current frame
	Mat frame, frameGray;
	Mat frameROI, eyeMaskSmall;
	Mat grayMaskSmall, grayMaskSmallThresh, grayMaskSmallThreshInv;
	Mat maskedEye, maskedFrame;

	char ch;
	//Create the capture object
	//0->input arg that specifies it should take the input from the webcam
	VideoCapture cap(0);
	//If you cannot open the webcam, stop the execution!
	if (!cap.isOpened()) {
		return -1;
	}
	namedWindow("Frame");
	//Scaling factor to resize the input frames from the webcam
	float scalingFactor = 0.75;
	vector<Rect> faces;
	//Iterate until the user presses the Esc key
	while (true)
	{
		//Capture the current frame
		cap >> frame;
		//Resize the frame
		resize(frame, frame, Size(), scalingFactor, scalingFactor,INTER_AREA);
		//Convert to grayscale
		cvtColor(frame, frameGray, COLOR_BGR2GRAY);
		//Equalize the histogram
		equalizeHist(frameGray, frameGray);
		//Detect faces
		faceCascade.detectMultiScale(frameGray, faces, 1.1, 2, 0 | 2, Size(30, 30));
		vector<Point> centers;

		//Draw green circles around the eyes
		for (int i = 0; i < faces.size(); i++) {
			Mat faceROI = frameGray(faces[i]);
			vector<Rect> eyes;

			//In each face, detect eyes
			eyeCascade.detectMultiScale(faceROI, eyes, 1.1, 2, 0 | 2, Size(30, 30));
			//For each eye detected, computer the center
			for (int j = 0; j < eyes.size(); j++) {
				Point center(faces[i].x + eyes[j].x + int(eyes[j].width*0.5), faces[i].y + eyes[j].y + int(eyes[j].height*0.5));
				centers.push_back(center);
			}
		}
		//Overlay sunglasses only if both eyes are detected
		if (centers.size() == 2) {
			Point leftPoint, rightPoint;
			//Identify the left and right eyes
			if (centers[0].x < centers[1].x) {
				leftPoint = centers[0];
				rightPoint = centers[1];
			}
			else {
				leftPoint = centers[1];
				rightPoint = centers[0];
			}
			//Custom parameters to make the sungloasses fit your face.You may have to play around with them to make sure it works.
			int w = 2.3*(rightPoint.x - leftPoint.x);
			int h = int(0.4*w);
			int x = leftPoint.x - 0.25*w;
			int y = leftPoint.y - 0.5*h;

			//Extract region of interest(ROI) covering both the eyes
			frameROI = frame(Rect(x, y, w, h));
			//Resize the sunglasses image based on the dimensions of the above ROI
			resize(eyeMask, eyeMaskSmall, Size(w, h));
			//Convert the above image to grayscale
			cvtColor(eyeMaskSmall, grayMaskSmall, COLOR_BGR2GRAY);
			//Threshold the above image to isolate the foreground object
			threshold(grayMaskSmall, grayMaskSmallThresh, 245, 255, THRESH_BINARY_INV);
			//Create mask by inverting the above image(because we don't want the background to affect the overlay)
			bitwise_not(grayMaskSmallThresh, grayMaskSmallThreshInv);
			//Use bitwise "AND" operator to extract precise boundary of sunglasses
			bitwise_and(eyeMaskSmall, eyeMaskSmall, maskedEye, grayMaskSmallThresh);
			//Use bitwise "AND" operator overlay sunglasses
			bitwise_and(frameROI, frameROI, maskedFrame, grayMaskSmallThreshInv);
			//And the above masked images and place it in the original frame ROI to create the final image
			add(maskedEye, maskedFrame, frame(Rect(x, y, w, h)));
		}
		//Show the current frame
		imshow("Frame", frame);
		//Get the keyboard input and check if it's 'Esc'
		//27->ASCII value of 'Esc' key
		ch = waitKey(30);
		if (ch == 27) {
			break;
		}
	}
	//Release the video capture object
	cap.release();
	destroyAllWindows();
	return 1;
}

未完

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值