日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 人工智能 > pytorch >内容正文

pytorch

使用OpenCV进行人脸检测(Viola-Jones人脸检测方法)

發(fā)布時(shí)間:2025/7/25 pytorch 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 使用OpenCV进行人脸检测(Viola-Jones人脸检测方法) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

擴(kuò)展閱讀: 

OpenCV用于人臉檢測(cè)


參考文獻(xiàn):Paul Viola, Michael J. Jones. Robust Real-Time Face Detection[J]. International Journal of Computer Vision,2004,57(2):137-154.

優(yōu)點(diǎn):

1.積分圖像(integral image)快速計(jì)算Haar-like特征。

2.利用Adaboost算法進(jìn)行特征選擇和分類器訓(xùn)練,把弱分類器組合成強(qiáng)分類器。

3.采用分類器級(jí)聯(lián)提高效率。


檢測(cè)步驟:

Step1 加載分類器

  讀入xml格式的模型文件,其中haarcascade_frontalface_atl.xml和haarcascade_frontalface_atl2.xml效果較好。文件在OpenCV安裝目錄下的“data/haarcascades/”路徑下。

Step2 讀入待檢測(cè)圖像(或者視頻解碼后的圖像)

Step3 調(diào)用用函數(shù)檢測(cè)人臉。

代碼1:

#include "opencv2/core/core.hpp" #include "opencv2/objdetect/objdetect.hpp" #include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #include <iostream> #include <stdio.h> using namespace std; using namespace cv; string face_cascade_name = "haarcascade_frontalface_alt.xml"; //該文件存在于OpenCV安裝目錄下的\sources\data\haarcascades內(nèi),需要將該xml文件復(fù)制到當(dāng)前工程目錄下 CascadeClassifier face_cascade; void detectAndDisplay( Mat frame ); int main( int argc, char** argv ){ Mat image; image =imread("face.jpg",1); //當(dāng)前工程的image目錄下的mm.jpg文件,注意目錄符號(hào)if( !face_cascade.load( face_cascade_name ) ){ printf("級(jí)聯(lián)分類器錯(cuò)誤,可能未找到文件,拷貝該文件到工程目錄下!\n"); return -1; } detectAndDisplay(image); //調(diào)用人臉檢測(cè)函數(shù)waitKey(0); //暫停顯示一下。 } void detectAndDisplay( Mat face ){ std::vector<Rect> faces; Mat face_gray; cvtColor( face, face_gray, CV_BGR2GRAY ); //rgb類型轉(zhuǎn)換為灰度類型equalizeHist( face_gray, face_gray ); //直方圖均衡化face_cascade.detectMultiScale( face_gray, faces, 1.1, 2, 0|CV_HAAR_SCALE_IMAGE, Size(1, 1) ); for( int i = 0; i < faces.size(); i++ ){ Point center( faces[i].x + faces[i].width*0.5, faces[i].y + faces[i].height*0.5 ); ellipse( face, center, Size( faces[i].width*0.5, faces[i].height*0.5), 0, 0, 360, Scalar( 255, 0, 0), 2,7, 0 ); } imshow("人臉識(shí)別", face ); }

代碼1效果:


代碼2:

