1
+ # coding: utf-8
2
+ """
3
+ 读取lfw net face 数据集
4
+ 生成正样本和负样本。
5
+ 正样本标签为:1
6
+ 负样本标签为:0
7
+ 部分人脸样本标签为:2
8
+ landmark样本:-1
9
+ 综合标签为: img_path xmin ymin xmax ymax landmark[10] label
10
+
11
+ 注意:保存的图片缩放到了12*12,bbox的坐标也是相对于12*12的
12
+ """
13
+ import sys
14
+ sys .path .append (sys .path [0 ] + "/../" )
15
+ import os
16
+ import numpy as np
17
+ import random
18
+ import cv2
19
+ from pylab import plt
20
+ from util .utility import *
21
+ from util .Logger import Logger
22
+ import time
23
+ import lmdb
24
+ if not os .path .exists ("./log" ):
25
+ os .mkdir ("./log" )
26
+ log = Logger ("./log/{}_{}.log" .format (__file__ .split ('/' )[- 1 ],
27
+ time .strftime ("%Y%m%d-%H%M%S" ), time .localtime ), level = 'debug' ).logger
28
+ # 小于该人脸的就不要了
29
+ # 太小的话,会有太多的误检
30
+ MIN_FACE_SIZE = 40
31
+ IOU_POS_THRES = 0.65
32
+ IOU_NEG_THRES = 0.3
33
+ IOU_PART_THRES = 0.4
34
+
35
+ ## 关键点样本个数
36
+ landmark_samples = 20
37
+
38
+ OUT_IMAGE_SIZE = 12
39
+
40
+ root_dir = r'../../dataset/LFW_NET_FACE'
41
+ root_dir = os .path .expanduser (root_dir )
42
+ output_root_dir = r"../../dataset/train_faces_p"
43
+ if not os .path .exists (output_root_dir ):
44
+ os .mkdir (output_root_dir )
45
+ output_landmark_dir = os .path .join (output_root_dir , "landmark" )
46
+ if not os .path .exists (output_landmark_dir ):
47
+ os .mkdir (output_landmark_dir )
48
+
49
+ LMDB_MAP_SIZE = 1099511627776
50
+ env_landmark_image = lmdb .open (os .path .join (output_landmark_dir , "image_landmark" ), map_size = LMDB_MAP_SIZE )
51
+ env_landmark_label = lmdb .open (os .path .join (output_landmark_dir , "label_landmark" ), map_size = LMDB_MAP_SIZE )
52
+ global_idx_landmark = 0
53
+ txn_landmark_image = env_landmark_image .begin (write = True )
54
+ txn_landmark_label = env_landmark_label .begin (write = True )
55
+
56
+ anno_file = os .path .join (root_dir , "trainImageList.txt" )
57
+
58
+ with open (anno_file , "r" ) as f :
59
+ inner_landmark_idx = 0
60
+ while True :
61
+ line = f .readline ()
62
+ if not line :
63
+ break
64
+ line_split = line .split ()
65
+ filename_split = line_split [0 ].split ("\\ " )
66
+ filename = os .path .join (filename_split [0 ],filename_split [1 ])
67
+ img = cv2 .imread (os .path .join (root_dir ,filename ))
68
+ if img is None :
69
+ log .warning ("error to load image {}" , filename )
70
+ continue
71
+ # 读取真值 bbox
72
+ H , W , C = img .shape
73
+ x = int (line_split [1 ])
74
+ x1 = int (line_split [2 ])
75
+ y = int (line_split [3 ])
76
+ y1 = int (line_split [4 ])
77
+ w = x1 - x
78
+ h = y1 - y
79
+ box = np .array ([x , y , w , h ])
80
+ for i in range (landmark_samples ):
81
+ size = random .randrange (int (np .min ((w ,h )) * 0.8 ), int (np .ceil (1.25 * np .max ((w ,h )))))
82
+ dx = random .randrange (int (- w * 0.2 ), int (w * 0.2 ))
83
+ dy = random .randrange (int (- h * 0.2 ), int (h * 0.2 ))
84
+ nx = np .max ((x + w / 2 + dx - size / 2 ), 0 )
85
+ ny = np .max ((y + h / 2 + dy - size / 2 ), 0 )
86
+ nx = int (nx )
87
+ ny = int (ny )
88
+ if nx < 0 :
89
+ nx = 0
90
+ if ny < 0 :
91
+ ny = 0
92
+ if nx + size > W or ny + size > H :
93
+ continue
94
+ if size < OUT_IMAGE_SIZE / 2 :
95
+ continue
96
+
97
+ #iou
98
+ crop_box = np .array ([nx , ny , size , size ])
99
+ iou = IOU (box , crop_box )
100
+ # log.info("{} {} {} {}".format(nx, ny, size, size))
101
+ crop = img [ny : ny + size , nx :nx + size ]
102
+ out = cv2 .resize (crop , (OUT_IMAGE_SIZE , OUT_IMAGE_SIZE ))
103
+ scalor = float (size ) / float (OUT_IMAGE_SIZE )
104
+ # ground truth 坐标变换
105
+ ## 变换到crop
106
+ ox = x - nx
107
+ oy = y - ny
108
+ ow = w
109
+ oh = h
110
+ # ## 变换到out
111
+ ox = ox / scalor
112
+ oy = oy / scalor
113
+ ow = ow / scalor
114
+ oh = oh / scalor
115
+ #关键点
116
+ landmarks = []
117
+ for i in range (5 ):
118
+ lx = int (float (line_split [5 + i * 2 ])) - nx
119
+ ly = int (float (line_split [5 + i * 2 + 1 ])) - ny
120
+ lx = lx / scalor
121
+ ly = ly / scalor
122
+ landmarks .append (lx )
123
+ landmarks .append (ly )
124
+ #
125
+ # # 这里保存成左上角点和右下角点
126
+ xmin = ox
127
+ ymin = oy
128
+ xmax = xmin + ow
129
+ ymax = ymin + oh
130
+ if iou > IOU_POS_THRES :
131
+ #### 正样本
132
+ #path_ = "/home/chengliu/MTCNN/mtcnn-pytorch/dataset/out_img/" + str(global_idx_landmark) + ".png"
133
+ #cv2.imwrite(path_,out)
134
+ label_list = [xmin , ymin , xmax , ymax ] + landmarks + [- 1 ]
135
+ label = np .array (label_list , dtype = np .float32 )
136
+ txn_landmark_image .put ("{}" .format (global_idx_landmark ).encode ("ascii" ), out .tostring ())
137
+ txn_landmark_label .put ("{}" .format (global_idx_landmark ).encode ("ascii" ), label .tostring ())
138
+ global_idx_landmark += 1
139
+ inner_landmark_idx += 1
140
+ log .info ("landmark num: {}" .format (global_idx_landmark ))
141
+ if inner_landmark_idx > 1000 :
142
+ txn_landmark_image .commit ()
143
+ txn_landmark_label .commit ()
144
+ txn_landmark_image = env_landmark_image .begin (write = True )
145
+ txn_landmark_label = env_landmark_label .begin (write = True )
146
+ inner_landmark_idx = 0
147
+ log .info ("now commit landmark lmdb" )
148
+ log .info ("process done!" )
149
+ txn_landmark_image .commit ()
150
+ txn_landmark_label .commit ()
0 commit comments