如何将620x480 2d数组中包含的2d数组(30x20)扩展为36x60?

时间:2019-05-22 13:40:05

标签: arrays python-3.x numpy opencv

起始数据:包含2d数组(620x480)的图像(显示人脸)和包含眼睛图像的2d数组(30x20)。面部图像包括眼睛图像。

如何将眼睛图像扩展到36x60以包含面部图像中的像素?有现成的解决方案吗?

另一个类似的任务:眼睛图像的尺寸为37x27。如何将眼睛图像扩展到目标(最接近36x60)尺寸,例如39x65,即在调整大小之前保持所需的宽高比,然后将其调整为36x60。

测试代码(reference可以提供项目):

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

1 个答案:

答案 0 :(得分:1)

对于第一部分,您可以使用(\\\\([a-z|A-Z|0-9|-|_|\s]{2,15}){1}(\.[a-z|A-Z|0-9|-|_|\s]{1,64}){0,3}){1}(\\[^\\|\/|\:|\*|\?|"|\<|\>|\|]{1,64}){1,}(\\){0,} 查找脸部的眼睛区域,然后根据您想要的大小进行放大。您可以详细了解here

已使用面部图像

face

使用过的眼睛图像

eye

我的眼睛大小(12,32)。

cv2.matchTemplate

使用此代码的结果是:

matching eye on face

现在我的眼睛的左上和右下坐标相匹配,其中top_left =(112,108)和bottom_right =(144,120)。现在将其扩展为36x60的尺寸,我只需从top_left中减去所需的值,然后在bottom_right中添加所需的值。

编辑1

该问题已经过编辑,表明dlib已与训练有素的执行左眼检测的模型一起使用。使用我获得的相同代码

eye found

之后,按照上面的建议,我发现了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() top_left = (x,y)

现在,如果眼睛的尺寸较小,为36x60,那么我们只需要占用其周围的区域即可将其扩展为36x60,否则我们就必须对其进行扩展,以使宽高比不会受到干扰,然后重新调整尺寸并且无法进行硬编码。使用的完整代码为:

bottom_right = (x+w, y+h)

哪个给了我们36x60的眼睛区域:

eye extracted

当眼睛的尺寸小于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() 。结果是:

eye extracted 2

检测到的眼睛大小为(95,33),提取的区域为(97,159),这与调整大小前的3:5宽高比非常接近,这也满足了第二项任务。