人臉檢測(cè)——fcn

在上一篇的基礎(chǔ)上修改即可:人臉檢測(cè)——滑動(dòng)窗口篇(訓(xùn)練和實(shí)現(xiàn))
J当巍5茨搿!注意:這些是我的調(diào)試版本局装,最優(yōu)版本不方便公開(kāi)坛吁,但是自己可以查看論文,自行在此基礎(chǔ)上修改铐尚,加深一些模型拨脉,加上回歸框,要不fcn容易出現(xiàn)較大偏差宣增。
fcn:

import tensorflow as tf  
import numpy as np  
import sys  
# from models import *  
from PIL import Image  
from PIL import ImageDraw  
from PIL import ImageFile  
from skimage.transform import pyramid_gaussian  
from skimage.transform import resize  
from matplotlib import pyplot  
ImageFile.LOAD_TRUNCATED_IMAGES = True  
import utils  
import cv2  
import pylab  
  
def fcn_12_detect(threshold, dropout=False, activation=tf.nn.relu):  
      
    imgs = tf.placeholder(tf.float32, [None, None, None, 3])  
    labels = tf.placeholder(tf.float32, [None, 2])  
    keep_prob = tf.placeholder(tf.float32, name='keep_prob')  
    with tf.variable_scope('net_12'):  
        conv1,_ = utils.conv2d(x=imgs, n_output=16, k_w=3, k_h=3, d_w=1, d_h=1, name="conv1")  
        conv1 = activation(conv1)  
        pool1 = tf.nn.max_pool(conv1, ksize=[1, 3, 3, 1], strides=[1, 2, 2, 1], padding="SAME", name="pool1")  
        ip1,W1 = utils.conv2d(x=pool1, n_output=16, k_w=6, k_h=6, d_w=1, d_h=1, padding="VALID", name="ip1")  
        ip1 = activation(ip1)  
        if dropout:  
            ip1 = tf.nn.dropout(ip1, keep_prob)  
        ip2,W2 = utils.conv2d(x=ip1, n_output=2, k_w=1, k_h=1, d_w=1, d_h=1, name="ip2")  
  
        #pred = tf.nn.sigmoid(utils.flatten(ip2))  
        pred = tf.nn.sigmoid(ip2)  
          
        return {'imgs': imgs, 'keep_prob': keep_prob,'pred': pred, 'features': ip1}  
  
def fcn_24_detect(threshold, dropout=False, activation=tf.nn.relu):  
  
    imgs = tf.placeholder(tf.float32, [None, 24, 24, 3])  
    labels = tf.placeholder(tf.float32, [None, 2])  
    keep_prob = tf.placeholder(tf.float32, name='keep_prob')  
      
    with tf.variable_scope('net_24'):  
        conv1, _ = utils.conv2d(x=imgs, n_output=64, k_w=5, k_h=5, d_w=1, d_h=1, name="conv1")  
        conv1 = activation(conv1)  
        pool1 = tf.nn.max_pool(conv1, ksize=[1, 3, 3, 1], strides=[1, 2, 2, 1], padding="SAME", name="pool1")  
        ip1, W1 = utils.conv2d(x=pool1, n_output=128, k_w=12, k_h=12, d_w=1, d_h=1, padding="VALID", name="ip1")  
        ip1 = activation(ip1)  
        concat = ip1  
        if dropout:  
            concat = tf.nn.dropout(concat, keep_prob)  
        ip2, W2 = utils.conv2d(x=concat, n_output=2, k_w=1, k_h=1, d_w=1, d_h=1, name="ip2")  
  
        pred = tf.nn.sigmoid(utils.flatten(ip2))  
        target = utils.flatten(labels)  
  
        regularizer = 8e-3 * (tf.nn.l2_loss(W1)+100*tf.nn.l2_loss(W2))  
  
        loss = tf.reduce_mean(tf.div(tf.add(-tf.reduce_sum(target * tf.log(pred + 1e-9),1), -tf.reduce_sum((1-target) * tf.log(1-pred + 1e-9),1)),2)) + regularizer  
        cost = tf.reduce_mean(loss)  
          
        predict = pred  
        max_idx_p = tf.argmax(predict, 1)    
        max_idx_l = tf.argmax(target, 1)    
        correct_pred = tf.equal(max_idx_p, max_idx_l)    
        acc = tf.reduce_mean(tf.cast(correct_pred, tf.float32))    
  
        thresholding_24 = tf.cast(tf.greater(pred, threshold), "float")  
        recall_24 = tf.reduce_sum(tf.cast(tf.logical_and(tf.equal(thresholding_24, tf.constant([1.0])), tf.equal(target, tf.constant([1.0]))), "float")) / tf.reduce_sum(target)  
  
  
        return { 'imgs': imgs, 'labels': labels,   
            'keep_prob': keep_prob, 'cost': cost, 'pred': pred, 'accuracy': acc, 'features': concat,  
            'recall': recall_24, 'thresholding': thresholding_24}  
  
