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

一、环境准备

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

基于opencv的人脸检测-LMLPHP

2.配置java.library.path

基于opencv的人脸检测-LMLPHP

3.配置jar依赖

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

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

二、opencv官网示例代码

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

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();
    }
}

最终效果:

基于opencv的人脸检测-LMLPHP基于opencv的人脸检测-LMLPHP

12-26 17:57