Skip to content
GitLab
Explore
Projects
Groups
Topics
Snippets
Projects
Groups
Topics
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Паршина Екатерина Сергеевна
AIMM
Commits
51717e6a
Commit
51717e6a
authored
1 month ago
by
Паршина Екатерина Сергеевна
Browse files
Options
Download
Patches
Plain Diff
Upload New File
parent
b40630a7
master
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
HW 4/Task1/task1.py
+147
-0
HW 4/Task1/task1.py
with
147 additions
and
0 deletions
+147
-0
HW 4/Task1/task1.py
0 → 100644
+
147
−
0
View file @
51717e6a
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
}
"
)
This diff is collapsed.
Click to expand it.
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment
Menu
Explore
Projects
Groups
Topics
Snippets