opencv - FDDB评估代码

标签 opencv face-detection evaluation dlib evaluate

我正在研究 opencv 和 dlib,以便在大学项目中使用人脸检测器,而且我对机器学习和计算机视觉这整件事真的很陌生。如何使用来自 FDDB 的评估代码评估我的人脸检测代码?我正在使用 dlib 的 CNN 方法从图像中检测人脸。

import cv2
import dlib

image = cv2.imread('..\\pessoas\\beatles.jpg')

detector = dlib.cnn_face_detection_model_v1("..\\mmods\\mmod_human_face_detector.dat")
detectedFaces = detector(image)

for face in detectedFaces:
    l, t, r, b, c = (int(face.rect.left()), int(face.rect.top()), int(face.rect.right()), int(face.rect.bottom()),
                 face.confidence)
    cv2.rectangle(image, (l, t), (r, b), (255, 0, 0), 2)

cv2.imshow("CNN Detector", image)
cv2.waitKey(0)
cv2.destroyAllWindows()

如您所见,代码非常简单,但我必须计算精度、召回率和 F1 分数来绘制 ROC 曲线,但我还不知道该怎么做,项目的自述文件github没有帮助。

最佳答案

对于ubuntu16的我来说,必须按照以下步骤来完成:

  1. 下载检测人脸的fddb原始图像数据集,得到检测结果,可以下载here .这是我的目录: enter image description here

  2. 将所有图片文件路径加入一个txt文件,将所有fddb注释加入一个txt文件。 您可以下载所有文件here

enter image description here

对于我来说,我将所有的FDDB-FOLD-%d.txt 移动到目录all_file_path,然后通过cat * 将它们合并到一个文件中> 文件路径.txt

enter image description here

通过cat *ellipse*.txt > annotFile.txt将所有的FDDB-fold-%d-ellipseList.txt合并成一个txt

请注意,您可能不需要创建它,因为 runEvaluate.pl 已在运行过程中为您创建。

3.创建FDDB evalute exe,在这里下载源代码here 然后编译,可以改makefile,看原因here , 添加

INCS = -I/usr/local/include/opencv

LIBS = -L/usr/local/lib -lopencv_core -lopencv_imgproc -lopencv_highgui
       -lopencv_ml -lopencv_video -lopencv_features2d -lopencv_calib3d 
       -lopencv_objdetect -lopencv_contrib -lopencv_legacy

生成文件。

  1. 求值,可以用runEvaluate.pl来求值,但我(ubuntu16),不能直接运行。

    4.1 更改GUNPLOT路径(需要先安装gnuplot,使用它创建ROC图像)

enter image description here

4.2 我用的是矩形检测模型,所以我把$detFormat改成0。

我的 $detFormat = 0; # 0:矩形,1:椭圆 2:像素

4.3 所有图片的相对路径:

my $listFile ="/home/xy/face_sample/evaluation/compareROC/FDDB-folds/filePath.txt";

4.4 所有图片标注

my $annotFile = "/home/xy/face_sample/evaluation/compareROC/FDDB-folds/annotFile.txt";

4.5 你要生成的roc文件(通过evaluate exe创建):

my $gpFile ="/home/xy/face_sample/evaluation/compareROC/createROC.p";

4.6 你的检测文件(后面会给出如何创建)

my $detFile ="/home/xy/face_sample/evaluation/compareROC/detDir/fddb_rect_ret1.txt";

It’s content like that:

enter image description here

'runEvaluate.pl' 有一些错误,将执行评估更改为以下内容:

system($evaluateBin, "-a", $annotFile, "-d", $detFile, "-f", $detFormat, "-i", $imDir, "-l", $listFile, "-r", $detDir, "-z", ".jpg");

也可以使用命令查看:

enter image description here

xy@xy:~/face_sample/evaluation/compareROC$ ./evaluate \
> -a /home/xy/face_sample/evaluation/compareROC/FDDB-folds/annotFile.txt \
> -d /home/xy/face_sample/evaluation/compareROC/detDir/fddb_rect_ret1.txt \
> -f 0 \
> -i /home/xy/face_sample/evaluation/compareROC/originalPics/ \
> -l /home/xy/face_sample/evaluation/compareROC/FDDB-folds/filePath.txt \
> -r /home/xy/face_sample/evaluation/compareROC/detDir/ \
> -z .jpg

