用python、opencv快速實現人臉檢測

Prerequisites:

python2.7、openCV3.0

代碼及註釋

def detectface(filename):
    files = []
    print('Using face detector %s' % FLAGS.face_detection_model)
    face_detect = FaceDetector('haarcascade_frontalface_default.xml')
    face_files, rectangles = face_detect.run(filename)
    files += face_files
    if (len(files)>0) :
        return 1
    else:
        return 0

主要是FaceDetector類的run函數實現了人臉檢測,run函數會返回人臉的文件、以及矩形區域
我們把FaceDetector類的實現代碼貼出來

class FaceDetector(object):

    def __init__(self, model_name, basename = 'frontal-face', tgtdir = '.'):
        self.tgtdir = tgtdir
        self.basename = basename
        self.face_cascade = cv2.CascadeClassifier(model_name)

    def run(self, image_file, min_height_dec = 20, min_width_dec = 20, min_height_thresh=50, min_width_thresh=50):
        print(image_file)
        img = cv2.imread(image_file)
        min_h = int(max(img.shape[0] / min_height_dec, min_height_thresh))
        min_w = int(max(img.shape[1] / min_width_dec, min_width_thresh))
        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        faces = self.face_cascade.detectMultiScale(gray, 1.3, minNeighbors=5, minSize=(min_h,min_w))

        images = []
        for i, (x,y,w,h) in enumerate(faces):
            images.append(self.sub_image('%s/%s-%d.jpg' % (self.tgtdir, self.basename, i+1), img, x, y, w, h))

        print('%d faces detected' % len(images))

        for (x,y,w,h) in faces:
            self.draw_rect(img, x, y, w, h)
            # Fix in case nothing found in the image
        outfile = '%s/%s.jpg' % (self.tgtdir, self.basename)
        cv2.imwrite(outfile, img)

        return images, outfile

    def sub_image(self, name, img, x, y, w, h):
        upper_cut = [min(img.shape[0], y+h+FACE_PAD), min(img.shape[1], x+w+FACE_PAD)]
        lower_cut = [max(y-FACE_PAD, 0), max(x-FACE_PAD, 0)]
        roi_color = img[lower_cut[0]:upper_cut[0], lower_cut[1]:upper_cut[1]]
        cv2.imwrite(name, roi_color)
        return name

    def draw_rect(self, img, x, y, w, h):
        upper_cut = [min(img.shape[0], y+h+FACE_PAD), min(img.shape[1], x+w+FACE_PAD)]
        lower_cut = [max(y-FACE_PAD, 0), max(x-FACE_PAD, 0)]
        cv2.rectangle(img, (lower_cut[1],lower_cut[0]),(upper_cut[1],upper_cut[0]), (255,0,0), 2)

FaceDetector類有init初始化函數來初始化顯式變量,是可變長參數
我們第一段代碼中只是傳了模型參數

more haarcascade_frontalface_default.xml 

打開模型配置文件,發現是一堆xml配置參數

  <stages>
    <_>
      <maxWeakCount>9</maxWeakCount>
      <stageThreshold>-5.0425500869750977e+00</stageThreshold>
      <weakClassifiers>
        <_>
          <internalNodes>
            0 -1 0 -3.1511999666690826e-02</internalNodes>
          <leafValues>
            2.0875380039215088e+00 -2.2172100543975830e+00</leafValues></_>
        <_>
          <internalNodes>
            0 -1 1 1.2396000325679779e-02</internalNodes>
          <leafValues>
            -1.8633940219879150e+00 1.3272049427032471e+00</leafValues></_>
        <_>
          <internalNodes>
            0 -1 2 2.1927999332547188e-02</internalNodes>
          <leafValues>
            -1.5105249881744385e+00 1.0625729560852051e+00</leafValues></_>
        <_>
          <internalNodes>
            0 -1 3 5.7529998011887074e-03</internalNodes>
          <leafValues>
            -8.7463897466659546e-01 1.1760339736938477e+00</leafValues></_>
        <_>
          <internalNodes>
            0 -1 4 1.5014000236988068e-02</internalNodes>
          <leafValues>
            -7.7945697307586670e-01 1.2608419656753540e+00</leafValues></_>
        <_>
          <internalNodes>

這是從openCV源碼那邊拷貝過來的,是別人訓練好的haar分類器模型,可以看到起到主要作用的函數是
detectMultiScale
人臉檢測主要用到的是CascadeClassifier這個類,以及該類下的detectMultiScale函數。

函數原型是:

void CascadeClassifier::detectMultiScale(InputArray image, vector<Rect>& objects, double scaleFactor=1.1, int minNeighbors=3, int flags=0, Size minSize=Size(), Size maxSize=Size())

總共有7個參數,分別是

第一個參數image: 要檢測的圖片,一般爲灰度圖

第二個參數objects: Rect型的容器,存放所有檢測出的人臉,每個人臉是一個矩形

第三個參數scaleFactor: 縮放因子,對圖片進行縮放,默認爲1.1

第四個參數minNeighbors: 最小鄰居數,默認爲3

第五個參數flags: 兼容老版本的一個參數,在3.0版本中沒用處。默認爲0

第六個參數minSize: 最小尺寸,檢測出的人臉最小尺寸

第七個參數maxSize: 最大尺寸,檢測出的人臉最大尺寸

這裏關注第六和第七個參數,由之前的代碼看出

        min_h = int(max(img.shape[0] / min_height_dec, min_height_thresh))
        min_w = int(max(img.shape[1] / min_width_dec, min_width_thresh))

img.shape[0]和img.shape[1]分別是圖片的高、寬,然後除以20的整數,和預設的min_height_thresh、min_width_thresh作比較後,取最大值的整數。
也就是理論上說可以最小檢測到圖片1/20的人臉
可以看到這裏沒有傳遞最大的值。

具體的參數配置可參考這篇csdn博友的文章http://blog.csdn.net/delltdk/article/details/9186875
(待續)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章