def py_nms(dets, thresh, mode="Union"):  
    """ 
        greedily select boxes with high confidence 
        keep boxes overlap <= thresh 
        rule out overlap > thresh 
        :param dets: [[x1, y1, x2, y2 score]] 
        :param thresh: retain overlap <= thresh 
        :return: indexes to keep 
        """  
    if len(dets) == 0:  
        return []  
    x1 = dets[:, 0]  
    y1 = dets[:, 1]  
    x2 = dets[:, 2]  
    y2 = dets[:, 3]  
    scores = dets[:, 4]  
      
    areas = (x2 - x1 + 1) * (y2 - y1 + 1)  
    order = scores.argsort()[::-1]  
      
    keep = []  
    while order.size > 0:  
        i = order[0]  
        keep.append(i)  
        xx1 = np.maximum(x1[i], x1[order[1:]])  
        yy1 = np.maximum(y1[i], y1[order[1:]])  
        xx2 = np.minimum(x2[i], x2[order[1:]])  
        yy2 = np.minimum(y2[i], y2[order[1:]])  
          
        w = np.maximum(0.0, xx2 - xx1 + 1)  
        h = np.maximum(0.0, yy2 - yy1 + 1)  
        inter = w * h  
        if mode == "Union":  
            ovr = inter / (areas[i] + areas[order[1:]] - inter)  
        elif mode == "Minimum":  
            ovr = inter / np.minimum(areas[i], areas[order[1:]])  
          
        inds = np.where(ovr <= thresh)[0]  
        order = order[inds + 1]  
      
    return dets[keep]  
  
def nms(boxes, threshold, method):  
    if boxes.size==0:  
        return np.empty((0,3))  
    x1 = boxes[:,0]  
    y1 = boxes[:,1]  
    x2 = boxes[:,2]  
    y2 = boxes[:,3]  
    s = boxes[:,4]  
    area = (x2-x1+1) * (y2-y1+1)  
    I = np.argsort(s)  
    pick = np.zeros_like(s, dtype=np.int16)  
    counter = 0  
    while I.size>0:  
        i = I[-1]  
        pick[counter] = i  
        counter += 1  
        idx = I[0:-1]  
        xx1 = np.maximum(x1[i], x1[idx])  
        yy1 = np.maximum(y1[i], y1[idx])  
        xx2 = np.minimum(x2[i], x2[idx])  
        yy2 = np.minimum(y2[i], y2[idx])  
        w = np.maximum(0.0, xx2-xx1+1)  
        h = np.maximum(0.0, yy2-yy1+1)  
        inter = w * h  
        if method is 'Min':  
            o = inter / np.minimum(area[i], area[idx])  
        else:  
            o = inter / (area[i] + area[idx] - inter)  
        I = I[np.where(o<=threshold)]  
    pick = pick[0:counter]  
    return pick  
  
  # 預(yù)處理變了要重新訓(xùn)練哦玫膀。
def image_preprocess(img):

    img = (img - 127.5)*0.0078125
    '''m = img.mean()
    s = img.std()
    min_s = 1.0/(np.sqrt(img.shape[0]*img.shape[1]*img.shape[2]))
    std = max(min_s, s)  
    img = (img-m)/std'''

    return img
  
def min_face(img, F, window_size, stride):  
    # img:輸入圖像,F(xiàn):最小人臉大小爹脾, window_size:滑動(dòng)窗帖旨,stride:滑動(dòng)窗的步長(zhǎng)。  
    h, w, _ = img.shape  
    w_re = int(float(w)*window_size/F)  
    h_re = int(float(h)*window_size/F)  
    if w_re<=window_size+stride or h_re<=window_size+stride:  
        print (None)  
    # 調(diào)整圖片大小的時(shí)候注意參數(shù)灵妨,千萬(wàn)不要寫(xiě)反了  
    # 根據(jù)最小人臉縮放圖片  
    img = cv2.resize(img, (w_re, h_re))  
    return img  
  
# 構(gòu)建圖像的金字塔碉就,以便進(jìn)行多尺度滑動(dòng)窗口  
# image是輸入圖像,f為縮放的尺度闷串, window_size最小尺度  
def pyramid(image, f, window_size):  
    w = image.shape[1]  
    h = image.shape[0]  
    img_ls = []  
    while( w > window_size and h > window_size):  
        img_ls.append(image)  
        w = int(w * f)  
        h = int(h * f)  
        image = cv2.resize(image, (w, h))  
    return img_ls  
  
# 選取map中大于人臉閥值的點(diǎn),映射到原圖片的窗口大小筋量,默認(rèn)map中的一個(gè)點(diǎn)對(duì)應(yīng)輸入圖中的12*12的窗口烹吵,最后要根據(jù)縮放比例映射到原圖碉熄。  
def generateBoundingBox(imap, scale, t):  
    # use heatmap to generate bounding boxes  
    stride=2  
    cellsize=12  
  
    imap = np.transpose(imap)  
    y, x = np.where(imap >= t)  
      
    score = imap[(y,x)]  
    bb = np.transpose(np.vstack([y,x]))  
    q1 = np.fix((stride*bb+1)/scale)  
    q2 = np.fix((stride*bb+cellsize-1+1)/scale)  
    boundingbox = np.hstack([q1, q2, np.expand_dims(score,1)])  
    return boundingbox  
  
def imresample(img, sz):  
    im_data = cv2.resize(img, (sz[1], sz[0]), interpolation=cv2.INTER_AREA) #pylint: disable=no-member  
    return im_data  
  
