基於c++的OpenCV目標檢測
阿新 • • 發佈:2018-12-21
宣告:本文的原始碼全部來OpenCV的官方文件,筆者只是做一個學習筆記
以下程式碼主要實現通過攝像頭完成人臉、眼睛、身體檢測
#include "opencv2/objdetect.hpp" #include "opencv2/highgui.hpp" #include "opencv2/imgproc.hpp" #include <iostream> using namespace std; using namespace cv; void detectAndDisplay(Mat frame); CascadeClassifier face_cascade; //使用級聯分類器類載入視訊中物件 //face CascadeClassifier eyes_cascade; //eyes CascadeClassifier upperbody_cascade; //body int main(int argc, const char** argv) { CommandLineParser parser(argc, argv, "{help h||}" "{face_cascade|D:/opencv/sources/data/haarcascades/haarcascade_frontalface_alt.xml|Path to face cascade.}" "{eyes_cascade|D:/opencv/sources/data/haarcascades/haarcascade_eye_tree_eyeglasses.xml|Path to eyes cascade.}" "{upperbody_cascade|D:/opencv/sources/data/haarcascades/haarcascade_upperbody.xml|Path to upperbody cascade.}" "{camera|0|Camera device number.}"); //路徑自己改,在你安裝OpenCV目錄尋找 parser.about("\nThis program demonstrates using the cv::CascadeClassifier class to detect objects (Face + eyes) in a video stream.\n" "You can use Haar or LBP features.\n\n"); parser.printMessage(); String face_cascade_name = parser.get<String>("face_cascade"); String eyes_cascade_name = parser.get<String>("eyes_cascade"); String upperbody_cascade_name = parser.get<String>("upperbody_cascade"); //-- 1. Load the cascades if (!face_cascade.load(face_cascade_name)) { cout << "--(!)Error loading face cascade\n"; return -1; }; if (!eyes_cascade.load(eyes_cascade_name)) { cout << "--(!)Error loading eyes cascade\n"; return -1; }; if (!upperbody_cascade.load(upperbody_cascade_name)) { cout << "--(!)Error loading upperbody cascade\n"; return -1; }; int camera_device = parser.get<int>("camera"); VideoCapture capture; //-- 2. Read the video stream capture.open(camera_device); if (!capture.isOpened()) { cout << "--(!)Error opening video capture\n"; return -1; } Mat frame; while (capture.read(frame)) { if (frame.empty()) { cout << "--(!) No captured frame -- Break!\n"; break; } //-- 3. Apply the classifier to the frame detectAndDisplay(frame); if (waitKey(10) == 27) { break; // escape } } return 0; } void detectAndDisplay(Mat frame) { Mat frame_gray; cvtColor(frame, frame_gray, COLOR_BGR2GRAY); //轉灰度圖 equalizeHist(frame_gray, frame_gray); //直方圖等化:增強影象的對比度 //-- Detect faces std::vector<Rect> faces; face_cascade.detectMultiScale(frame_gray, faces); //在影象中檢測不同大小的物件,並將檢測到的物件以矩形列表返回,這裡檢測的是人臉 //這個返回值是放在faces裡面的,detectMultiScale這個函式是void for (size_t i = 0; i < faces.size(); i++) { Point center(faces[i].x + faces[i].width / 2,\ faces[i].y + faces[i].height / 2); //計算到面部的中心點 ellipse(frame, center, Size(faces[i].width / 2,\ faces[i].height / 2), 0, 0, 360, Scalar(255, 0, 255), 4); //繪製圓 Mat faceROI = frame_gray(faces[i]); //先確定臉,再去找眼睛 //-- In each face, detect eyes std::vector<Rect> eyes; eyes_cascade.detectMultiScale(faceROI, eyes); for (size_t j = 0; j < eyes.size(); j++) { Point eye_center(faces[i].x + eyes[j].x + eyes[j].width / 2,\ faces[i].y + eyes[j].y + eyes[j].height / 2); int radius = cvRound((eyes[j].width + eyes[j].height)*0.25); circle(frame, eye_center, radius, Scalar(255, 0, 0), 4); } } std::vector<Rect> upperbody; upperbody_cascade.detectMultiScale(frame_gray, upperbody); for (size_t i = 0; i < upperbody.size(); i++) { Point top_left(upperbody[i].x, upperbody[i].y); Point low_right(upperbody[i].x + upperbody[i].width, \ upperbody[i].y + upperbody[i].height); rectangle(frame, top_left, low_right, Scalar(0, 255, 0), 4); } //-- Show what you got imshow("Capture - Face detection", frame); }