Dlib库中提供了正脸人脸关键点检测的接口,这里参考dlib/examples/face_landmark_detection_ex.cpp中的代码,通过调用Dlib中的接口,实现正脸人脸关键点检测的测试代码,测试代码如下:

/* reference: dlib/examples/face_landmark_detection_ex.cpp
  This program shows how to find frontal human faces in an image and
  estimate their pose.  The pose takes the form of 68 landmarks.  These are
  points on the face such as the corners of the mouth, along the eyebrows, on
  the eyes, and so forth
*/
int test_face_landmark()
{
	// download: http://dlib.net/files/shape_predictor_68_face_landmarks.dat.bz2
	const std::string shape_predictor_68_face_landmarks = "E:/GitCode/Face_Test/src/dlib/data/shape_predictor_68_face_landmarks.dat";

	// We need a face detector.  We will use this to get bounding boxes for
	// each face in an image.
	dlib::frontal_face_detector detector = dlib::get_frontal_face_detector();

	// And we also need a shape_predictor.  This will predict face
	// landmark positions given an image and face bounding box
	dlib::shape_predictor sp;
	dlib::deserialize(shape_predictor_68_face_landmarks) >> sp;

	std::vector<std::string> images{ "1.jpg", "2.jpg", "3.jpg", "4.jpeg", "5.jpeg", "6.jpg", "7.jpg", "8.jpg", "9.jpg", "10.jpg",
		"11.jpeg", "12.jpg", "13.jpeg", "14.jpg", "15.jpeg", "16.jpg", "17.jpg", "18.jpg", "19.jpg", "20.jpg" };
	std::vector<int> count_faces{ 1, 2, 6, 0, 1, 1, 1, 2, 1, 1,
		1, 1, 1, 1, 1, 1, 1, 0, 8, 2 };

	std::string path_images{ "E:/GitCode/Face_Test/testdata/" };

	if (images.size() != count_faces.size()) {
		fprintf(stderr, "their size that images and count_faces are mismatch\n");
		return -1;
	}

	for (int i = 0; i < images.size(); i++) {
		cv::Mat matSrc = cv::imread(path_images + images[i], 1);
		if (matSrc.empty()) {
			fprintf(stderr, "read image error: %s\n", images[i].c_str());
			return -1;
		}

		dlib::array2d<unsigned char> img;
		dlib::load_image(img, path_images + images[i]);
		// Make the image larger so we can detect small faces.
		pyramid_up(img);

		// Now tell the face detector to give us a list of bounding boxes
		// around all the faces it can find in the image.
		std::vector<dlib::rectangle> dets = detector(img);
		fprintf(stderr, "detect face count: %d, actual face count: %d\n", dets.size(), count_faces[i]);

		// Now we will go ask the shape_predictor to tell us the pose of
		// each face we detected.
		std::vector<dlib::full_object_detection> shapes;
		for (unsigned long j = 0; j < dets.size(); ++j) {
			dlib::full_object_detection shape = sp(img, dets[j]);
			fprintf(stderr, "landmark num: %d\n", shape.num_parts());
			dlib::rectangle rect = shape.get_rect();
			fprintf(stderr, "rect: left = %d, top = %d, width = %d, height = %d\n", rect.left() / 2, rect.top() / 2, rect.width() / 2, rect.height() / 2);
			cv::rectangle(matSrc, cv::Rect(rect.left() / 2, rect.top() / 2, rect.width() / 2, rect.height() / 2), cv::Scalar(0, 255, 0), 2);

			for (int pt = 0; pt < shape.num_parts(); pt++) {
				cv::circle(matSrc, cv::Point(shape.part(pt).x() / 2, shape.part(pt).y() / 2), 1, cv::Scalar(0, 0, 255), 2);
			}
		}

		std::string save_result = path_images + "_" + images[i];
		cv::imwrite(save_result, matSrc);
	}

	int width = 200;
	int height = 200;
	cv::Mat dst(height * 5, width * 4, CV_8UC3);
	for (int i = 0; i < images.size(); i++) {
		std::string input_image = path_images + "_" + images[i];
		cv::Mat src = cv::imread(input_image, 1);
		if (src.empty()) {
			fprintf(stderr, "read image error: %s\n", images[i].c_str());
			return -1;
		}

		cv::resize(src, src, cv::Size(width, height), 0, 0, 4);
		int x = (i * width) % (width * 4);
		int y = (i / 4) * height;
		cv::Mat part = dst(cv::Rect(x, y, width, height));
		src.copyTo(part);
	}
	std::string output_image = path_images + "result.png";
	cv::imwrite(output_image, dst);

	return 0;
}

执行结果如下图:

Dlib库中实现正脸人脸关键点(landmark)检测的测试代码-LMLPHP

  人脸关键点检测结果如下:
Dlib库中实现正脸人脸关键点(landmark)检测的测试代码-LMLPHP

05-04 05:52