使用python创建fddb评估txt文件:

def get_img_relative_path():
    """
    :return: ['2002/08/11/big/img_344', '2002/08/02/big/img_473', ......]
    """
    f_name = 'E:/face_rec/face__det_rec_code/face_det/FDDB-folds/all_img_files.txt'
    lst_name = open(f_name).read().split('\n')

    return lst_name

def write_lines_to_txt(lst):
    # lst = ['line1', 'line2', 'line3']
    f_path = 'fddb_rect_ret.txt'
    with open(f_path, 'w') as fp:

        for line in lst:
            fp.write("%s\n" % line)

# For example use opencv to face detection
def detect_face_lst(img):
    """
    :param img: opencv image 
    :return: face rectangles [[x, y, w, h], ..........]
    """
    m_path = 'D:/opencv/sources/data/haarcascades/haarcascade_frontalface_default.xml'
    face_cascade = cv2.CascadeClassifier(m_path)

    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

    faces = face_cascade.detectMultiScale(gray, 1.3, 5)

    return faces


def generate_fddb_ret():
    # The directory from which we get the test images from FDDB
    img_base_dir = 'E:/face_rec/face__det_rec_code/face_det/originalPics/'

    # All the images relative path, like '['2002/08/11/big/img_344', '2002/08/02/big/img_473', ......]'
    lst_img_name = get_img_relative_path()

    # Store detect result, like:
    # ['2002/08/11/big/img_344', '1', '10 10 50 50 1', .............]
    lst_write2_fddb_ret = []

    try:
        for img_name in lst_img_name:
            img_full_name = img_base_dir + img_name + '.jpg'
            img = cv2.imread(img_full_name)

            if img == None:
                print 'error %s not exists, can not generate complete fddb evaluate file' % img_full_name
                return -1

            lst_face_rect = detect_face_lst(img)

            # append img name like '2002/08/11/big/img_344'
            lst_write2_fddb_ret.append(img_name)

            face_num = len(lst_face_rect)
            # append face num, note if no face 0 should be append
            lst_write2_fddb_ret.append(str(face_num))

            if face_num > 0:
                # append each face rectangle x y w h score
                for face_rect in lst_face_rect:
                    # append face rectangle x, y, w, h score
                    # note: opencv hava no confidence so use 1 here
                    s_rect = " ".join(str(item) for item in face_rect) + " 1"
                    lst_write2_fddb_ret.append(s_rect)

    except Exception as e:
        print 'error %s , can not generate complete fddb evaluate file' % e
        return -1

    # Write all the result to txt for FDDB evaluation
    write_lines_to_txt(lst_write2_fddb_ret)

运行上面的代码后就可以创建FDDB结果了: enter image description here

注意:在windows下创建上面的txt,如果在ubuntu下测试可能会报如下错误Incompatible annotation and detection files。查看输出规范:

enter image description here

只需将内容复制到一个新的txt文件(在ubuntu中创建)即可解决。

结果如下:

enter image description here

一些提示:

  1. 你可以看到runEvaluate.pl这并不难,上面的改动可能不需要。你也可以改变runEvaluate.pl中的一些变量,像 $GNUPLOT, $imDir 等等。 添加 "-z", ".jpg" 到 系统($evaluateBin,“-a”,$annotFile,“-d”,$detFile,“-f”,$detFormat,“-i”,$imDir,“-l”,$listFile,“-r”, $detDir);

    system($evaluateBin, "-a", $annotFile, "-d", $detFile, "-f", $detFormat, "-i", $imDir, "-l", $listFile, "- r", $detDir, "-z", ".jpg");

  2. 您还可以阅读evaluate代码(主要是evaluate.cpp,比较通俗易懂),让您对如何评估它。

关于opencv - FDDB评估代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50542775/

相关文章:

c++ - OpenCV 3.0 : Calibration not fitting as expected

opencv - 使用 Azure 机器学习检测图像中的符号

android - FaceDetector.Builder().build(getApplicationContext()) 给我错误

c++ - If 语句 - 不正确的评估

jsp - EL 会自动转换/转换类型吗? ${a.name} 实际上是如何工作的?

opencv - 在 OpenCV 图像拼接中混合伪影

java - 无法在android中实现描述符

python - Python 的面部和头发检测

python-3.x - 保存面孔openCV

C++11 declval : what is "unevaluated context"?