精华内容
下载资源
问答
  • MTCNN中用celebA样本生成landmark训练样本python代码解读 2017年08月28日 17:36:32 XZZPPP 阅读数:1136更多 <div class="...

    MTCNN中用celebA样本生成landmark训练样本python代码解读

    最近跑通了MTCNN的训练代码,对其中生成positive,negative,part样本gen_48net_data2.py代码进行修改。

    项目地址:https://github.com/dlunion/mtcnn

    对应代码地址:https://github.com/dlunion/mtcnn/blob/master/train/gen_48net_data2.py


    修改后实现:用celebA样本生成MTCNN的landmark训练样本。

    标注文件格式如下:

    000001.jpg 138 70 343 330 165 184 244 176 196 249 194 271 266 260
    000002.jpg 105 107 295 362 140 204 220 204 168 254 146 289 226 289
    000003.jpg 205 50 267 173 244 104 264 105 263 121 235 134 251 140
    000004.jpg 505 172 1069 932 796 539 984 539 930 687 762 756 915 756
    000005.jpg 241 98 365 239 273 169 328 161 298 172 283 208 323 207
    000006.jpg 149 95 291 270 202 158 259 165 234 196 197 228 243 233
    000007.jpg 71 93 256 335 129 198 204 190 163 242 140 277 202 271
    

    第1列表示: 图片名;

    第2-5列表示:标注的人脸bbox位置, x1,y1,x2,y2;

    第6-15列表示:标注的landmark位置,  ptx0,pty0,ptx1,pty1,ptx2,pty2,ptx3,pty3,ptx4,pty4;


    主要思路:在bbox基础上,随机扰动生成很多bbox,当且仅当五个landmark都在随机扰动生成的crop区域中时,认为是符合要求的landmark训练样本。   代码如下:


    import sys
    sys.path.append('D:\\Anaconda2\\libs')  #导入系统路径,以便cv2模块的导入
    

    import numpy as np
    import cv2
    import os
    import numpy.random as npr
    from utils import IoU

    stdsize = 48

    标注txt文件路径,celebA原图路径

    anno_file = “E:/face_alignment/data/CelebA/Anno/celebA_bbox_landmark.txt”
    im_dir = “E:/face_alignment/data/CelebA/Img/img_celeba.7z/img_celeba/”

    landmark样本的保存路径

    pos_save_dir = str(stdsize) + “/landmark”
    save_dir = “./” + str(stdsize)

    创建文件夹函数

    def mkr(dr):
    if not os.path.exists(dr):
    os.mkdir(dr)

    mkr(save_dir)
    mkr(pos_save_dir)

    f1 = open(os.path.join(save_dir, ‘landmark_’ + str(stdsize) + ‘.txt’), ‘w’)
    with open(anno_file, ‘r’) as f:
    annotations = f.readlines()
    num = len(annotations)
    print “%d pics in total” % num
    p_idx = 0 # positive
    d_idx = 0 # dont care
    idx = 0
    box_idx = 0

    for annotation in annotations:
    # strip():去除annotations开头、结尾处空白符,split(’ ‘)按空格进行切片
    annotation = annotation.strip().split(’ ')
    im_path = annotation[0] # 图片名
    bbox = map(float, annotation[1:-10]) # bbox 坐标
    pts = map(float, annotation[-10:]) # landmark 坐标
    boxes = np.array(bbox, dtype=np.float32).reshape(-1, 4) # 将bbox转化为矩阵,并将列resize为4
    im_path = im_dir + im_path # 图片全路径
    img = cv2.imread(im_path) # 读取图片
    idx += 1
    if idx % 100 == 0:
    print idx, “images done”

    height, width, channel = img.shape
    
    
    backupPts = pts[:]        
    for box in boxes:
        # box (x_left, y_top, x_right, y_bottom)
        x1, y1, x2, y2 = box
        w = x2 - x1 + 1
        h = y2 - y1 + 1
    
        # ignore small faces
        # in case the ground truth boxes of small faces are not accurate
        if max(w, h) < 12 or x1 < 0 or y1 < 0:
            continue
    
        # generate landmark examples and part faces
    	# 对bbox进行随机scale,offset,得到新的crop区域,即对样本进行扰动,做样本增强
        for i in range(10):
            pts = backupPts[:]
            size = npr.randint(int(min(w, h) * 0.9), np.ceil(1.1 * max(w, h)))
            # scale做(0.9~1.1)之间扰动,offser做(-0.1~0.1)之间扰动
            # delta here is the offset of box center
            delta_x = npr.randint(-w * 0.1, w * 0.1)
            delta_y = npr.randint(-h * 0.1, h * 0.1)
    
            nx1 = max(x1 + w / 2 + delta_x - size / 2, 0)
            ny1 = max(y1 + h / 2 + delta_y - size / 2, 0)
            nx2 = nx1 + size
            ny2 = ny1 + size
    
            if nx2 > width or ny2 > height:
                continue
            crop_box = np.array([nx1, ny1, nx2, ny2])
    
            offset_x1 = (x1 - nx1) / float(size)
            offset_y1 = (y1 - ny1) / float(size)
            offset_x2 = (x2 - nx2) / float(size)
            offset_y2 = (y2 - ny2) / float(size)
    
    		# 当且仅当五个landmark都在随机扰动生成的crop区域中时,才保持使用
            if pts[0] < nx1 or pts[0] > nx2:
                continue
            if pts[2] < nx1 or pts[2] > nx2:
                continue
            if pts[4] < nx1 or pts[4] > nx2:
                continue
            if pts[6] < nx1 or pts[6] > nx2:
                continue
            if pts[8] < nx1 or pts[8] > nx2:
                continue
    		
            if pts[1] < ny1 or pts[1] > ny2:
                continue
            if pts[3] < ny1 or pts[3] > ny2:
                continue
            if pts[5] < ny1 or pts[5] > ny2:
                continue
            if pts[7] < ny1 or pts[7] > ny2:
                continue
            if pts[9] < ny1 or pts[9] > ny2:
                continue
    		
            ptss = pts[:]
    		# 将landmark转化为相对于左上角的归一化值
            for k in range(len(ptss) / 2):
                pts[k] = (ptss[k*2] - nx1) / float(size);
                pts[k+5] = (ptss[k*2+1] - ny1) / float(size);
    
    		# 从原图中crop图片区域,并resize成stdsize大小
            cropped_im = img[int(ny1) : int(ny2), int(nx1) : int(nx2), :]
            resized_im = cv2.resize(cropped_im, (stdsize, stdsize), interpolation=cv2.INTER_LINEAR)
    
            box_ = box.reshape(1, -1)
    
    		# 将图片名,bbox偏移量写入txt文本中
            save_file = os.path.join(pos_save_dir, "%s.jpg"%p_idx)
            f1.write(str(stdsize)+"/landmark/%s.jpg"%p_idx + ' -1 -1 -1 -1 -1')
             
    		# 将landmark坐标写入txt文件中
            for k in range(len(pts)):
                f1.write(" %f" % pts[k])
            f1.write("\n")
            cv2.imwrite(save_file, resized_im)  # 保存图片
            p_idx += 1
    		
    
        box_idx += 1
        print "%s images done, pos: %s part: %s "%(idx, p_idx, d_idx)
    

    f1.close()



    得到的效果图如下:





    展开全文
  • 为了验证我们训练MTCNN的O-Net在训练集上的表现,我们写了一个测试代码,来测试训练图片的landmark的mean error。 landmark标签格式如下所示: 48/landmark/0.jpg -1 -1 -1 -1 -1 0.224199 0.505338 0.334520 0....

    为了验证我们训练的MTCNN的O-Net在训练集上的表现,我们写了一个测试代码,来测试训练图片的landmark的mean error。

    landmark标签格式如下所示:

    48/landmark/0.jpg -1 -1 -1 -1 -1 0.224199 0.505338 0.334520 0.327402 0.583630 0.364769 0.336299 0.596085 0.674377 0.635231
    48/landmark/1.jpg -1 -1 -1 -1 -1 0.494662 0.775801 0.665480 0.416370 0.672598 0.336299 0.364769 0.596085 0.635231 0.674377
    48/landmark/2.jpg -1 -1 -1 -1 -1 0.283217 0.559441 0.391608 0.384615 0.636364 0.435315 0.407343 0.662587 0.739510 0.701049
    48/landmark/3.jpg -1 -1 -1 -1 -1 0.440559 0.716783 0.608392 0.363636 0.615385 0.407343 0.435315 0.662587 0.701049 0.739510
    48/landmark/4.jpg -1 -1 -1 -1 -1 0.153846 0.457692 0.273077 0.265385 0.542308 0.505769 0.475000 0.755769 0.840385 0.798077
    48/landmark/5.jpg -1 -1 -1 -1 -1 0.542308 0.846154 0.726923 0.457692 0.734615 0.475000 0.505769 0.755769 0.798077 0.840385
    48/landmark/6.jpg -1 -1 -1 -1 -1 0.110092 0.472477 0.252294 0.243119 0.573394 0.392202 0.355505 0.690367 0.791284 0.740826
    48/landmark/7.jpg -1 -1 -1 -1 -1 0.527523 0.889908 0.747706 0.426606 0.756881 0.355505 0.392202 0.690367 0.740826 0.791284
    


    第1列表示:图片名;

    第2列表示:是不是人脸,是人脸为1,不是人脸为0, ignore为-1;

    第3-6列表示: 人脸的标签,即人脸相对于ground truch人脸左上角的偏移量;

    第7-16列表示:  人脸landmark标签,即人脸相对于crop区域的归一化量。


    训练样本如下图所示:

                        


    将48*48的训练样本输入到O-Net中,预测landmark位置,  测试代码如下所示:


    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    
    import sys
    sys.path.append('D:\\Anaconda2\\libs')
    
    import _init_paths
    import caffe
    import cv2
    import math
    import numpy as np
    # from python_wrapper import *
    import os
    
    # 计算pts_gt, pts_pre的mean error
    def computer_meanerror(pts_gt, pts_pre):
        mean_error = []
        d_outer = math.sqrt((pts_gt[2] - pts_gt[0]) * (pts_gt[2] - pts_gt[0]) + (pts_gt[3] - pts_gt[1]) * (pts_gt[3] - pts_gt[1]))
    
        for j in range(5):
            error = math.sqrt((pts_gt[2 * j] - pts_pre[2 * j]) * (pts_gt[2 * j] - pts_pre[2 * j]) + (pts_gt[2 * j + 1] - pts_pre[2 * j + 1]) * (pts_gt[2 * j + 1] - pts_pre[2 * j + 1]))
            error = error / d_outer
            mean_error.append(error)
    
        return mean_error
    
    # 画关键点
    def drawlandmark(im, points):
        for i in range(points.shape[0]):
            for j in range(5):
                cv2.circle(im, (int(points[i][j]), int(points[i][j + 5])), 2, (255, 0, 0), -1)
        return im
    
    # landmark检测程序
    def detect_face(img, ONet):
        # 定义temping数据格式和blob相同,即: num*channel*height*width
        temping = np.zeros((1, 48, 48, 3))
        temping[0,:,:,:] = img
        tempimg = (temping - 127.5) * 0.0078125  # [0,255] -> [-1,1] , 归一化
    
    	# 对temping做轴变换,opencv读取img格式为:height*width*channel,变换后变为*channel*height*width
        tempimg = np.swapaxes(tempimg, 1, 3)
        tempimg = np.swapaxes(tempimg, 2, 3)
    
        ONet.blobs['data'].reshape(1, 3, 48, 48)
        ONet.blobs['data'].data[...] = tempimg
        out = ONet.forward()
    
        score = out['prob1'][:, 1]    # 预测得分
        points = out['conv6-3']       # landmark预测偏移量
    
        point = []
        for i in range(5):
            point.append( points[0][i] * 48 )
            point.append( points[0][i+5] * 48 )
    
        point = np.array(point)
    
        return point
    
    
    
    
    
    # 判断这是否为一个主程序,其他python程序无法调用
    if __name__ == '__main__':
    
        infile_list = open('C:/mtcnn/48/landmark_48_1000.txt', 'r')
        img_dir = "C:/mtcnn/"
    
        caffe_model_path = "E:/mtcnn_DuinoDu/model"
    
        threshold = [0.6, 0.7, 0.7]
    
        caffe.set_mode_gpu()
        # ONet = caffe.Net(caffe_model_path+"/det3.prototxt", caffe_model_path+"/48net_v5_7.caffemodel", caffe.TEST)
        ONet = caffe.Net(caffe_model_path + "/det3.prototxt", "C:/mtcnn/train_V11_64/models_48_31" + "/_iter_140000.caffemodel", caffe.TEST)
    
    
        landmark_num = 0
        landmark_pos = 0
        mean_error = [0, 0, 0, 0, 0]
        mean_error = np.array(mean_error)
    
        for name_list in infile_list.readlines():
    
            landmark_num = landmark_num + 1
            print landmark_num
    
            align_gt = []      # landmark真实坐标位置
            # align_pre = []
            name_list = name_list.strip().split(' ')
            image_name = img_dir = "C:/mtcnn/" + name_list[0]
            img = cv2.imread(image_name)
    
            for i in range(5):
                align_gt.append(float(name_list[i + 6]))
                align_gt.append(float(name_list[i + 11]))
            align_gt = np.array(align_gt)
    
    		# 标签是相对于48*48的crop图像的归一化位置,进行反变换得到真实位置
            for j in range(10):
                align_gt[j] = align_gt[j] * 48
    
            # forward fitch key point
            align_pre = detect_face(img, ONet)     # 预测的landmark坐标位置
    
            #for i in range(5):
            #    cv2.circle(img, (int(align_gt[i]), int(align_gt[i+1])), 2, (255,0,0), -1)
            cv2.circle(img, (int(align_pre[0]), int(align_pre[1])), 2, (255, 0, 0), -1)
            cv2.circle(img, (int(align_pre[2]), int(align_pre[3])), 2, (255, 0, 0), -1)
            cv2.circle(img, (int(align_pre[4]), int(align_pre[5])), 2, (255, 0, 0), -1)
            cv2.circle(img, (int(align_pre[6]), int(align_pre[7])), 2, (255, 0, 0), -1)
            cv2.circle(img, (int(align_pre[8]), int(align_pre[9])), 2, (255, 0, 0), -1)
    
            #cv2.imshow("image",  img)
            #cv2.waitKey(1000)
    
            error = []
    		# 计算landmark的 mean error
            error = computer_meanerror(align_gt, align_pre)
            error = np.array(error)
            mean_error = mean_error + error
            landmark_pos = landmark_pos + 1
    
    
        mean_error = mean_error / float(landmark_pos)
        print "left eye mean error:", mean_error[0]
        print "right eye mean error:" , mean_error[1]
        print "nose mean error:" , mean_error[2]
        print "left mouth mean error:" , mean_error[3]
        print "right mouth mean error:" , mean_error[4]
        print  "eye and mouth mean error:" ,(mean_error[0] + mean_error[1] + mean_error[3] + mean_error[4] ) / 4.0
    
        infile_list.close()
    

     

    顺便说一句:linux上pycaffe的测试代码,可以直接移植到windows上,只要将对应平台依赖的库替换即可,代码不需要修改。




    展开全文
  • mtcnn

    2018-10-17 10:15:58
    mtcnn caffe 下的代码,是总共有三组数据,分别对应三种任务的单独训练,数据不交叉,训练随机进行3中任务号,中的一个,进行训练,每个任务都会被训练到。分类任务的batch,是pos 和neg 数据, 框的任务batch是,...
    1. mtcnn caffe 下的代码,是总共有三组数据,分别对应三种任务的单独训练,数据不交叉,训练随机进行3中任务号,中的一个,进行训练,每个任务都会被训练到。分类任务的batch,是pos 和neg 数据, 框的任务batch是,part pos 数据,关键点坐标,用的是landmark,制作的数据
    2. 方法2,训练,把训练样本直接按照3:1:1:2的方制作成一个数据,一个batchsize 包含4种数据,没有三种任务轮流训练,只有一个任务,同时训练三种,损失值是按照权重相加。
    展开全文
  • 想用mtcnn训练关键点检测,不用bbox的训练。由于手中只有关键点的数据集图片跟标签,所以就想只训练landmark而不训练boundingbox。之前看了一下网络结构天真的以为可以暴力裁剪一下,只训练ONet就行了,结果发现...

    想用mtcnn来训练关键点检测,不用bbox的训练。由于手中只有关键点的数据集图片跟标签,所以就想只训练landmark而不训练boundingbox。之前看了一下网络结构天真的以为可以暴力裁剪一下,只训练ONet就行了,结果发现无论如何都跑不起来,我认为还是必须要有P跟RNet的二分类和边框回归才行……那请问一下这个该怎么办呢?没有边框检测训练数据的前提下无法训练P跟R网络,如何得到landmark训练需要的那些前置参数?

            ----  by  jhgfkdj  

     

    关键点的计算是来自用bbox的范围的二次计算吧?

     

     

     

     

     

     

    展开全文
  • MTCNN训练GitHub: MTCNNpaper: 下载数据集 wider face数据集下载→wider face该数据集包含32,203 images and ...landmark数据集下载→landmark训练数据该数据有训练和测试两个数据集,其中训练数据有10000张...
  • 本代码基于作者提供的python版本代码修改,参考: https://github.com/DuinoDu/mtcnn/blob/master/demo.py  (作者提供) ...https://github.com/dlunion/mtcnn/blob/master/train/gen_...
  • from tensorflow.python import pywrap_tensorflow import numpy as np #PNet RNet还有ONet模型文件...reader=pywrap_tensorflow.NewCheckpointReader('/mnt/F/lwr/MTCNN/data/MTCNN_model/PNet_landmark/PNet-30')...
  • WIDER Facefor face detection andCelebafor landmark detection WIDER Face 总共62个场景的文件夹,每个文件夹中多张图片 文件中保存的是每个图片中所有人脸框的位置,表示意义如下: Cel...
  • 我在用模型只训练landmark,任务,的话,用提供的标签的框,做测试还原关键点坐标,挺好的,但是增加关键点到13个眼睛密集处的地方效果不好,没有太分开,用同样的数据集,找了一个新的模型进行训练,也只是训练关键...
  • MTCNN总结

    千次阅读 2019-07-21 12:29:38
    该算法训练数据来源于wider和celeba两个公开的数据库,wider提供人脸检测数据,在图上标注了人脸框groundtruth的坐标信息,celeba提供了5个landmark点的数据。 1、数据来源 人脸数据集widerface,仅提供了大量的...
  • import numpy as np import os from tool.utils import IouDo from PIL import Image, ImageFilter from PIL import ImageDraw img_path = r"D:\CelebA\img_celeba...label_landmark_path = r"D:\BaiduNetdiskDownl...
  • 这篇博客主要分析PNet的数据准备和训练 从下面几个文件入手: Run prepare_data/gen_12net_data.py Run gen_landmark_aug_12.py Run gen_imglist_pnet.py Run gen_PNet_tfrecords.py 首先分析 gen_12net_data.py 这个...
  • MTCNN-Tensorflow

    千次阅读 2018-11-01 18:10:30
    mtcnn为一个多任务训练,物体框和特征点数据分别为两个数据集, 数据集1标记里物体框位置,因此只用与训练物体检测。 数据集2标记有物体框,特征点,用于训练特征点。 输入数据每行分别为, path to image, cls_...
  • 上一篇博客是对于landmark数据集的操作,这篇博客我们要对两部份的训练数据进行合并。 1 训练数据进行合并 进入prepare_data文件夹打开gen_imglist_pnet.py import numpy as np import numpy.random as npr import ...
  • 训练mtcnn的数据集论文里使用的是WIDER FACE 和CelebA,其中WIDER FACE用作回归人脸分类和box,CelebA用来回归关键点(landmark) 人脸数据集特点 训练数据集里面分为 negatives, positives, part face。 negatives...
  • gen_landmark_aug_12.py生成用于PNet网络的训练数据(用于人脸特征点)。此外对于RNet,ONet(用于人脸特征点)的训练数据生成与其类似,不再赘述。 主函数: if __name__ == '__main__': dstdir = "../../DATA/...
  • tfrecords文件存放在文件"../../DATA/imglists/PNet/train_PNet_landmark.tfrecord_shuffle中,接下来用它来训练PNet网络,即文件train_PNet.py; def train_PNet(base_dir, prefix, end_epoch, display, lr): ""...
  • 上篇博客讲述了在训练caffe模型时,生成了3个txt文件,再分成训练集和验证集后要生成整体的train/val.txt,该py文件将整理好train与valid。默认比例是pos:neg:part:landmark为1:3:1:0 #!/usr/bin/env python "...
  • 1 训练PNet的数据的采样代码 上一篇博客是生成P_Net...进入prepare_data文件夹打开gen_landmark_aug_12,代码如下: # coding: utf-8 import os import random from os.path import join, exists import cv2 import...
  • 进入prepare_data文件夹打开gen_hard_example.py脚本,该脚本既可用于生成RNet,也可用于ONet,只要把主函数中:...至于landmark样本,由gen_landmark_aug_24.py和gen_landmark_aug_48.py脚本生成 gen_hard_e...
  • landmark问题

    2020-12-01 22:43:24
    <div><p>如果我不做landmark的学习,,可不可以不生成landmark.tfrecords?能否只生成pos,neg,part的tfrecords做训练。如果可以,应该怎么修改训练部分&...AITTSMD/MTCNN-Tensorflow</p></div>
  • MTCNN--Pnet--decode

    2019-11-24 11:54:55
    现在我们记录下如何在训练好P_net模型后,来把网络输出decode出人脸框的坐标,坐标偏移...输出为(height_,width_,2) (height_,width_,4)暂时先不考虑landmark的输出 由于整个P_net为fcn,所以height_和width_的大小...
  • 对于PNet,运行gen_PNet_tfrecords.py一次,生成tfrecords文件存放在文件"../../DATA/imglists/PNet/train_PNet_landmark.tfrecord_shuffle中,用于训练PNet。 对于PNet,运行gen_RNet_tfrecords.py四次,生成neg,...
  • landmark相关问题?

    2020-12-02 11:26:01
    训练的效果有没有和mtcnn的对比过呢? 2、原始模型结构上是mobilenetv2,但是relu6替换成了relu,看你这边给出的backbone,用的relu6,有对比过二者在训练上的差别么</p><p>该提问来源于开源...
  • 数据来进行模型训练,原先5个关键点时landmark_loss的曲线会衰减收敛,但是64个关键点时landmark_loss的曲线只会上下浮动不衰减。想请问这可能是由于什么情况引起?谢谢!!!...
  • 使用基于坐标或基于热图的回归方法对模型进行了训练。 支持不同的面部检测器。 这里显示了和结果。 支持68点和39点界标推断。 支持自动对齐和裁剪 支持不同的骨干网和面部检测器。 支持ONNX和OpenVINO推断。 ...
  • <div><p>运行train.py训练ONet,循环617次出现错误tf.errors.OutOfRangeError 测试后发现,错误出现在读取TFRecords文件 image_batch_array, label_batch_array, bbox_batch_array,landmark_batch_array...
  • ./data/MTCNN_model/PNet_landmark (256, 24, 24, 3) (256, 22, 22, 28) (256, 11, 11, 28) (256, 9, 9, 48) (256, 4, 4, 48) (256, 3, 3, 64) (256, 576) (256, 128) (256, 2) (256, 4) (256, 10) 0 images done [0...

空空如也

空空如也

1 2
收藏数 37
精华内容 14
关键字:

landmark训练mtcnn