Commit 51717e6a authored by Паршина Екатерина Сергеевна's avatar Паршина Екатерина Сергеевна
Browse files

Upload New File

parent b40630a7
No related merge requests found
Showing with 147 additions and 0 deletions
+147 -0
import cv2 as cv
import numpy as np
from scipy.spatial.distance import cityblock, euclidean
from scipy.stats import pearsonr
# Пути к моделям
FACE_DETECTION_MODEL = "models/face_detection_yunet_2023mar.onnx"
FACE_RECOGNITION_MODEL = "models/face_recognition_sface_2021dec.onnx"
# Параметры обработки
SCORE_THRESHOLD = 0.5
NMS_THRESHOLD = 0.3
SCALE = 1.0
TOP_K = 5000
# Пути к файлам
GROUND_BASE_IMAGES = ["orig.jpg", "smile.jpg", "think.jpg", "flow.jpg"] # Несколько эталонных изображений
VIDEO_INPUT = "spb.mp4"
VIDEO_OUTPUT = "output_video9.mp4"
def load_models():
"""Загружает модели детекции и распознавания лиц."""
detector = cv.FaceDetectorYN.create(
FACE_DETECTION_MODEL, "", (320, 320),
SCORE_THRESHOLD, NMS_THRESHOLD, TOP_K
)
recognizer = cv.FaceRecognizerSF.create(FACE_RECOGNITION_MODEL, "")
return detector, recognizer
def get_ground_base_features(detector, recognizer, image_paths):
"""Извлекает признаки для нескольких эталонных изображений."""
features = []
for image_path in image_paths:
base_image = cv.imread(cv.samples.findFile(image_path))
if base_image is None:
print(f"Ошибка загрузки {image_path}")
continue
width, height = base_image.shape[1], base_image.shape[0]
detector.setInputSize((width, height))
faces = detector.detect(base_image)
if faces[1] is None:
print(f"Лицо не найдено в {image_path}")
continue
face_align = recognizer.alignCrop(base_image, faces[1][0])
feature = recognizer.feature(face_align).flatten()
features.append(feature)
assert len(features) > 0, "Не удалось загрузить ни одного эталонного изображения!"
return features
def compare_faces(recognizer, face_img, reference_features):
"""Сравнивает лицо с несколькими эталонными изображениями."""
feature = recognizer.feature(face_img).flatten()
metrics_list = []
for ref_feature in reference_features:
cos_sim = recognizer.match(feature, ref_feature, cv.FaceRecognizerSF_FR_COSINE)
l2_sim = recognizer.match(feature, ref_feature, cv.FaceRecognizerSF_FR_NORM_L2)
l1_dist = cityblock(feature, ref_feature)
euclidean_dist = euclidean(feature, ref_feature)
pearson_corr, _ = pearsonr(feature, ref_feature)
metrics_list.append({
"cos_sim": cos_sim,
"l2_sim": l2_sim,
"l1_dist": l1_dist,
"euclidean_dist": euclidean_dist,
"pearson_corr": pearson_corr,
})
return metrics_list
def determine_face_match(metrics_list):
"""Определяет, является ли лицо совпадающим, используя несколько эталонных изображений."""
for metrics in metrics_list:
if (
metrics["cos_sim"] >= 0.3 or
metrics["l1_dist"] <= 1.0 or
metrics["pearson_corr"] > 0.9
):
return True
return False
def process_frame(frame, detector, recognizer, reference_features):
"""Обрабатывает кадр: обнаружение лиц и рисование рамок."""
detector.setInputSize((frame.shape[1], frame.shape[0]))
faces = detector.detect(frame)
if faces[1] is None:
return frame
for face in faces[1]:
aligned_face = recognizer.alignCrop(frame, face)
metrics_list = compare_faces(recognizer, aligned_face, reference_features)
color = (0, 255, 0) if determine_face_match(metrics_list) else (0, 0, 255)
try:
x, y, w, h = face[:4].astype(np.int32)
except ValueError:
print(f"Ошибка при извлечении координат для лица: {face}")
continue
cv.rectangle(frame, (x, y), (x + w, y + h), color, 2)
return frame
def process_video(input_path, output_path, detector, recognizer, reference_features):
"""Обрабатывает входное видео и сохраняет результат."""
video_capture = cv.VideoCapture(input_path)
if not video_capture.isOpened():
print("Не удалось открыть видео.")
return
fourcc = cv.VideoWriter_fourcc(*'mp4v')
frame_width = int(video_capture.get(cv.CAP_PROP_FRAME_WIDTH) * SCALE)
frame_height = int(video_capture.get(cv.CAP_PROP_FRAME_HEIGHT) * SCALE)
output_video = cv.VideoWriter(output_path, fourcc, 30.0, (frame_width, frame_height))
while True:
ret, frame = video_capture.read()
if not ret:
print("Видео закончилось.")
break
frame = cv.resize(frame, (frame_width, frame_height))
processed_frame = process_frame(frame, detector, recognizer, reference_features)
output_video.write(processed_frame)
video_capture.release()
output_video.release()
cv.destroyAllWindows()
"""Основной процесс обработки видео."""
detector, recognizer = load_models()
reference_features = get_ground_base_features(detector, recognizer, GROUND_BASE_IMAGES)
process_video(VIDEO_INPUT, VIDEO_OUTPUT, detector, recognizer, reference_features)
print(f"Обработка завершена. Видео сохранено в {VIDEO_OUTPUT}")
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment