mil*_*_15 7 arrays opencv numpy python-3.x
起始数据:包含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])
Run Code Online (Sandbox Code Playgroud)
对于第一部分,您可以用来cv2.matchTemplate找到脸部的眼睛区域,然后根据您想要的尺寸将其放大。你可以在这里读更多关于它的内容。
使用的脸部图像
使用的眼睛图像
我的眼睛大小 (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()
Run Code Online (Sandbox Code Playgroud)
这段代码的结果是:
现在我有了匹配的眼睛的左上和右下坐标,其中 top_left = (112, 108) 和 Bottom_right = (144, 120)。现在,要将它们扩展到 36x60 的尺寸,我只需从 top_left 中减去所需的值,然后在 Bottom_right 中添加所需的值。
编辑1
该问题已被编辑,表明 dlib 已与经过训练以执行左眼检测的模型一起使用。使用我获得的相同代码
之后,按照上面的建议,我发现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()
Run Code Online (Sandbox Code Playgroud)
这给了我们一个 36x60 的眼睛区域:
这可以解决眼睛尺寸小于 36x60 的情况。对于第二种情况,当眼睛的大小大于 36x60 区域时,我使用了face = cv2.resize(face, None, fx=4, fy=4, interpolation = cv2.INTER_CUBIC)。结果是:
检测到的眼睛大小为 (95, 33),提取的区域为 (97, 159),这非常接近调整大小之前的 3:5 宽高比,这也满足第二个任务。
| 归档时间: |
|
| 查看次数: |
108 次 |
| 最近记录: |