Как расширить 2d-массив (30x20) до 36x60, который содержится в 2d-массиве 620x480?

Исходные данные: массив 2d (620x480) содержит изображение, на котором показано человеческое лицо, и массив 2d (30x20), содержащий изображение глаза. Изображение лица включает изображение глаз.

Как я могу расширить изображение глаза до 36x60, чтобы включить пиксели из изображения лица? Есть ли готовые решения?

Еще одна похожая задача: изображение глаза имеет размер 37x27. Как я могу расширить изображение глаза до целевого (ближайшего к 36x60) размера, например. 39x65, т.е. сохраните требуемое соотношение сторон перед изменением размера, а затем измените размер до 36x60.

Код для тестирования (проект доступен по ссылка):

import dlib
import cv2 as cv
from imutils.face_utils import shape_to_np
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor('res/model.dat')


frame = cv.imread('photo.jpg')
gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)

img = frame.copy()
dets = detector(gray, 0)

for i, det in enumerate(dets):
    shape = shape_to_np(predictor(gray, det))
    shape_left_eye = shape[36:42]

    x, y, h, w = cv.boundingRect(shape_left_eye)
    cv.rectangle(img, (x, y), (x + h, y + w), (0, 255, 0), 1)
    cv.imwrite('file.png', frame[y: y+w, x: x+h])

Изображение 42x13: enter image description here

Не могли бы вы добавить несколько изображений, чтобы более подробно объяснить, что вы хотите? В нынешнем виде это немного сбивает с толку.

TheChubbyPanda 22.05.2019 15:44

@TheChubbyPanda для тестирования необходимо установить библиотеки opencv и dlib и скачать обученную модель для dlib с github.com/davisking/dlib-models/blob/master/…

Youlfey 22.05.2019 16:08

Проект @TheChubbyPanda для тестирования yadi.sk/d/Gg-NlNc-yM959Q

millka_15 22.05.2019 16:22
3 метода стилизации элементов HTML
3 метода стилизации элементов HTML
Когда дело доходит до применения какого-либо стиля к нашему HTML, существует три подхода: встроенный, внутренний и внешний. Предпочтительным обычно...
Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно...
Flatpickr: простой модуль календаря для вашего приложения на React
Flatpickr: простой модуль календаря для вашего приложения на React
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей....
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
7
3
118
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

В первой части вы можете использовать cv2.matchTemplate, чтобы найти область глаз на лице, а затем в соответствии с желаемым размером вы можете увеличить ее. Подробнее об этом можно прочитать здесь.

ИСПОЛЬЗУЕМОЕ ИЗОБРАЖЕНИЕ ЛИЦА

face

ИСПОЛЬЗУЕТСЯ ИЗОБРАЖЕНИЕ ГЛАЗА

eye

Размер глаз у меня (12, 32).

face = cv2.imread('face.jpg', 0)
eye = cv2.imread('eye.jpg', 0)
w, h = eye.shape[::-1]
res = cv2.matchTemplate(face,eye,cv2.TM_CCOEFF)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
top_left = max_loc
bottom_right = (top_left[0] + w, top_left[1] + h)
cv2.rectangle(face ,top_left, bottom_right, 255, 2)
cv2.imshow('image', face)
cv2.waitKey(0)
cv2.destroyAllWindows()

Результат с этим кодом:

matching eye on face

Теперь у меня есть верхняя левая и нижняя правая координаты глаза, которые совпадают, где top_left = (112, 108) и bottom_right = (144, 120). Теперь, чтобы расширить их до размеров 36x60, я просто вычитаю требуемые значения из top_left и добавляю требуемые значения в bottom_right.

РЕДАКТИРОВАТЬ 1

Вопрос был отредактирован, что предполагает, что dlib использовался вместе с моделью, обученной выполнять обнаружение левого глаза. Используя тот же код, который я получил

eye found

После этого, как было предложено выше, я нахожу top_left = (x,y) и bottom_right = (x+w, y+h).

Теперь, если размер глаза меньше 36x60, нам просто нужно взять область вокруг него, чтобы расширить его до 36x60, в противном случае мы должны расширить его таким образом, чтобы соотношение сторон не нарушалось, а затем изменить размер, и его нельзя было жестко запрограммировать. Используемый полный код:

import dlib
from imutils.face_utils import shape_to_np
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor('res/model.dat')

face = cv2.imread('face.jpg', 0)
img = face.copy()
dets = detector(img, 0)
for i, det in enumerate(dets):
    shape = shape_to_np(predictor(img, det))
    shape_left_eye = shape[36:42]
    x, y, w, h = cv2.boundingRect(shape_left_eye)
    cv2.rectangle(face, (x, y), (x + w, y + h), (255, 255, 255), 1)
top_left = (x, y)
bottom_right = (x + w, y + h)
if w <= 36 and h <= 60:
    x = int((36 - w)/2)
    y = int((60 - h)/2) 
else:
    x1 = w - 36
    y1 = h - 60
    if x1 > y1:
        x = int((w % 3)/2)
        req = (w+x) * 5 / 3
        y = int((req - h)/2)
    else:
        y = int((h % 5)/2)
        req = (y+h) * 3 / 5
        x = int((req - w)/2)
top_left = (top_left[0] - x, top_left[1] - y)
bottom_right = (bottom_right[0] + x, bottom_right[1] + y)        
extracted = face[top_left[1]:bottom_right[1], top_left[0]:bottom_right[0]]
result = cv2.resize(extracted, (36, 60),  interpolation = cv2.INTER_LINEAR)
cv2.imshow('image', face)
cv2.imshow('imag', result)
cv2.waitKey(0)
cv2.destroyAllWindows()

Что дает нам область глаза размером 36x60:

eye extracted

Это касается случая, когда размер глаза меньше 36x60. Для второго случая, когда размер глаза больше, чем область 36x60, я использовал face = cv2.resize(face, None, fx=4, fy=4, interpolation = cv2.INTER_CUBIC). В результате:

eye extracted 2

Обнаруженный размер глаза равен (95, 33), а извлеченная область — (97, 159), что очень близко к соотношению сторон 3:5 до изменения размера, что также удовлетворяет второй задаче.

Только сейчас увидел твою правку. Есть ли что-нибудь, что вы хотите, чтобы я отредактировал в своем ответе или решил вопрос с помощью dlib?

Vardan Agarwal 22.05.2019 16:29

Мне нужно это для работы с видеопотоком. Что параметры расширения умеют рассчитывать динамически. В каждом кадре разные координаты глаза. Также, если у меня есть размер глаза, который выходит за границы, я должен рассчитать размер больше 36х60, а потом изменить размер до 36х60.

millka_15 22.05.2019 16:34

может ли глаз размером в любое время быть больше 36x60?

Vardan Agarwal 22.05.2019 16:38

Иногда да. Например, 37 x 27, в этом случае необходимо расширить до ближайшего размера относительно 36 x 60 (в данном конкретном случае до 39 x 65 добавьте 3/5 к 36 x 60)

millka_15 22.05.2019 16:43

теперь все в порядке? @millka_15

Vardan Agarwal 23.05.2019 15:52

Другие вопросы по теме