int faceDetect_GPU(Mat &image, vector<Mat> &faces, int init) { static CascadeClassifier_GPU cascade_gpu; static HANDLE init_mutex; if(init == 1) { init_mutex = CreateMutex(NULL, FALSE, NULL); cascade_gpu.load(string(CASCADE_PATH)); return 0; } Mat gray; cvtColor(image, gray, CV_BGR2GRAY); equalizeHist(gray, gray); GpuMat image_gpu(gray); GpuMat objbuf; WaitForSingleObject(init_mutex, INFINITE); double start = GetTickCount(); int detections_number = cascade_gpu.detectMultiScale(image_gpu, objbuf, 1.1, 3); cout << "Face Detect GPU Time : " << GetTickCount()-start << "ms" << endl; ReleaseMutex(init_mutex); Mat obj_host; objbuf.colRange(0, detections_number).download(obj_host); Rect* det_faces = obj_host.ptr<Rect>(); for(int i = 0; i < detections_number; ++i) { Mat face = gray(det_faces[i]); faces.push_back(face); } return 0; }
void App::run(int argc, char **argv) { parseCmdArgs(argc, argv); if (help_showed) return; if (getCudaEnabledDeviceCount() == 0) throw runtime_error("No GPU found or the library is compiled without GPU support"); if (cascade_name.empty()) { cout << "Using default cascade file...\n"; cascade_name = "data/face_detect/haarcascade_frontalface_alt.xml"; } if (!cascade_gpu.load(cascade_name) || !cascade_cpu.load(cascade_name)) { stringstream msg; msg << "Could not load cascade classifier \"" << cascade_name << "\""; throw runtime_error(msg.str()); } if (sources.size() != 1) { cout << "Loading default frames source...\n"; sources.resize(1); sources[0] = new VideoSource("data/face_detect/browser.flv"); } Mat frame, frame_cpu, gray_cpu, resized_cpu, faces_downloaded, frameDisp; vector<Rect> facesBuf_cpu; GpuMat frame_gpu, gray_gpu, resized_gpu, facesBuf_gpu; int detections_num; while (!exited) { sources[0]->next(frame_cpu); frame_gpu.upload(frame_cpu); convertAndResize(frame_gpu, gray_gpu, resized_gpu, scaleFactor); convertAndResize(frame_cpu, gray_cpu, resized_cpu, scaleFactor); TickMeter tm; tm.start(); if (useGPU) { cascade_gpu.visualizeInPlace = true; cascade_gpu.findLargestObject = findLargestObject; detections_num = cascade_gpu.detectMultiScale(resized_gpu, facesBuf_gpu, 1.2, (filterRects || findLargestObject) ? 4 : 0); facesBuf_gpu.colRange(0, detections_num).download(faces_downloaded); } else { Size minSize = cascade_gpu.getClassifierSize(); cascade_cpu.detectMultiScale(resized_cpu, facesBuf_cpu, 1.2, (filterRects || findLargestObject) ? 4 : 0, (findLargestObject ? CV_HAAR_FIND_BIGGEST_OBJECT : 0) | CV_HAAR_SCALE_IMAGE, minSize); detections_num = (int)facesBuf_cpu.size(); } if (!useGPU && detections_num) { for (int i = 0; i < detections_num; ++i) { rectangle(resized_cpu, facesBuf_cpu[i], Scalar(255)); } } if (useGPU) { resized_gpu.download(resized_cpu); } tm.stop(); double detectionTime = tm.getTimeMilli(); double fps = 1000 / detectionTime; /*//print detections to console cout << setfill(' ') << setprecision(2); cout << setw(6) << fixed << fps << " FPS, " << detections_num << " det"; if ((filterRects || findLargestObject) && detections_num > 0) { Rect *faceRects = useGPU ? faces_downloaded.ptr<Rect>() : &facesBuf_cpu[0]; for (int i = 0; i < min(detections_num, 2); ++i) { cout << ", [" << setw(4) << faceRects[i].x << ", " << setw(4) << faceRects[i].y << ", " << setw(4) << faceRects[i].width << ", " << setw(4) << faceRects[i].height << "]"; } } cout << endl;*/ cvtColor(resized_cpu, frameDisp, CV_GRAY2BGR); displayState(frameDisp, helpScreen, useGPU, findLargestObject, filterRects, fps); imshow("face_detect_demo", frameDisp); processKey(waitKey(3)); } }
py::list face_detection(const cv::Mat& in,const bool useGPU=true,const bool filterRects=true,const bool findLargestObject=false,const double scaleFactor=1.0) { /* if (getCudaEnabledDeviceCount() == 0){ cerr << "No GPU found or the library is compiled without GPU support" << endl; } cv::gpu::printShortCudaDeviceInfo(cv::gpu::getDevice()); */ /* CascadeClassifier cascade_cpu; if (!cascade_cpu.load(cascadeName)){ cerr << "ERROR: Could not load cascade classifier "" << cascadeName << """ << endl; } */ Mat frame, frame_cpu, gray_cpu, resized_cpu, faces_downloaded, frameDisp; //vector<Rect> facesBuf_cpu; GpuMat frame_gpu, gray_gpu, resized_gpu, facesBuf_gpu; //vector<Rect> face_rects ; //in.copyTo(frame_cpu); frame_gpu.upload(in); //convertAndResize(frame_gpu, gray_gpu, resized_gpu, scaleFactor); convertAndResize(frame_gpu, gray_gpu, resized_gpu, scaleFactor); //TickMeter tm; //tm.start(); if (useGPU){ //cascade_gpu.visualizeInPlace = true; cascade_gpu.findLargestObject = findLargestObject; detections_num = cascade_gpu.detectMultiScale(resized_gpu, facesBuf_gpu, 1.2, (filterRects || findLargestObject) ? 4 : 0); facesBuf_gpu.colRange(0, detections_num).download(faces_downloaded); } /* else { Size minSize = cascade_gpu.getClassifierSize(); cascade_cpu.detectMultiScale(resized_cpu, facesBuf_cpu, 1.2, (filterRects || findLargestObject) ? 4 : 0, (findLargestObject ? CV_HAAR_FIND_BIGGEST_OBJECT : 0) | CV_HAAR_SCALE_IMAGE, minSize); detections_num = (int)facesBuf_cpu.size(); } */ /* tm.stop(); double detectionTime = tm.getTimeMilli(); double fps = 1000 / detectionTime; //print detections to console cout << setfill(' ') << setprecision(2); cout << setw(6) << fixed << fps << " FPS, " << detections_num << " det"; */ py::list facereturn; //Rect *faces = useGPU ? faces_downloaded.ptr<Rect>() : &facesBuf_cpu[0]; Rect* faces = faces_downloaded.ptr<cv::Rect>(); for (int i = 0; i < detections_num; ++i) { py::list points; points.append(faces[i].x); points.append(faces[i].y); points.append(faces[i].width); points.append(faces[i].height); facereturn.append(points); //face_rects.push_back(faces[i]); } //std::cerr << "detections_num: " << detections_num << std::endl; //std::cerr << "sz: " << in.size() << std::endl; return facereturn; }
void App::process() { if (cascade_name.empty()) { cout << "Using default cascade file...\n"; cascade_name = "data/face_detect/haarcascade_frontalface_alt.xml"; } if (!cascade_gpu.load(cascade_name) || !cascade_cpu.load(cascade_name)) { ostringstream msg; msg << "Could not load cascade classifier \"" << cascade_name << "\""; throw runtime_error(msg.str()); } if (sources.size() != 1) { cout << "Loading default frames source...\n"; sources.resize(1); sources[0] = new VideoSource("data/face_detect/browser.flv"); } cout << "\nControls:\n" << "\tESC - exit\n" << "\tSpace - change mode GPU <-> CPU\n" << "\t1/Q - increase/decrease scale\n" << "\tM - switch OneFace / MultiFace\n" << "\tF - toggle rectangles filter\n" << endl; Mat frame, frame_cpu, gray_cpu, resized_cpu, img_to_show; GpuMat frame_gpu, gray_gpu, resized_gpu, facesBuf_gpu; vector<Rect> faces; while (!exited) { int64 start = getTickCount(); sources[0]->next(frame_cpu); double proc_fps; if (useGPU) { frame_gpu.upload(frame_cpu); resizeAndConvert(frame_gpu, resized_gpu, gray_gpu, scaleFactor); cascade_gpu.visualizeInPlace = false; cascade_gpu.findLargestObject = findLargestObject; int64 proc_start = getTickCount(); int detections_num = cascade_gpu.detectMultiScale(gray_gpu, facesBuf_gpu, 1.2, (filterRects || findLargestObject) ? 4 : 0); if (detections_num == 0) faces.clear(); else { faces.resize(detections_num); cv::Mat facesMat(1, detections_num, DataType<Rect>::type, &faces[0]); facesBuf_gpu.colRange(0, detections_num).download(facesMat); } proc_fps = getTickFrequency() / (getTickCount() - proc_start); } else { resizeAndConvert(frame_cpu, resized_cpu, gray_cpu, scaleFactor); Size minSize = cascade_gpu.getClassifierSize(); int64 proc_start = getTickCount(); cascade_cpu.detectMultiScale(gray_cpu, faces, 1.2, (filterRects || findLargestObject) ? 4 : 0, (findLargestObject ? CV_HAAR_FIND_BIGGEST_OBJECT : 0) | CV_HAAR_SCALE_IMAGE, minSize); proc_fps = getTickFrequency() / (getTickCount() - proc_start); } if (useGPU) resized_gpu.download(img_to_show); else img_to_show = resized_cpu; for (size_t i = 0; i < faces.size(); i++) rectangle(img_to_show, faces[i], CV_RGB(0, 255, 0), 3); double total_fps = getTickFrequency() / (getTickCount() - start); displayState(img_to_show, proc_fps, total_fps); imshow("face_detect_demo", img_to_show); processKey(waitKey(3) & 0xff); } }