基于opencv的人脸检测

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

一、环境准备

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

09459bfc44fa5dcb7631c38ed3b13da7c7f.jpg

2.配置java.library.path

8778b0be66718752fa9d072064a948af007.jpg

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

最终效果:

a19c83b26b616b0a8c77ae417170f310ab2.jpg8755a096e38c970e9cc3b3ac048be9a9e66.jpg

转载于:https://my.oschina.net/u/1271447/blog/2993533

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值