58 lines
1.8 KiB
Python
58 lines
1.8 KiB
Python
|
import cv2
|
|||
|
|
|||
|
class FaceDetector:
|
|||
|
def __init__(self, cascade_path='haarcascade_frontalface_default.xml'):
|
|||
|
self.face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + cascade_path)
|
|||
|
|
|||
|
def find_faces(self, img, draw=True):
|
|||
|
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
|
|||
|
faces = self.face_cascade.detectMultiScale(gray, 1.3, 5)
|
|||
|
|
|||
|
bboxs = []
|
|||
|
for i, (x, y, w, h) in enumerate(faces):
|
|||
|
bbox = (x, y, w, h)
|
|||
|
bboxs.append([i, bbox, None]) # 'None' 用于保持与原代码结构一致,因为OpenCV不提供置信度分数
|
|||
|
|
|||
|
if draw:
|
|||
|
img = self.fancy_draw(img, bbox)
|
|||
|
|
|||
|
return img, bboxs
|
|||
|
|
|||
|
def fancy_draw(self, img, bbox, l=30, t=5, rt=1):
|
|||
|
x, y, w, h = bbox
|
|||
|
x1, y1 = x + w, y + h
|
|||
|
|
|||
|
# 绘制矩形
|
|||
|
cv2.rectangle(img, bbox, (0, 255, 255), rt)
|
|||
|
|
|||
|
# 绘制角落
|
|||
|
# 左上角
|
|||
|
cv2.line(img, (x, y), (x+l, y), (255, 0, 255), t)
|
|||
|
cv2.line(img, (x, y), (x, y+l), (255, 0, 255), t)
|
|||
|
# 右上角
|
|||
|
cv2.line(img, (x1, y), (x1-l, y), (255, 0, 255), t)
|
|||
|
cv2.line(img, (x1, y), (x1, y+l), (255, 0, 255), t)
|
|||
|
# 左下角
|
|||
|
cv2.line(img, (x, y1), (x+l, y1), (255, 0, 255), t)
|
|||
|
cv2.line(img, (x, y1), (x, y1-l), (255, 0, 255), t)
|
|||
|
# 右下角
|
|||
|
cv2.line(img, (x1, y1), (x1-l, y1), (255, 0, 255), t)
|
|||
|
cv2.line(img, (x1, y1), (x1, y1-l), (255, 0, 255), t)
|
|||
|
|
|||
|
return img
|
|||
|
|
|||
|
# 使用示例
|
|||
|
if __name__ == "__main__":
|
|||
|
detector = FaceDetector()
|
|||
|
cap = cv2.VideoCapture(0) # 使用默认摄像头
|
|||
|
|
|||
|
while True:
|
|||
|
success, img = cap.read()
|
|||
|
img, bboxs = detector.find_faces(img)
|
|||
|
|
|||
|
cv2.imshow("Image", img)
|
|||
|
if cv2.waitKey(1) & 0xFF == ord('q'):
|
|||
|
break
|
|||
|
|
|||
|
cap.release()
|
|||
|
cv2.destroyAllWindows()
|