如何检测一张图片是否为人脸?

3

有没有简单的算法可以判断一张给定的图片是人脸还是其他东西(最好不需要训练)?

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


没有训练就没有办法。OpenCV使用Haar/LBP增强级联分类器进行人脸检测,使用特征值/LBPH进行识别(但后者没有聚类,直接最近邻)。 - berak
完成后,返回翻译的文本: 一些测试图像 - AakashM
如果没有任何训练,那么这将非常困难。然而,有一些可以使用的样本人脸分类器,但是其鲁棒性和准确性可能不是很出色。 - rockinfresh
3个回答

4
Eigen分解通过在数据空间中找到方差高的方向来降低连续域中的维度。K-means在具有高密度点的空间中查找聚类。您在完全忽略如何到达第一位面部特征的情况下将它们混合在一起(您将如何缩放,旋转和裁剪要检查的任何内容)。
您不需要训练Haar检测器,因为它们已经针对面部进行了训练。它们检测面部,而不是识别其身份。您所需的只是将代码与参数文件一起传输,这些参数是在训练后(已经执行)获得的,正如Shiva上面建议的那样。
然而,毫无思考地复制粘贴代码并没有多大意义。阅读一些关于 Haar的内容。尝试理解。
  1. 为什么它们能够工作 - 人脸具有最明显的中等空间尺度特征,例如眼睛、鼻子和眉毛。太小(瞳孔大小)或太大(整个面部大小)的特征不太有用。
  2. 为什么Haar比小波或Gabor更受青睐 - Haar只是Gabor的原始(盒状)近似,但由于可以通过积分图像Integral images快速计算,因此它们比更精确但速度较慢的替代品更受青睐;
  3. 有哪些限制 - Haar具有自己的空间尺度和方向,但可以快速重新计算为另一个尺度。
  4. 如何训练Haar分类器(您试图避免的最令人兴奋的主题)。Ada boost是训练由几个Haar组成的更复杂分类器的一种方法。最后,为了加快处理速度,您可以询问一个略微不同的问题,而不是找到一个脸。也就是说,您可以尝试快速排除图像中不能成为脸的区域。这被称为级联分类。系统地研究这些方面,您将比从代码粘贴中学到更多关于人脸检测的知识。

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文档

Harr训练及用途演示


3
哦,请不要将新手引导到已经过时的C-API,他们已经几年前转向C++了,现在没有人应该再写这样的代码了。 - berak
@berak:首先,如果你有更好的答案,请直接发布。其次,这只是为了让事情变得简单。有人在这里问如何检测人脸,这是最简单的答案之一,因为我仍然相信你应该从一个“Hello World”程序开始,而不是说“如何创建操作系统”。 - Shiva
@Shiva非常感谢您的回答。我已为您点赞。但是我想知道是否有任何无监督算法可以解决这个问题?请注意,我不需要识别图像A是爱丽丝,B是鲍勃,我只想确保A和B都是人脸。谢谢。 - ChuNan
@ChuNan:有很多(大多数是研究用途),但我没有使用过任何一个,就人脸检测而言,Harr级联也只是捕捉人脸(假设它是用于人脸的Harr级联),并不能识别它们。你还可以在opencv自带的通用Harr文件中找到适合你目的的文件。 - Shiva
@ChuNan:如果你想将A识别为Alice,B识别为Bob或其他特定人物,则需要训练自己的Harr文件。否则,对于大多数情况,标准文件就足够了。 - Shiva

1
这是我的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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接