지금까지 설명한 SSD 네트워크를 이용한 얼굴 검출 코드를 모아서 코드 16-5에 나타냈습니다. 코드 16-5에 나타난 dnnface 예제 프로그램 소스 코드는 카메라 입력 영상에서 얼굴을 검출하고, 그 위치를 녹색 사각형으로 표시합니다. 코드 16-5에 나타난 소스 코드 파일은 내려받은 예제 파일 중 ch16/dnnface 프로젝트에서 확인할 수 있습니다.
코드 16-5 SSD 얼굴 검출 예제 프로그램 [ch16/dnnface]
01 #include "opencv2/opencv.hpp" 02 #include <iostream> 03 04 using namespace cv; 05 using namespace cv::dnn; 06 using namespace std; 07 08 const String model = "res10_300x300_ssd_iter_140000_fp16.caffemodel"; 09 const String config = "deploy.prototxt"; 10 //const String model = "opencv_face_detector_uint8.pb"; 11 //const String config = "opencv_face_detector.pbtxt"; 12 13 int main(void) 14 { 15 VideoCapture cap(0); 16 17 if (!cap.isOpened()) { 18 cerr << "Camera open failed!" << endl; 19 return -1; 20 } 21 22 Net net = readNet(model, config); 23 24 if (net.empty()) { 25 cerr << "Net open failed!" << endl; 26 return -1; 27 } 28 29 Mat frame; 30 while (true) { 31 cap >> frame; 32 if (frame.empty()) 33 break; 34 35 Mat blob = blobFromImage(frame, 1, Size(300, 300), Scalar(104, 177, 123)); 36 net.setInput(blob); 37 Mat res = net.forward(); 38 39 Mat detect(res.size[2], res.size[3], CV_32FC1, res.ptr<float>()); 40 41 for (int i = 0; i < detect.rows; i++) { 42 float confidence = detect.at<float>(i, 2); 43 if (confidence < 0.5) 44 break; 45 46 int x1 = cvRound(detect.at<float>(i, 3) * frame.cols); 47 int y1 = cvRound(detect.at<float>(i, 4) * frame.rows); 48 int x2 = cvRound(detect.at<float>(i, 5) * frame.cols); 49 int y2 = cvRound(detect.at<float>(i, 6) * frame.rows); 50 51 rectangle(frame, Rect(Point(x1, y1), Point(x2, y2)), Scalar(0, 255, 0)); 52 53 String label = format("Face: %4.3f", confidence); 54 putText(frame, label, Point(x1, y1 - 1), FONT_HERSHEY_SIMPLEX, 0.8, Scalar(0, 255, 0)); 55 } 56 57 imshow("frame", frame); 58 if (waitKey(1) = = 27) 59 break; 60 } 61 62 return 0; 63 }