#include "cv.h" #include "highgui.h"#include <stdio.h> #include <stdlib.h> #include <string.h> #include <assert.h> #include <math.h> #include <float.h> #include <limits.h> #include <time.h> #include <ctype.h>static CvMemStorage* storage = 0; static CvHaarClassifierCascade* cascade = 0;void detect_and_draw( IplImage* image );const char* cascade_name = "haarcascade_frontalface_alt.xml"; /* "haarcascade_profileface.xml";*/int main( int argc, char** argv ) { cascade_name = "haarcascade_frontalface_alt2.xml"; cascade = (CvHaarClassifierCascade*)cvLoad( cascade_name, 0, 0, 0 ); if( !cascade ) { fprintf( stderr, "ERROR: Could not load classifier cascade\n" ); return -1; } storage = cvCreateMemStorage(0); cvNamedWindow( "result", 1 ); const char* filename = "face.jpg"; IplImage* image = cvLoadImage( filename, 1 );if( image ) { detect_and_draw( image ); cvWaitKey(0); cvReleaseImage( &image ); }cvDestroyWindow("result"); return 0; }void detect_and_draw(IplImage* img ) { double scale=1.2; 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}} };//Just some pretty colors to draw with//Image Preparation // IplImage* gray = cvCreateImage(cvSize(img->width,img->height),8,1); IplImage* small_img=cvCreateImage(cvSize(cvRound(img->width/scale),cvRound(img->height/scale)),8,1); cvCvtColor(img,gray, CV_BGR2GRAY); cvResize(gray, small_img, CV_INTER_LINEAR);cvEqualizeHist(small_img,small_img); //直方圖均衡//Detect objects if any // cvClearMemStorage(storage); double t = (double)cvGetTickCount(); CvSeq* objects = cvHaarDetectObjects(small_img, cascade, storage, 1.1, 2, 0/*CV_HAAR_DO_CANNY_PRUNING*/, cvSize(30,30));t = (double)cvGetTickCount() - t; printf( "detection time = %gms\n", t/((double)cvGetTickFrequency()*1000.) );//Loop through found objects and draw boxes around them for(int i=0;i<(objects? objects->total:0);++i) { CvRect* r=(CvRect*)cvGetSeqElem(objects,i); cvRectangle(img, cvPoint(r->x*scale,r->y*scale), cvPoint((r->x+r->width)*scale,(r->y+r->height)*scale), colors[i%8]); } for( int i = 0; i < (objects? objects->total : 0); i++ ) { CvRect* r = (CvRect*)cvGetSeqElem( objects, i ); CvPoint center; int radius; center.x = cvRound((r->x + r->width*0.5)*scale); center.y = cvRound((r->y + r->height*0.5)*scale); radius = cvRound((r->width + r->height)*0.25*scale); cvCircle( img, center, radius, colors[i%8], 3, 8, 0 ); }cvShowImage( "result", img ); cvReleaseImage(&gray); cvReleaseImage(&small_img); }


代碼2效果

?


從效果看,代碼1的效果較好。原因使用的函數(shù)不同,內(nèi)部的實(shí)現(xiàn)和參數(shù)也有區(qū)別。請(qǐng)根據(jù)實(shí)際情況子集選擇。


代碼3,OpenCV? 原版附帶眼睛檢測(cè)

