【问题标题】:What is the method to detect whether a given picture is human face or not?检测给定图片是否为人脸的方法是什么?
【发布时间】:2014-04-24 21:40:38
【问题描述】:

是否有任何简单的算法来判断给定图像是人脸还是其他东西(希望无需训练)?

我的想法是构造每个图像的特征向量,然后应用一些聚类方法(例如 k-means 与 k = 2)。但我不确定即使获得了良好的聚类结果,区分人脸/非人脸的最佳标准是什么?

【问题讨论】:

  • 未经培训 - 没办法。 opencv 使用 haar/lbp boosted-cascade-classifiers 进行面部检测 和特征值/LBPH 特征进行recognition(但对于后者根本没有聚类,直接最近邻)
  • 如果没有任何培训,这将是相当困难的,但是您可以使用样本人脸分类器,但是,鲁棒性和准确性可能不是那么出色。

标签: algorithm opencv image-processing machine-learning computer-vision


【解决方案1】:

您可以使用 Haar 分类器方法在图像/视频帧中进行人脸检测。

在图像中查找人脸的示例代码如下所示

int main(int argc, _TCHAR* argv[])
{
    IplImage* img;
    img = cvLoadImage( "dasl_hubo.jpg" );
    CvMemStorage* storage = cvCreateMemStorage(0);
    // Note that you must copy C:\Program Files\OpenCV\data\haarcascades\haarcascade_frontalface_alt2.xml or where opencv is installed
    // to your working directory

    CvHaarClassifierCascade* cascade = (CvHaarClassifierCascade*)cvLoad( "haarcascade_frontalface_alt2.xml" );

    double scale = 1.3;

    static CvScalar colors[] = { {{0,0,255}}, {{0,128,255}}, {{0,255,255}}, 
    {{0,255,0}}, {{255,128,0}}, {{255,255,0}}, {{255,0,0}}, {{255,0,255}} };// this will draw rectangles of these colors around the detected faces.

    // Detect objects
    cvClearMemStorage( storage );
    CvSeq* objects = cvHaarDetectObjects( img, cascade, storage, 1.1, 4, 0, cvSize( 40, 50 ));

    CvRect* r;
    // Loop through objects and draw boxes
    for( int i = 0; i < (objects ? objects->total : 0 ); i++ ){
        r = ( CvRect* )cvGetSeqElem( objects, i );
        cvRectangle( img, cvPoint( r->x, r->y ), cvPoint( r->x + r->width, r->y + r->height ),
            colors[i%8]);
    }

    cvNamedWindow( "Output" );
    cvShowImage( "Output", img );
    cvWaitKey();

    cvReleaseImage( &img );

    return 0;
}

访问这些链接以了解有关使用 harr 级联的人脸检测的更多信息

drexel.edu

opencv documentation

presentation on Harr training and usages

【讨论】:

  • 哦,请不要将菜鸟指向已弃用的 c-api,他们几年前就迁移到 c++ 了,再也没有人应该编写这样的代码了。
  • @berak:首先,如果你写一个更好的答案就发布,第二个只是为了让事情简单,这里有人问如何检测面部,这是最简单的答案,因为我仍然相信您从 hello world 程序开始,而不是说 如何创建操作系统
  • @Shiva 非常感谢您的回答。我支持你。但我想知道这个问题是否有任何无监督算法?请注意,我不需要识别图像 A 是 Alice,B 是 Bob,我只想确定 A 和 B 都是人脸。谢谢。
  • @ChuNan:其中有很多(主要用于研究),但我没有使用过,就面部检测而言,Harr Cascade 也只是捕捉面部(假设它是面部的 harr 级联)并且无法识别它们。您还可以获得一个带有 opencv 本身的通用 Harr 文件,该文件将适合该建议。
  • @ChuNan:如果您想将 A 识别为 Alice 并将 B 识别为 Bob 或某个特定的人,那么您只需要以其他方式训练您自己的 Harr 文件,大多数情况下标准文件都可以。
