使用python即opencv

时间:2019-04-16 08:28:41

标签: python opencv face-detection motion-blur

我正在检测具有级联的面孔,并使用OpenCV使用网络摄像头对其进行跟踪。我需要保存被跟踪的每个面孔。但是问题是人们在移动时。在这种情况下,脸部会变得模糊。

我已经尝试使用opencv的dnn人脸检测器和Laplacian使用以下代码来缓解此问题:

blob = cv2.dnn.blobFromImage(cropped_face, 1.0, (300, 300), (104.0, 177.0, 123.0))
net.setInput(blob)
detections = net.forward()
confidence = detections[0, 0, 0, 2]
blur = cv2.Laplacian(cropped_face, cv2.CV_64F).var()
if confidence >= confidence_threshold and blur >= blur_threshold:
    cv2.imwrite('less_blurry_image', cropped_face)

在这里,我尝试限制保存的脸部(如果由于运动setting blur_threshold而导致的模糊不模糊,将其保存为500,将confidence_threshold的保存为0.98(即98%)。

但是问题是,如果我更换相机,则必须再次手动更改阈值。而且在大多数情况下,设置阈值会忽略大多数面孔。

此外,由于背景始终比模糊的面孔清晰,因此很难检测到。

所以我的问题是如何检测到脸上的运动模糊。我知道我可以训练一个ML模型来检测人脸的运动模糊。但这将需要大量的处理资源来完成一项小任务。

此外,如果我走那条路线,我将需要大量带注释的数据进行培训。对于像我这样的学生来说,这并不容易。

因此,我正在尝试使用OpenCV进行检测,与使用ML模型进行检测相比,这将节省大量资源。

是否有任何资源密集型解决方案?

2 个答案:

答案 0 :(得分:1)

如@PlinyTheElder所述,DCT信息可以使您运动模糊。我正在附上以下repo的代码段:

代码在C中,我不确定libjpeg是否有python绑定。否则,您需要创建一个。

/* Fast blur detection using JPEG DCT coefficients
 *
 * Based on "Blur Determination in the Compressed Domain Using DCT
 * Information" by Xavier Marichal, Wei-Ying Ma, and Hong-Jiang Zhang.
 *
 * Tweak MIN_DCT_VALUE and MAX_HISTOGRAM_VALUE to adjust
 * effectiveness.  I reduced these values from those given in the
 * paper because I find the original to be less effective on large
 * JPEGs.
 *
 * Copyright 2010 Julian Squires <julian@cipht.net>
 */

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <jpeglib.h>

static int min_dct_value = 1;   /* -d= */
static float max_histogram_value = 0.005; /* -h= */

static float weights[] = {  /* diagonal weighting */
    8,7,6,5,4,3,2,1,
    1,8,7,6,5,4,3,2,
    2,1,8,7,6,5,4,3,
    3,2,1,8,7,6,5,4,
    4,3,2,1,8,7,6,5,
    5,4,3,2,1,8,7,6,
    6,5,4,3,2,1,8,7,
    7,6,5,4,3,2,1,8
};
static float total_weight = 344;

static inline void update_histogram(JCOEF *block, int *histogram)
{
    for(int k = 0; k < DCTSIZE2; k++, block++)
        if(abs(*block) > min_dct_value) histogram[k]++;
}

static float compute_blur(int *histogram)
{
    float blur = 0.0;
    for(int k = 0; k < DCTSIZE2; k++)
        if(histogram[k] < max_histogram_value*histogram[0])
            blur += weights[k];
    blur /= total_weight;
    return blur;
}


static int operate_on_image(char *path)
{
        struct jpeg_error_mgr jerr;
    struct jpeg_decompress_struct cinfo;
    jvirt_barray_ptr *coeffp;
    JBLOCKARRAY cs;
    FILE *in;
    int histogram[DCTSIZE2] = {0};

        cinfo.err = jpeg_std_error(&jerr);
        jpeg_create_decompress(&cinfo);
    if((in = fopen(path, "rb")) == NULL) {
        fprintf(stderr, "%s: Couldn't open.\n", path);
        jpeg_destroy_decompress(&cinfo);
        return 0;
    }
    jpeg_stdio_src(&cinfo, in);
    jpeg_read_header(&cinfo, TRUE);
    // XXX might be a little faster if we ask for grayscale
    coeffp = jpeg_read_coefficients(&cinfo);

    /* Note: only looking at the luma; assuming it's the first component. */
    for(int i = 0; i < cinfo.comp_info[0].height_in_blocks; i++) {
        cs = cinfo.mem->access_virt_barray((j_common_ptr)&cinfo, coeffp[0], i, 1, FALSE);
        for(int j = 0; j < cinfo.comp_info[0].width_in_blocks; j++)
            update_histogram(cs[0][j], histogram);
    }

    printf("%f\n", compute_blur(histogram));
    // output metadata XXX should be in IPTC etc

    // XXX also need to destroy coeffp?
    jpeg_destroy_decompress(&cinfo);
    return 0;
}

int main(int argc, char **argv)
{
    int status, i;

    for(status = 0, i = 1; i < argc; i++) {
        if(argv[i][0] == '-') {
            if(argv[i][1] == 'd')
                sscanf(argv[i], "-d=%d", &min_dct_value);
            else if(argv[i][1] == 'h')
                sscanf(argv[i], "-h=%f", &max_histogram_value);
            continue;
        }
        status |= operate_on_image(argv[i]);
    }

    return status;
}

编译代码:

gcc -std=c99 blur_detection.c -l jpeg -o blur-detection

运行代码:

./blur-detection <image path>

答案 1 :(得分:0)

您可能可以使用傅立叶变换(FFT)或离散余弦变换(DCT)来计算面部的模糊程度。图像模糊会导致高频消失,仅剩下低频。

因此,您需要拍摄一张脸部图像,将其零填充到适合FFT或DCT的大小,然后查看较高频率下的频谱功率。

您可能不需要FFT-DCT就足够了。 DCT的优点是它可以产生实值结果(无虚部)。在性能方面,FFT和DCT对于2的幂的大小以及仅包含2、3和5的大小的速度确实非常快(尽管如果您也有3和5的话,速度会慢一些) )。