基于opencv的人脸检测

因为项目须要了解下图像识别,看到opencv有丰富的类库,就到官网看了下例子,由于自己项目是基于java的,因此尝试改为java版本熟悉下opencv。这里只是说人脸检测,还没能识别是谁的脸。html

1、环境准备

1.下载opencv,以下因为网络缘由下到了opencv-3.4.1,下载完成后执行安装,下面的opencv就是解压后的目录java

2.配置java.library.path网络

3.配置jar依赖app

~\opencv\build\java这个目录下有个jar包opencv-341.jar添加到工程依赖,用maven的话能够手动添加jar包依赖,也能够从中央仓库下载。阿里云仓库找到以下版本了。也能够用。System.loadLibrary(Core.NATIVE_LIBRARY_NAME);改为System.loadLibrary("opencv_java341");maven

<dependency>
            <groupId>org.openpnp</groupId>
            <artifactId>opencv</artifactId>
            <version>3.2.0-1</version>
        </dependency>

2、opencv官网示例代码

https://docs.opencv.org/4.0.1/d4/d26/samples_2cpp_2facedetect_8cpp-example.html,这个是C++版本,翻译下来:ui

public class NesttyMain  {
    public static void main(String[] args){
        System.out.println(System.getProperty("java.library.path"));
        System.loadLibrary("opencv_java341");
        CascadeClassifier cascade= new CascadeClassifier();
        CascadeClassifier nestedCascade = new CascadeClassifier();
//下面的训练好的文件改为本身的目录        
        cascade.load("D:\\3rd_app\\opencv3.4.1\\opencv\\build\\etc\\haarcascades\\haarcascade_frontalface_alt.xml");
        nestedCascade.load("D:\\3rd_app\\opencv3.4.1\\opencv\\build\\etc\\haarcascades\\haarcascade_eye_tree_eyeglasses.xml");
        Mat image = Imgcodecs
                .imread("C:\\Users\\Administrator\\Desktop\\3women.jpg");
        detectAndDraw(image,cascade,nestedCascade,1,false);
    }

    static void  detectAndDraw( Mat img, CascadeClassifier cascade,
                        CascadeClassifier nestedCascade,
                        double scale, boolean tryflip ) {
        double t = 0;
        MatOfRect faces = new MatOfRect();
        MatOfRect faces2 = new MatOfRect();
        Scalar colors[] =
                {
                        new Scalar(255, 0, 0),
                        new Scalar(255, 128, 0),
                        new Scalar(255, 255, 0),
                        new Scalar(0, 255, 0),
                        new Scalar(0, 128, 255),
                        new Scalar(0, 255, 255),
                        new Scalar(0, 0, 255),
                        new Scalar(255, 0, 255)
                };
        Mat gray = new Mat();
        Mat smallImg = new Mat();
        Imgproc.cvtColor(img, gray, Imgproc.COLOR_BGR2GRAY);
        double fx = 1 / scale;
        Imgproc.resize(gray, smallImg, new Size(), fx, fx, 5);
        Imgproc.equalizeHist(smallImg, smallImg);
        t = (double) Core.getTickCount();

        cascade.detectMultiScale(smallImg, faces,
                1.1, 2, 0
                        //|CASCADE_FIND_BIGGEST_OBJECT
                        //|CASCADE_DO_ROUGH_SEARCH
                        | CASCADE_SCALE_IMAGE,
                new Size(),
                new Size(150, 150));
        if (tryflip) {
            Core.flip(smallImg, smallImg, 1);
            cascade.detectMultiScale(smallImg, faces2,
                    1.1, 2, 0
                            //|CASCADE_FIND_BIGGEST_OBJECT
                            //|CASCADE_DO_ROUGH_SEARCH
                            | CASCADE_SCALE_IMAGE,
                    new Size(0, 0),
                    new Size(300, 300));
            for (Rect rect : faces2.toArray()) {
                Imgproc.rectangle(img, new Point(rect.x, rect.y), new Point(rect.x + rect.width, rect.y + rect.height), new Scalar(0, 255, 0));
            }
        }
        t = (double) Core.getTickCount() - t;
        System.out.println(String.format("detection time = %g ms\n", t * 1000 / Core.getTickFrequency()));
        System.out.println(String.format("detection faces = %s \n", faces.toArray().length));
        int i = 0;
        for (Rect rect : faces.toArray()) {
            Rect r = rect;
            Mat smallImgROI;
            MatOfRect nestedObjects = new MatOfRect();
            Point center = new Point();
            Scalar color = colors[i % 8];
            int radius;
            double aspect_ratio = (double) r.width / r.height;
            if (0.75 < aspect_ratio && aspect_ratio < 1.3) {
                center.x = Math.round((r.x + r.width * 0.5) * scale);
                center.y = Math.round((r.y + r.height * 0.5) * scale);
                radius = (int) Math.round((r.width + r.height) * 0.25 * scale);
                Imgproc.circle(img, center, radius, color, 3, 8, 0);
            } else
                Imgproc.rectangle(img, new Point(Math.round(r.x * scale), Math.round(r.y * scale)),
                        new Point(Math.round((r.x + r.width - 1) * scale), Math.round((r.y + r.height - 1) * scale)),
                        color, 3, 8, 0);
            if (nestedCascade.empty())
                continue;
            smallImgROI = smallImg.submat(r);
            nestedCascade.detectMultiScale(smallImgROI, nestedObjects,
                    1.1, 2, 0
                            //|CASCADE_FIND_BIGGEST_OBJECT
                            //|CASCADE_DO_ROUGH_SEARCH
                            //|CASCADE_DO_CANNY_PRUNING
                            | CASCADE_SCALE_IMAGE,
                    new Size(),
                    new Size(40, 40));
            System.out.println(String.format("detection eyes = %s \n", nestedObjects.toArray().length));
            for (Rect rectNested : nestedObjects.toArray()) {
                {
                    Rect nr = rectNested;
                    center.x = Math.round((r.x + nr.x + nr.width * 0.5) * scale);
                    center.y = Math.round((r.y + nr.y + nr.height * 0.5) * scale);
                    radius = (int) Math.round((nr.width + nr.height) * 0.25 * scale);
                    Imgproc.circle(img, center, radius, color, 3, 8, 0);
                }
                i++;
            }
            Imgcodecs.imwrite("ouput.png", img);
        }
        img.dump();
    }
}

最终效果:阿里云

相关文章
相关标签/搜索