if __name__ == '__main__':  
  
    image = cv2.imread('images/11.jpg')  
    h,w,_ = image.shape  
    # 調(diào)參的參數(shù)  
    IMAGE_SIZE = 12  
    # 步長(zhǎng)  
    stride = 2  
    # 最小人臉大小  
    F = 24  
    # 構(gòu)建金字塔的比例  
    ff = 0.8  
    # 概率多大時(shí)判定為人臉?  
    p_12 = 0.8  
    p_24 = 0.8  
    # nms  
    overlapThresh_12 = 0.7
    # 是否啟用net-24  
    net_24 = True  
    overlapThresh_24 = 0.3
    '''''--------------------------------------'''  
      
    net_12 = fcn_12_detect(0.0)  
    net_12_vars = [v for v in tf.trainable_variables() if v.name.startswith('net_12')]  
    saver_net_12 = tf.train.Saver(net_12_vars)  
      
    net_24 = fcn_24_detect(0.0)  
    net_24_vars = [v for v in tf.trainable_variables() if v.name.startswith('net_24')]  
    saver_net_24 = tf.train.Saver(net_24_vars)  
      
  
    sess = tf.Session()  
    sess.run(tf.initialize_all_variables())  
  
    saver_net_12.restore(sess, 'model/12-net/model_net_12-123246')  
    saver_net_24.restore(sess, 'model/24-net/model_net_24-161800')  
    # saver_cal_48.restore(sess, 'model/model_cal_48-10000')  
      
      
    # 需要檢測(cè)的最小人臉  
    img =image  
    factor_count=0  
    total_boxes=np.empty((0,5))  
    points=[]  
    h=img.shape[0]  
    w=img.shape[1]  
    minl=np.amin([h, w])  
    m=12.0/F  
    minl=minl*m  
    # creat scale pyramid  
    scales=[]  
    factor=ff  
    while minl>=12:  
        scales += [m*np.power(factor, factor_count)]  
        minl = minl*factor  
        factor_count += 1  
  
    # first stage  
    for j in range(len(scales)):  
        scale=scales[j]  
        hs=int(np.ceil(h*scale))  
        ws=int(np.ceil(w*scale))  
        im_data = imresample(img, (hs, ws))  
        im_data = image_preprocess(im_data)  
        pred_cal_12 = sess.run(net_12['pred'], feed_dict={net_12['imgs']: [im_data]})  
        out = np.transpose(pred_cal_12, (0,2,1,3))  
        threshold_12 = p_12  
        boxes = generateBoundingBox(out[0,:,:,1].copy(), scale, threshold_12)  
        boxes = py_nms(boxes, overlapThresh_12, 'Union')  
        if boxes != []:  
            total_boxes = np.append(total_boxes, boxes, axis=0)  
          
      
    window_net = total_boxes  
    # 后面24-net肋拔,48-net  
  
    if window_net == []:  
        print "windows is None!"  
    if window_net != []:  
        print(window_net.shape)  
        for box in window_net:  
            #ImageDraw.Draw(image).rectangle((box[1], box[0], box[3], box[2]), outline = "red")  
            cv2.rectangle(image, (int(box[1]),int(box[0])), (int(box[3]),int(box[2])), (0, 255, 0), 2)  
    cv2.imwrite("images/face_img.jpg", image)  
    cv2.imshow("face detection", image)  
    cv2.waitKey(10000)  
    cv2.destroyAllWindows()  
      
  
    sess.close()  

檢測(cè)結(jié)果:


20170920084446842.jpg
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末锈津,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子凉蜂,更是在濱河造成了極大的恐慌琼梆,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,194評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件窿吩,死亡現(xiàn)場(chǎng)離奇詭異茎杂,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)纫雁,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門(mén)煌往,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人轧邪,你說(shuō)我怎么就攤上這事刽脖。” “怎么了忌愚?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,780評(píng)論 0 346
  • 文/不壞的土叔 我叫張陵曲管,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我硕糊,道長(zhǎng)院水,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,388評(píng)論 1 283
  • 正文 為了忘掉前任癌幕,我火速辦了婚禮衙耕,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘勺远。我一直安慰自己橙喘,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,430評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布胶逢。 她就那樣靜靜地躺著厅瞎,像睡著了一般。 火紅的嫁衣襯著肌膚如雪初坠。 梳的紋絲不亂的頭發(fā)上和簸,一...
    開(kāi)封第一講書(shū)人閱讀 49,764評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音碟刺,去河邊找鬼锁保。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 38,907評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼对人,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼艺蝴!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,679評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后酿矢,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,122評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡怎燥,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,459評(píng)論 2 325
  • 正文 我和宋清朗相戀三年瘫筐,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片刺覆。...
    茶點(diǎn)故事閱讀 38,605評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡严肪,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出谦屑,到底是詐尸還是另有隱情驳糯,我是刑警寧澤,帶...
    沈念sama閱讀 34,270評(píng)論 4 329
  • 正文 年R本政府宣布氢橙,位于F島的核電站酝枢,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏悍手。R本人自食惡果不足惜帘睦,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,867評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望坦康。 院中可真熱鬧竣付,春花似錦、人聲如沸滞欠。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,734評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)筛璧。三九已至逸绎,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間夭谤,已是汗流浹背棺牧。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,961評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留朗儒,地道東北人颊乘。 一個(gè)月前我還...
    沈念sama閱讀 46,297評(píng)論 2 360
  • 正文 我出身青樓参淹,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親乏悄。 傳聞我的和親對(duì)象是個(gè)殘疾皇子承二,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,472評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容