JavaOpenCV学习笔记(3):人脸检测解决旋转图片验证


前言

去年年尾曾经搞过某个图片旋转验证,需要把 4 张图片转到正向才能通过验证:

你们还真拿验证码打广告呀

当时的第一反应是只有正向的时候才能检测出人脸,可以拿人脸检测来做,可惜当时并不知道该怎么在项目里接入人脸检测,也不方便使用第三方 API。最后发现这些验证图片是数量并不是很多,于是就把这些图全部爬了下来,人工做了方向标注(可把我累死啦),然后用相似哈希来做匹配。这种粗暴的做法(像不像刷 OJ 打表)有一个致命的缺点,只要对方更新图库,甚至是改成动态出题,就会直接被废掉。

今天突然想起来,其实静态图片检测个人脸,实在也没多大难度。

调包小子请求出战

OpenCV 直接提供了几个人脸检测模型,可以直接拿来用,虽然这几个模型并不是很强,但至少解决这个图片验证是足够了。

直接上代码:

package opencv;

import opencv.match.Face;
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.MatOfRect;
import org.opencv.core.Point;
import org.opencv.core.Scalar;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import org.opencv.objdetect.CascadeClassifier;
import utils.ImageUtils;
import utils.ImageViewer;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

import static org.opencv.imgcodecs.Imgcodecs.IMREAD_COLOR;

/**
 * @author yuanbug
 * date: 2020/5/13
 */
public class Face {
    static {
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
    }

    private static String FACE_DATA_PATH = String.valueOf(Face.class.getClassLoader().getResource("haarcascade_frontalface_alt.xml")).replace("file:/", "");
    private static final String[] IMAGE_PATH = {
            "D:/test/img1.jpg",
            "D:/test/img2.jpg",
            "D:/test/img3.jpg",
            "D:/test/img4.jpg"
    };

    public static void main(String[] args) {
        CascadeClassifier faceClassifier = new CascadeClassifier(FACE_DATA_PATH);
        List<Mat> images = Arrays.stream(IMAGE_PATH)
                .map(path -> Imgcodecs.imread(path, IMREAD_COLOR))
                .peek(image -> {
                    MatOfRect faceRect = new MatOfRect();
                    faceClassifier.detectMultiScale(image, faceRect);
                    System.out.println("有脸: " + faceRect.empty());
                    faceRect.toList().forEach(rec -> Imgproc.rectangle(image, new Point(rec.x, rec.y), new Point(rec.x + rec.width, rec.y + rec.height), new Scalar(255, 0, 0)));
                })
                .collect(Collectors.toList());
        new ImageViewer(ImageUtils.horizontalConcat(images), "人脸检测", true);
    }
}

运行结果:

只有正向能检测到人脸

实验说明,这个思路是可行的。拿到验证图片后,先切割成 4 张小图,然后看看需要旋转多少次才能检测到人脸,就能得到点击次数了。

书到用时方恨少,多懂一点东西,就可以少干很多苦力活呀!


文章作者: yuanbug
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 yuanbug !
评论
  目录