OpenCV中基于LBP算法的人脸检测测试代码

        下面是OpenCV 3.3中基于CascadeClassifier类的LBP算法实现的人脸检测,从结果上看,不如其它开源库效果好,如libfacedetection,可参考 https://blog.csdn.net/fengbingchun/article/details/52964163 

#include "funset.hpp"
#include <string>
#include <vector>
#include <algorithm>
#include <opencv2/opencv.hpp>

namespace {

const std::string images_path_detect{ "E:/GitCode/Face_Test/testdata/detection/" };
const std::vector<std::string> images_name_detect{ "1.jpg", "2.jpg", "3.jpg", "4.jpg", "5.jpg", "6.jpg", "7.jpg", "8.jpg", "9.jpg", "10.jpg",
	"11.jpg", "12.jpg", "13.jpg", "14.jpg", "15.jpg", "16.jpg", "17.jpg", "18.jpg", "19.jpg", "20.jpg" };

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

		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 = images_path_detect + "result.png";
	cv::imwrite(output_image, dst);
}

} // namespace

int test_face_detect_LBP()
{
	const std::string lbp_files_path{ "E:/GitCode/Face_Test/testdata/lbpcascades/" };
	const std::vector<std::string> lbpcascades_files{ "lbpcascade_frontalface.xml", "lbpcascade_frontalface_improved.xml", "lbpcascade_profileface.xml" };

	cv::CascadeClassifier face_cascade(lbp_files_path+lbpcascades_files[0]);
	if (face_cascade.empty()) {
		fprintf(stderr, "classifier hasn't been loaded\n");
		return -1;
	}

	// Search for many objects in the one image.
	const int flags = cv::CASCADE_SCALE_IMAGE;
	// Smallest object size.
	const cv::Size min_feature_size = cv::Size(10, 10);
	// How detailed should the search be. Must be larger than 1.0.
	const float search_scale_factor = 1.1f;
	// How much the detections should be filtered out. This should depend on how bad false detections are to your system.
	// min_neighbors=2 means lots of good+bad detections, and min_neighbors=6 means only good detections are given but some are missed.
	const int min_neighbors = 2;
	const int scaled_width = 320;

	for (int i = 0; i < images_name_detect.size(); ++i) {
		std::string name = images_path_detect + images_name_detect[i];
		cv::Mat bgr = cv::imread(name, 1);
		cv::Mat gray = cv::imread(name, 0);
		if (!bgr.data || bgr.channels() != 3 || !gray.data || gray.channels() != 1) {
			fprintf(stderr, "read image fail: %s\n", name.c_str());
			return -1;
		}
		fprintf(stdout, "image name: %s: size(width, height): (%d, %d)\n", images_name_detect[i].c_str(), gray.cols, gray.rows);

		// possibly shrink the image to run much faster.
		cv::Mat resized, equalized;
		float scale = gray.cols / (float)scaled_width;
		if (gray.cols > scaled_width) {
			// Shrink the image while keeping the same aspect ratio.
			int scaled_height = cvRound(gray.rows / scale);
			cv::resize(gray, resized, cv::Size(scaled_width, scaled_height));
		} else {
			// Access the input image directly, since it is already small.
			resized = gray;
		}

		// standardize the brightness and contrast to improve dark images.
		cv::equalizeHist(resized, equalized);

		std::vector<cv::Rect> objects;
		// Detect objects in the small grayscale image.
		face_cascade.detectMultiScale(equalized, objects, search_scale_factor, min_neighbors, flags, min_feature_size);
		fprintf(stdout, "image name: %s: detect face count: %d\n", images_name_detect[i].c_str(), objects.size());

		// Enlarge the results if the image was temporarily shrunk before detection.
		if (gray.cols > scaled_width) {
			for (int j = 0; j < objects.size(); ++j) {
				objects[j].x = cvRound(objects[j].x * scale);
				objects[j].y = cvRound(objects[j].y * scale);
				objects[j].width = cvRound(objects[j].width * scale);
				objects[j].height = cvRound(objects[j].height * scale);
			}
		}

		for (int j = 0; j < objects.size(); ++j) {
			// Make sure the object is completely within the image, in case it was on a border.
			objects[j].x = std::max(objects[j].x, 0);
			objects[j].y = std::max(objects[j].y, 0);
			if (objects[j].x + objects[j].width > gray.cols) {
				objects[j].x = gray.cols - objects[j].width;
			}
			if (objects[j].y + objects[j].height > gray.rows) {
				objects[j].y = gray.rows - objects[j].height;
			}

			cv::rectangle(bgr, objects[j], cv::Scalar(0, 255, 0), 2);
		}

		std::string save_result = images_path_detect + "_" + images_name_detect[i];
		cv::imwrite(save_result, bgr);
	}

	save_mats();

	return 0;
} 

        检测结果如下:


GitHub: https://github.com/fengbingchun/Face_Test 

猜你喜欢

转载自blog.csdn.net/fengbingchun/article/details/79867667