OpenCV运用多个分类器进行人脸检测

逻辑:用灰度直方图并增加对比度来提高识别成功率;将灰度图中已经被识别的部分涂黑再进行下一次识别以防止多个分类器重复识别同一张人脸。

需先配置OpenCV。
C++代码:

#include <iostream>
#include <opencv2\opencv.hpp>
#include <opencv2\imgproc\types_c.h>
#include <opencv2\objdetect\objdetect.hpp> 
#include <opencv2\calib3d\calib3d.hpp>

using namespace std;
using namespace cv;
int main()
{

	Mat image,image_gray;      //定义两个Mat变量,用于存储每一帧的图像
	int a=0;
	string c = "9.png";      //图片路径

	image = imread(c);
	cvtColor(image, image_gray, CV_BGR2GRAY);//转为灰度图
	equalizeHist(image_gray, image_gray);//直方图均衡化,增加对比度方便处理

	CascadeClassifier face_cascade1;    //载入分类器1

									   //加载分类训练器,OpenCv官方文档提供的xml文档,可以直接调用
									   //xml文档路径  opencv\sources\data\haarcascades 
	if (!face_cascade1.load("D:\\OpenCV\\opencv\\sources\\data\\haarcascades\\haarcascade_frontalface_alt.xml"))  //需要将xml文档放在自己指定的路径下
	{
		cout << "Load haarcascade_frontalface_alt.xml failed!" << endl;
		return 0;
	}
	CascadeClassifier face_cascade2;    //载入分类器2
	if (!face_cascade2.load("D:\\OpenCV\\opencv\\sources\\data\\haarcascades\\haarcascade_frontalface_alt2.xml"))  //需要将xml文档放在自己指定的路径下
	{
		cout << "Load haarcascade_frontalface_alt.xml failed!" << endl;
		return 0;
	}


	//vector 是个类模板 需要提供明确的模板实参 vector<Rect>则是个确定的类 模板的实例化
	vector<Rect> faceRect1;
	vector<Rect> faceRect2;


	//检测关于脸部位置
	face_cascade1.detectMultiScale(image_gray,faceRect1);
	a = a + faceRect1.size();
	for (size_t i = 0; i < faceRect1.size(); i++)
	{
		rectangle(image, faceRect1[i], Scalar(0, 255, 0));      //用矩形画出检测到的位置
		rectangle(image_gray, faceRect1[i], Scalar(0, 0, 0),-1,4);	//在灰度图中涂黑
	}
	face_cascade2.detectMultiScale(image_gray, faceRect2);
	for (size_t i = 0; i < faceRect2.size(); i++)
	{
		rectangle(image, faceRect2[i], Scalar(0, 0, 255));      //用矩形画出检测到的位置
	}
	a = a + faceRect2.size();
	imshow("find", image);         //显示当前帧
	cout << "find " << a << " faces";
	//imwrite(c,image);
	waitKey(0);
	return 0;
}

测试结果:
在这里插入图片描述
JAVA代码:

package FaceDetect;
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.MatOfRect;
import org.opencv.core.Point;
import org.opencv.core.Rect;
import org.opencv.core.Scalar;
import org.opencv.core.Size;
import org.opencv.imgproc.Imgproc;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.objdetect.CascadeClassifier;
public class FaceDetect {
	public static void main(String[] args) {
		 
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
        System.out.println("\nRunning FaceDetector");
 
        String xmlPath1 = "D:\\workspace\\videoStreamDetector\\haarcascade_frontalface_alt.xml";	//分类器1
        String xmlPath2 = "D:\\workspace\\videoStreamDetector\\haarcascade_frontalface_alt2.xml";	//分类器2
        CascadeClassifier faceDetector1 = new CascadeClassifier(xmlPath1);
        CascadeClassifier faceDetector2 = new CascadeClassifier(xmlPath2);
        String imgPath = "30.png";	//图片路径
        Mat image = Imgcodecs.imread(imgPath);
        Mat image_gray=new Mat();
        Imgproc.cvtColor(image, image_gray, Imgproc.COLOR_BGR2GRAY);
        Imgproc.equalizeHist(image_gray,image_gray);
        
        MatOfRect faceDetections1 = new MatOfRect();
        faceDetector1.detectMultiScale(image_gray, faceDetections1);
 
        int a=faceDetections1.toArray().length;
        	for (Rect rect : faceDetections1.toArray()) {
                Imgproc.rectangle(image, new Point(rect.x, rect.y), new Point(rect.x + rect.width, rect.y + rect.height),new Scalar(0, 255, 0));
                Imgproc.rectangle(image_gray, new Point(rect.x, rect.y), new Point(rect.x + rect.width, rect.y + rect.height),new Scalar(0, 0, 0),-1,4);
        	}
        MatOfRect faceDetections2 = new MatOfRect();
        faceDetector2.detectMultiScale(image_gray, faceDetections2);
 
        a=a+faceDetections2.toArray().length;
        	for (Rect rect : faceDetections2.toArray()) {
                Imgproc.rectangle(image, new Point(rect.x, rect.y), new Point(rect.x + rect.width, rect.y + rect.height),new Scalar(0, 0, 255));
            }

        System.out.println(String.format("Detected %s faces",a));
        String filename = "ouput.png";
        System.out.println(String.format("Writing %s", filename));
        Imgcodecs.imwrite(filename, image);
    }

	}

JAVA中没有imshow,所以只能通过imwrite保存结果图片来观察测试结果。

总结:利用同样的逻辑可用多个分类器对图像进行识别,提高识别到人脸的概率,缺点是所有分类器中错误识别的结果都会被返回,可以通过修改detectMultiScale的参数在一定程度上减少错误识别的情况。

C++人脸检测部分代码参考:OpenCv 之(图片人脸识别)和 (摄像头读入)
JAVA配置环境及部分代码参考:利用Java调用OpenCV进行人脸识别

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值