# dlib系列笔记3:人脸检测 ## 效果图 ![img1](https://raw.githubusercontent.com/lightjiang/FaceRecognize/master/results/others/1.png) ## 源码 截取重要类的实现片段 具体源码参考 https://github.com/lightjiang/FaceRecognize.git - base.py ``` python class Base(object): base_path = BASEPATH def __init__(self): self.img = None self.img_path = '' def load_img(self, path, relative=True, flags=cv2.IMREAD_COLOR): # 自动从web加载图片 if path.startswith('http'): path = self.download_web_img(path) img_path = path if relative: path = os.path.join(self.base_path, path) if os.path.exists(path): res = cv2.imread(path, flags=flags) # 转换图片通道, opencv默认bgr格式,dlib需要rgb格式 self.img = cv2.cvtColor(res, cv2.COLOR_BGR2RGB) self.img_path = img_path return self.img else: raise FileNotFoundError(path) def download_web_img(self, url): path = 'data/auto_download_img/%s.jpg' % uuid.uuid1() # 复制的百度图片链接有时会下载异常 request.urlretrieve(url, path) print('download complete') return path def save_img(self, img, path, relative=True): if relative: path = os.path.join(self.base_path, path) cv2.imwrite(path, cv2.cvtColor(img, cv2.COLOR_RGB2BGR)) def add_marks(self, pos, color=None): # 在self.img 上添加标记 if isinstance(pos, tuple): pos = [pos] elif isinstance(pos, list): pos = pos else: raise AttributeError if not color: color = (0, 255, 0) for p in pos: cv2.circle(self.img, p, 2, color, 1) def add_faces(self, faces, show_score=True, color=None, add_text=None): # 在self.img 上添加脸部识别框 if isinstance(faces, dict): faces = [faces] elif isinstance(faces, list): faces = faces else: raise AttributeError for face in faces: rect = face['position'] if not color: color = (255, 0, 0) cv2.rectangle(self.img, (rect.left(), rect.top()), (rect.right(), rect.bottom()), color, 3) if show_score and 'score' in face: score = face['score'] width = rect.right() - rect.left() cv2.putText(self.img, str(round(score, 3)), (rect.left() + 10, rect.bottom() - 10), cv2.FONT_HERSHEY_SIMPLEX, width/120, (255, 255, 255), 1) if add_text: width = rect.right() - rect.left() cv2.putText(self.img, str(add_text), (rect.left() + 10, rect.bottom() - 10), cv2.FONT_HERSHEY_SIMPLEX, width / 120, (255, 255, 255), 1) ``` - face_detector.py ``` python class FaceDetector(Base): """ based on HOG """ def __init__(self): self.face_detector = dlib.get_frontal_face_detector() super().__init__() def detect_face(self, log_status=True): if self.img is None: raise AttributeError('please load img before detect') t = time.time() dets, scores, idx = self.face_detector.run(self.img, 1, -1) res = [] for index, face in enumerate(dets): temp = { 'id': str(uuid.uuid1()), 'position': face, 'score': scores[index], 'src': self.img_path } if scores[index] > 0: res.append(temp) if log_status: print("Detecting faces takes: {}s\nNumber of faces detected: {}".format(time.time() - t, len(res))) return res def detect_faces_from_imgs(self, imgs: list): t = time.time() res = [] for img_path in imgs: self.load_img(img_path) res += self.detect_face(log_status=False) self.img = None print("Detecting faces takes: {}s\nNumber of faces detected: {}".format(time.time() - t, len(res))) return res ``` - cpp_src/face_detector.cpp ``` cpp #include #include #include #include #include #include #include #include #include #include "mybase.hpp" using namespace dlib; using namespace std; // ---------------------------------------------------------------------------------------- int main(int argc, char **argv) { try { if (argc == 1) { cout << "Give some image files as arguments to this program." << endl; return 0; } frontal_face_detector detector = get_frontal_face_detector(); // Loop over all the images provided on the command line. for (int i = 1; i < argc; ++i) { cout << "processing image " << argv[i] << endl; cv::Mat image; image = cv::imread(argv[i], cv::IMREAD_COLOR); dlib::cv_image img(image); std::vector dets = detector(img); cout << "Number of faces detected: " << dets.size() << dets[0].left() <