123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316 |
- // WARNING: this sample is under construction! Use it on your own risk.
- #if defined _MSC_VER && _MSC_VER >= 1400
- #pragma warning(disable : 4100)
- #endif
- #include <iostream>
- #include <iomanip>
- #include "opencv2/objdetect.hpp"
- #include "opencv2/highgui.hpp"
- #include "opencv2/imgproc.hpp"
- #include "opencv2/cudaobjdetect.hpp"
- #include "opencv2/cudaimgproc.hpp"
- #include "opencv2/cudawarping.hpp"
- using namespace std;
- using namespace cv;
- using namespace cv::cuda;
- static void help()
- {
- cout << "Usage: ./cascadeclassifier \n\t--cascade <cascade_file>\n\t(<image>|--video <video>|--camera <camera_id>)\n"
- "Using OpenCV version " << CV_VERSION << endl << endl;
- }
- static void convertAndResize(const Mat& src, Mat& gray, Mat& resized, double scale)
- {
- if (src.channels() == 3)
- {
- cv::cvtColor( src, gray, COLOR_BGR2GRAY );
- }
- else
- {
- gray = src;
- }
- Size sz(cvRound(gray.cols * scale), cvRound(gray.rows * scale));
- if (scale != 1)
- {
- cv::resize(gray, resized, sz);
- }
- else
- {
- resized = gray;
- }
- }
- static void convertAndResize(const GpuMat& src, GpuMat& gray, GpuMat& resized, double scale)
- {
- if (src.channels() == 3)
- {
- cv::cuda::cvtColor( src, gray, COLOR_BGR2GRAY );
- }
- else
- {
- gray = src;
- }
- Size sz(cvRound(gray.cols * scale), cvRound(gray.rows * scale));
- if (scale != 1)
- {
- cv::cuda::resize(gray, resized, sz);
- }
- else
- {
- resized = gray;
- }
- }
- static void matPrint(Mat &img, int lineOffsY, Scalar fontColor, const string &ss)
- {
- int fontFace = FONT_HERSHEY_DUPLEX;
- double fontScale = 0.8;
- int fontThickness = 2;
- Size fontSize = cv::getTextSize("T[]", fontFace, fontScale, fontThickness, 0);
- Point org;
- org.x = 1;
- org.y = 3 * fontSize.height * (lineOffsY + 1) / 2;
- putText(img, ss, org, fontFace, fontScale, Scalar(0,0,0), 5*fontThickness/2, 16);
- putText(img, ss, org, fontFace, fontScale, fontColor, fontThickness, 16);
- }
- static void displayState(Mat &canvas, bool bHelp, bool bGpu, bool bLargestFace, bool bFilter, double fps)
- {
- Scalar fontColorRed = Scalar(255,0,0);
- Scalar fontColorNV = Scalar(118,185,0);
- ostringstream ss;
- ss << "FPS = " << setprecision(1) << fixed << fps;
- matPrint(canvas, 0, fontColorRed, ss.str());
- ss.str("");
- ss << "[" << canvas.cols << "x" << canvas.rows << "], " <<
- (bGpu ? "GPU, " : "CPU, ") <<
- (bLargestFace ? "OneFace, " : "MultiFace, ") <<
- (bFilter ? "Filter:ON" : "Filter:OFF");
- matPrint(canvas, 1, fontColorRed, ss.str());
- // by Anatoly. MacOS fix. ostringstream(const string&) is a private
- // matPrint(canvas, 2, fontColorNV, ostringstream("Space - switch GPU / CPU"));
- if (bHelp)
- {
- matPrint(canvas, 2, fontColorNV, "Space - switch GPU / CPU");
- matPrint(canvas, 3, fontColorNV, "M - switch OneFace / MultiFace");
- matPrint(canvas, 4, fontColorNV, "F - toggle rectangles Filter");
- matPrint(canvas, 5, fontColorNV, "H - toggle hotkeys help");
- matPrint(canvas, 6, fontColorNV, "1/Q - increase/decrease scale");
- }
- else
- {
- matPrint(canvas, 2, fontColorNV, "H - toggle hotkeys help");
- }
- }
- int main(int argc, const char *argv[])
- {
- if (argc == 1)
- {
- help();
- return -1;
- }
- if (getCudaEnabledDeviceCount() == 0)
- {
- return cerr << "No GPU found or the library is compiled without CUDA support" << endl, -1;
- }
- cv::cuda::printShortCudaDeviceInfo(cv::cuda::getDevice());
- string cascadeName;
- string inputName;
- bool isInputImage = false;
- bool isInputVideo = false;
- bool isInputCamera = false;
- for (int i = 1; i < argc; ++i)
- {
- if (string(argv[i]) == "--cascade")
- cascadeName = argv[++i];
- else if (string(argv[i]) == "--video")
- {
- inputName = argv[++i];
- isInputVideo = true;
- }
- else if (string(argv[i]) == "--camera")
- {
- inputName = argv[++i];
- isInputCamera = true;
- }
- else if (string(argv[i]) == "--help")
- {
- help();
- return -1;
- }
- else if (!isInputImage)
- {
- inputName = argv[i];
- isInputImage = true;
- }
- else
- {
- cout << "Unknown key: " << argv[i] << endl;
- return -1;
- }
- }
- Ptr<cuda::CascadeClassifier> cascade_gpu = cuda::CascadeClassifier::create(cascadeName);
- cv::CascadeClassifier cascade_cpu;
- if (!cascade_cpu.load(cascadeName))
- {
- return cerr << "ERROR: Could not load cascade classifier \"" << cascadeName << "\"" << endl, help(), -1;
- }
- VideoCapture capture;
- Mat image;
- if (isInputImage)
- {
- image = imread(inputName);
- CV_Assert(!image.empty());
- }
- else if (isInputVideo)
- {
- capture.open(inputName);
- CV_Assert(capture.isOpened());
- }
- else
- {
- capture.open(atoi(inputName.c_str()));
- CV_Assert(capture.isOpened());
- }
- namedWindow("result", 1);
- Mat frame, frame_cpu, gray_cpu, resized_cpu, frameDisp;
- vector<Rect> faces;
- GpuMat frame_gpu, gray_gpu, resized_gpu, facesBuf_gpu;
- /* parameters */
- bool useGPU = true;
- double scaleFactor = 1.0;
- bool findLargestObject = false;
- bool filterRects = true;
- bool helpScreen = false;
- for (;;)
- {
- if (isInputCamera || isInputVideo)
- {
- capture >> frame;
- if (frame.empty())
- {
- break;
- }
- }
- (image.empty() ? frame : image).copyTo(frame_cpu);
- frame_gpu.upload(image.empty() ? frame : image);
- convertAndResize(frame_gpu, gray_gpu, resized_gpu, scaleFactor);
- convertAndResize(frame_cpu, gray_cpu, resized_cpu, scaleFactor);
- TickMeter tm;
- tm.start();
- if (useGPU)
- {
- cascade_gpu->setFindLargestObject(findLargestObject);
- cascade_gpu->setScaleFactor(1.2);
- cascade_gpu->setMinNeighbors((filterRects || findLargestObject) ? 4 : 0);
- cascade_gpu->detectMultiScale(resized_gpu, facesBuf_gpu);
- cascade_gpu->convert(facesBuf_gpu, faces);
- }
- else
- {
- Size minSize = cascade_gpu->getClassifierSize();
- cascade_cpu.detectMultiScale(resized_cpu, faces, 1.2,
- (filterRects || findLargestObject) ? 4 : 0,
- (findLargestObject ? CASCADE_FIND_BIGGEST_OBJECT : 0)
- | CASCADE_SCALE_IMAGE,
- minSize);
- }
- for (size_t i = 0; i < faces.size(); ++i)
- {
- rectangle(resized_cpu, faces[i], Scalar(255));
- }
- tm.stop();
- double detectionTime = tm.getTimeMilli();
- double fps = 1000 / detectionTime;
- //print detections to console
- cout << setfill(' ') << setprecision(2);
- cout << setw(6) << fixed << fps << " FPS, " << faces.size() << " det";
- if ((filterRects || findLargestObject) && !faces.empty())
- {
- for (size_t i = 0; i < faces.size(); ++i)
- {
- cout << ", [" << setw(4) << faces[i].x
- << ", " << setw(4) << faces[i].y
- << ", " << setw(4) << faces[i].width
- << ", " << setw(4) << faces[i].height << "]";
- }
- }
- cout << endl;
- cv::cvtColor(resized_cpu, frameDisp, COLOR_GRAY2BGR);
- displayState(frameDisp, helpScreen, useGPU, findLargestObject, filterRects, fps);
- imshow("result", frameDisp);
- char key = (char)waitKey(5);
- if (key == 27)
- {
- break;
- }
- switch (key)
- {
- case ' ':
- useGPU = !useGPU;
- break;
- case 'm':
- case 'M':
- findLargestObject = !findLargestObject;
- break;
- case 'f':
- case 'F':
- filterRects = !filterRects;
- break;
- case '1':
- scaleFactor *= 1.05;
- break;
- case 'q':
- case 'Q':
- scaleFactor /= 1.05;
- break;
- case 'h':
- case 'H':
- helpScreen = !helpScreen;
- break;
- }
- }
- return 0;
- }
|