从面部标志点cv2 dlib获取ROI

时间:2017-01-07 11:44:29

标签: python opencv dlib

使用以下代码使用dlib绘制面部地标点,实时搜索从网络摄像头捕获的帧,现在正在寻找的是获得限制所有符合面部的点的ROI,代码如下:

import cv2
import dlib
import numpy
from imutils.video import FPS
from imutils.video import WebcamVideoStream
import imutils

PREDICTOR_PATH = "./shape_predictor_68_face_landmarks.dat"
predictor = dlib.shape_predictor(PREDICTOR_PATH)
cascade_path = 'cascade/haarcascade_frontalface_default.xml'
cascade = cv2.CascadeClassifier(cascade_path)

webcam = WebcamVideoStream(src=0).start()
fps = FPS().start()

while True:
    im = webcam.read()
    im = imutils.resize(im, width=400)

    faces = cascade.detectMultiScale(im, 1.3, 5)
    if len(faces) != 0:
        for (x, y, w, h) in faces.astype(long):
            rect = dlib.rectangle(x, y, x + w, y + h)
            #cv2.imwrite('face.png', rect)
            get_landmarks = numpy.matrix([[p.x, p.y] for p in predictor(im, rect).parts()])

        for idx, point in enumerate(get_landmarks):
            pos = (point[0, 0], point[0, 1])
            cv2.putText(im, str(idx), pos,
                        fontFace=cv2.FONT_HERSHEY_SCRIPT_SIMPLEX,
                        fontScale=0.4,
                        color=(0, 0, 255))
           # cv2.drawContours(im, [pos], -1, (0, 255, 0), 2)
#            hullIndex = cv2.convexHull(pos, returnPoints=False)
#            cv2.imwrite('face.png', hullIndex)
            cv2.circle(im, pos, 3, color=(0, 255, 255))
    cv2.imshow('Result', im)

    if cv2.waitKey(1) & 0xFF == ord('q'):
        break
    fps.update()

cv2.destroyAllWindows()

我想将面部地标点转储到​​图像文件中。但我无法理解,我如何从这些标志性点提取ROI,然后使用

转储到文件
  

cv2.imwrite(' face.png',hullIndex)

,但在这里我不想要使用

扫描矩形
  

faces = cascade.detectMultiScale(im,1.3,5)

,我只想要面向面部地标点的形状,上面代码的输出如下所示。

enter image description here

所以,只转储围绕面部边缘点的点。

1 个答案:

答案 0 :(得分:0)

在从预测变量获得68个面部标志后,您可以简单地遍历所有点并更新minX, minY, maxX, maxY,在迭代之后,cv2.boundingRect(points)将产生完全包围所有面部标志的边界矩形。

您也可以使用minX, minY = 10000000, 10000000 maxX, maxY = 0, 0 for point in get_landmarks: if point[0] < minX: minX = point[0] elif point[0] > maxX: maxX = point[0] elif point[1] < minY: minY = point[1] elif point[1] > maxY: maxY = point[1] bounding_rect = [minX, minY, maxX - minX, maxY - minY] ,但在传递给此方法之前,您需要将所有点转换为numpy数组。

但我建议您使用第一个解决方案,并且很容易实现

class TableDropDown(ttk.Combobox):
    def __init__(self, parent):
        self.current_table = tk.StringVar() # create variable for table
        ttk.Combobox.__init__(self, parent)#  init widget
        self.config(textvariable = self.current_table, state = "readonly", values = ["Customers", "Pets", "Invoices", "Prices"])
        self.current(0) # index of values for current table
        self.place(x = 50, y = 50, anchor = "w") # place drop down box