#include "opencv2/objdetect/objdetect.hpp" #include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp"#include <cctype> #include <iostream> #include <iterator> #include <stdio.h>using namespace std; using namespace cv;static void help() {cout << "\nThis program demonstrates the cascade recognizer. Now you can use Haar or LBP features.\n""This classifier can recognize many kinds of rigid objects, once the appropriate classifier is trained.\n""It's most known use is for faces.\n""Usage:\n""./facedetect [--cascade=<cascade_path> this is the primary trained classifier such as frontal face]\n"" [--nested-cascade[=nested_cascade_path this an optional secondary classifier such as eyes]]\n"" [--scale=<image scale greater or equal to 1, try 1.3 for example>]\n"" [--try-flip]\n"" [filename|camera_index]\n\n""see facedetect.cmd for one call:\n""./facedetect --cascade=\"../../data/haarcascades/haarcascade_frontalface_alt.xml\" --nested-cascade=\"../../data/haarcascades/haarcascade_eye.xml\" --scale=1.3\n\n""During execution:\n\tHit any key to quit.\n""\tUsing OpenCV version " << CV_VERSION << "\n" << endl; }void detectAndDraw( Mat& img, CascadeClassifier& cascade,CascadeClassifier& nestedCascade,double scale, bool tryflip );string cascadeName = "../../data/haarcascades/haarcascade_frontalface_alt.xml"; string nestedCascadeName = "../../data/haarcascades/haarcascade_eye_tree_eyeglasses.xml";int main( int argc, const char** argv ) {CvCapture* capture = 0;Mat frame, frameCopy, image;const string scaleOpt = "--scale=";size_t scaleOptLen = scaleOpt.length();const string cascadeOpt = "--cascade=";size_t cascadeOptLen = cascadeOpt.length();const string nestedCascadeOpt = "--nested-cascade";size_t nestedCascadeOptLen = nestedCascadeOpt.length();const string tryFlipOpt = "--try-flip";size_t tryFlipOptLen = tryFlipOpt.length();string inputName;bool tryflip = false;help();CascadeClassifier cascade, nestedCascade;double scale = 1;for( int i = 1; i < argc; i++ ){cout << "Processing " << i << " " << argv[i] << endl;if( cascadeOpt.compare( 0, cascadeOptLen, argv[i], cascadeOptLen ) == 0 ){cascadeName.assign( argv[i] + cascadeOptLen );cout << " from which we have cascadeName= " << cascadeName << endl;}else if( nestedCascadeOpt.compare( 0, nestedCascadeOptLen, argv[i], nestedCascadeOptLen ) == 0 ){if( argv[i][nestedCascadeOpt.length()] == '=' )nestedCascadeName.assign( argv[i] + nestedCascadeOpt.length() + 1 );if( !nestedCascade.load( nestedCascadeName ) )cerr << "WARNING: Could not load classifier cascade for nested objects" << endl;}else if( scaleOpt.compare( 0, scaleOptLen, argv[i], scaleOptLen ) == 0 ){if( !sscanf( argv[i] + scaleOpt.length(), "%lf", &scale ) || scale < 1 )scale = 1;cout << " from which we read scale = " << scale << endl;}else if( tryFlipOpt.compare( 0, tryFlipOptLen, argv[i], tryFlipOptLen ) == 0 ){tryflip = true;cout << " will try to flip image horizontally to detect assymetric objects\n";}else if( argv[i][0] == '-' ){cerr << "WARNING: Unknown option %s" << argv[i] << endl;}elseinputName.assign( argv[i] );}if( !cascade.load( cascadeName ) ){cerr << "ERROR: Could not load classifier cascade" << endl;help();return -1;}if( inputName.empty() || (isdigit(inputName.c_str()[0]) && inputName.c_str()[1] == '\0') ){capture = cvCaptureFromCAM( inputName.empty() ? 0 : inputName.c_str()[0] - '0' );int c = inputName.empty() ? 0 : inputName.c_str()[0] - '0' ;if(!capture) cout << "Capture from CAM " << c << " didn't work" << endl;}else if( inputName.size() ){image = imread( inputName, 1 );if( image.empty() ){capture = cvCaptureFromAVI( inputName.c_str() );if(!capture) cout << "Capture from AVI didn't work" << endl;}}else{image = imread( "lena.jpg", 1 );if(image.empty()) cout << "Couldn't read lena.jpg" << endl;}cvNamedWindow( "result", 1 );if( capture ){cout << "In capture ..." << endl;for(;;){IplImage* iplImg = cvQueryFrame( capture );frame = iplImg;if( frame.empty() )break;if( iplImg->origin == IPL_ORIGIN_TL )frame.copyTo( frameCopy );elseflip( frame, frameCopy, 0 );detectAndDraw( frameCopy, cascade, nestedCascade, scale, tryflip );if( waitKey( 10 ) >= 0 )goto _cleanup_;}waitKey(0);_cleanup_:cvReleaseCapture( &capture );}else{cout << "In image read" << endl;if( !image.empty() ){detectAndDraw( image, cascade, nestedCascade, scale, tryflip );waitKey(0);}else if( !inputName.empty() ){/* assume it is a text file containing thelist of the image filenames to be processed - one per line */FILE* f = fopen( inputName.c_str(), "rt" );if( f ){char buf[1000+1];while( fgets( buf, 1000, f ) ){int len = (int)strlen(buf), c;while( len > 0 && isspace(buf[len-1]) )len--;buf[len] = '\0';cout << "file " << buf << endl;image = imread( buf, 1 );if( !image.empty() ){detectAndDraw( image, cascade, nestedCascade, scale, tryflip );c = waitKey(0);if( c == 27 || c == 'q' || c == 'Q' )break;}else{cerr << "Aw snap, couldn't read image " << buf << endl;}}fclose(f);}}}cvDestroyWindow("result");return 0; }void detectAndDraw( Mat& img, CascadeClassifier& cascade,CascadeClassifier& nestedCascade,double scale, bool tryflip ) {int i = 0;double t = 0;vector<Rect> faces, faces2;const static Scalar colors[] = { CV_RGB(0,0,255),CV_RGB(0,128,255),CV_RGB(0,255,255),CV_RGB(0,255,0),CV_RGB(255,128,0),CV_RGB(255,255,0),CV_RGB(255,0,0),CV_RGB(255,0,255)} ;Mat gray, smallImg( cvRound (img.rows/scale), cvRound(img.cols/scale), CV_8UC1 );cvtColor( img, gray, CV_BGR2GRAY );resize( gray, smallImg, smallImg.size(), 0, 0, INTER_LINEAR );equalizeHist( smallImg, smallImg );t = (double)cvGetTickCount();cascade.detectMultiScale( smallImg, faces,1.1, 2, 0//|CV_HAAR_FIND_BIGGEST_OBJECT//|CV_HAAR_DO_ROUGH_SEARCH|CV_HAAR_SCALE_IMAGE,Size(30, 30) );if( tryflip ){flip(smallImg, smallImg, 1);cascade.detectMultiScale( smallImg, faces2,1.1, 2, 0//|CV_HAAR_FIND_BIGGEST_OBJECT//|CV_HAAR_DO_ROUGH_SEARCH|CV_HAAR_SCALE_IMAGE,Size(30, 30) );for( vector<Rect>::const_iterator r = faces2.begin(); r != faces2.end(); r++ ){faces.push_back(Rect(smallImg.cols - r->x - r->width, r->y, r->width, r->height));}}t = (double)cvGetTickCount() - t;printf( "detection time = %g ms\n", t/((double)cvGetTickFrequency()*1000.) );for( vector<Rect>::const_iterator r = faces.begin(); r != faces.end(); r++, i++ ){Mat smallImgROI;vector<Rect> nestedObjects;Point center;Scalar color = colors[i%8];int radius;double aspect_ratio = (double)r->width/r->height;if( 0.75 < aspect_ratio && aspect_ratio < 1.3 ){center.x = cvRound((r->x + r->width*0.5)*scale);center.y = cvRound((r->y + r->height*0.5)*scale);radius = cvRound((r->width + r->height)*0.25*scale);circle( img, center, radius, color, 3, 8, 0 );}elserectangle( img, cvPoint(cvRound(r->x*scale), cvRound(r->y*scale)),cvPoint(cvRound((r->x + r->width-1)*scale), cvRound((r->y + r->height-1)*scale)),color, 3, 8, 0);if( nestedCascade.empty() )continue;smallImgROI = smallImg(*r);nestedCascade.detectMultiScale( smallImgROI, nestedObjects,1.1, 2, 0//|CV_HAAR_FIND_BIGGEST_OBJECT//|CV_HAAR_DO_ROUGH_SEARCH//|CV_HAAR_DO_CANNY_PRUNING|CV_HAAR_SCALE_IMAGE,Size(30, 30) );for( vector<Rect>::const_iterator nr = nestedObjects.begin(); nr != nestedObjects.end(); nr++ ){center.x = cvRound((r->x + nr->x + nr->width*0.5)*scale);center.y = cvRound((r->y + nr->y + nr->height*0.5)*scale);radius = cvRound((nr->width + nr->height)*0.25*scale);circle( img, center, radius, color, 3, 8, 0 );}}cv::imshow( "result", img );cv::waitKey(0); }



《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀

總結(jié)

以上是生活随笔為你收集整理的使用OpenCV进行人脸检测(Viola-Jones人脸检测方法)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。