【解决方案2】:

特征分解通过在具有高方差的数据空间中查找方向来减少连续域中的维数。 K-means 在空间中寻找高密度点的簇。您将它们混合在一起,同时完全忽略了您将如何首先获得面部特征(您将如何缩放、旋转和裁剪您想要检查的任何内容)。

您无需训练 Haar 检测器,因为它们已经针对人脸进行了训练。他们检测到一张脸,而不是识别它的身份。您所需要的只是将代码与一个小文件一起移植,其中包含训练后获得的参数(已经执行过),如 Shiva 建议的那样。

不过,不加思索地复制粘贴代码并没有多大意义。阅读一些关于Haar 的内容。试着理解

  1. 它们为什么起作用 - 面部具有在中间空间尺度上最明显的特征,例如眼睛、鼻子、眉毛。太小(瞳孔大小)或太大(整个脸部大小)的特征不太有用。
  2. 为什么 Haars 比小波或 Gabors 更受欢迎 - Haars 只是 Gabors 的原始(方形)近似值,但由于可以使用 Integral images 快速计算它们,因此它们优于更精确但速度较慢的对应物;
  3. 有什么限制 - Haars 有自己的空间尺度和方向,但可以快速重新计算为另一个尺度。
  4. 如何训练 Haar 分类器(您试图避免的最令人兴奋的话题)。 Ada boost 是训练由多个 Haars 组成的更复杂分类器的一种方法。最后,为了加快处理速度,您可以问一个稍微不同的问题,而不是找我一张脸。即,您可以尝试快速消除图像中不能是人脸的区域。这称为级联分类。以系统的方式研究这些方面,您将比从代码粘贴中学到更多关于人脸检测的知识。

【讨论】:

    【解决方案3】:

    这是我在 C++ 中的 opencv 代码,借助 Opencv haar-like 功能可以简单地检测图像中的人脸,您可以参考文档了解其中一些方法的用法。希望对你有帮助。

    CascadeClassifier face_cascade;  //for read in haar-like faces database in opencv
    std::vector<Rect> faces;         //for storing detected faces
    vector<Point2d> FaceCenter;      //for storing centres of faces
    
    Mat frame_gray = imread(“/Users/xxx/Desktop/xxx.jpg”, CV_8UC1);  //read the image in gray-scale;
    
    equalizeHist( frame_gray, frame_gray );                       //histogram to extract the contrast
    
    String face_cascade_name = "/Users/xxx/opencv-2.4.7/data/haarcascades/haarcascade_frontalface_alt.xml"; //path of the trained faces .xml file
    
    if(!face_cascade.load(face_cascade_name))  //load the .xml
    {
        cout << "face_casacade.xml load error" << endl;
    }
    
    face_cascade.detectMultiScale( frame_gray, faces, 1.1, 2, 0, Size(50, 50) ); //Detect faces in the image
    
    for(size_t i = 0; i < faces.size(); i++)
    {
        Point2d center(faces[i].x + faces[i].width*0.5, faces[i].y + faces[i].height*0.5); //store centres of faces
        FaceCenter.push_back(center);
    
        int radius = cvRound( (eyes[j].width + eyes[j].height)*0.25 ); //circle the faces in the image, optional
        ellipse( frame_gray, center, Size( eyes[j].width*0.5, eyes[j].height*0.25), 0, 0, 360, Scalar( 255, 0, 0 ), 2, 8, 0 );
    }
    
    imshow(“Faces Detection”, frame_gray); //show the result
    

    【讨论】:

      猜你喜欢
      • 2022-06-24
      • 2019-11-18
      • 2014-04-29
      • 2021-05-26
      • 2013-03-07
      • 2011-08-14
      • 2020-05-14
      • 2010-09-12
      • 2017-08-29
      相关资源
      最近更新 更多