mtCNN_sysu / get_data.py
Enderfga's picture
Add application file
7652882
raw history blame
No virus
32.2 kB
import sys
import numpy as np
import cv2
import os
from utils.tool import IoU,convert_to_square
import numpy.random as npr
import argparse
from utils.detect import MtcnnDetector, create_mtcnn_net
from utils.dataloader import ImageDB,TestImageLoader
import time
from six.moves import cPickle
import utils.config as config
import utils.vision as vision
sys.path.append(os.getcwd())
txt_from_path = './data_set/wider_face_train_bbx_gt.txt'
anno_file = os.path.join(config.ANNO_STORE_DIR, 'anno_train.txt')
# anno_file = './anno_store/anno_train.txt'
prefix = ''
use_cuda = True
im_dir = "./data_set/face_detection/WIDER_train/images/"
traindata_store = './data_set/train/'
prefix_path = "./data_set/face_detection/WIDER_train/images/"
annotation_file = './anno_store/anno_train.txt'
prefix_path_lm = ''
annotation_file_lm = "./data_set/face_landmark/CNN_FacePoint/train/trainImageList.txt"
# ----------------------------------------------------other----------------------------------------------
pos_save_dir = "./data_set/train/12/positive"
part_save_dir = "./data_set/train/12/part"
neg_save_dir = './data_set/train/12/negative'
pnet_postive_file = os.path.join(config.ANNO_STORE_DIR, 'pos_12.txt')
pnet_part_file = os.path.join(config.ANNO_STORE_DIR, 'part_12.txt')
pnet_neg_file = os.path.join(config.ANNO_STORE_DIR, 'neg_12.txt')
imglist_filename_pnet = os.path.join(config.ANNO_STORE_DIR, 'imglist_anno_12.txt')
# ----------------------------------------------------PNet----------------------------------------------
rnet_postive_file = os.path.join(config.ANNO_STORE_DIR, 'pos_24.txt')
rnet_part_file = os.path.join(config.ANNO_STORE_DIR, 'part_24.txt')
rnet_neg_file = os.path.join(config.ANNO_STORE_DIR, 'neg_24.txt')
rnet_landmark_file = os.path.join(config.ANNO_STORE_DIR, 'landmark_24.txt')
imglist_filename_rnet = os.path.join(config.ANNO_STORE_DIR, 'imglist_anno_24.txt')
# ----------------------------------------------------RNet----------------------------------------------
onet_postive_file = os.path.join(config.ANNO_STORE_DIR, 'pos_48.txt')
onet_part_file = os.path.join(config.ANNO_STORE_DIR, 'part_48.txt')
onet_neg_file = os.path.join(config.ANNO_STORE_DIR, 'neg_48.txt')
onet_landmark_file = os.path.join(config.ANNO_STORE_DIR, 'landmark_48.txt')
imglist_filename_onet = os.path.join(config.ANNO_STORE_DIR, 'imglist_anno_48.txt')
# ----------------------------------------------------ONet----------------------------------------------
def assemble_data(output_file, anno_file_list=[]):
#assemble the pos, neg, part annotations to one file
size = 12
if len(anno_file_list)==0:
return 0
if os.path.exists(output_file):
os.remove(output_file)
for anno_file in anno_file_list:
with open(anno_file, 'r') as f:
print(anno_file)
anno_lines = f.readlines()
base_num = 250000
if len(anno_lines) > base_num * 3:
idx_keep = npr.choice(len(anno_lines), size=base_num * 3, replace=True)
elif len(anno_lines) > 100000:
idx_keep = npr.choice(len(anno_lines), size=len(anno_lines), replace=True)
else:
idx_keep = np.arange(len(anno_lines))
np.random.shuffle(idx_keep)
chose_count = 0
with open(output_file, 'a+') as f:
for idx in idx_keep:
# write lables of pos, neg, part images
f.write(anno_lines[idx])
chose_count+=1
return chose_count
def wider_face(txt_from_path, txt_to_path):
line_from_count = 0
with open(txt_from_path, 'r') as f:
annotations = f.readlines()
with open(txt_to_path, 'w+') as f:
while line_from_count < len(annotations):
if annotations[line_from_count][2]=='-':
img_name = annotations[line_from_count][:-1]
line_from_count += 1 # change line to read the number
bbox_count = int(annotations[line_from_count]) # num of bboxes
line_from_count += 1 # change line to read the posession
for _ in range(bbox_count):
bbox = list(map(int,annotations[line_from_count].split()[:4])) # give a loop to append all the boxes
bbox = [bbox[0], bbox[1], bbox[0]+bbox[2], bbox[1]+bbox[3]] # make x1, y1, w, h --> x1, y1, x2, y2
bbox = list(map(str,bbox))
img_name += (' '+' '.join(bbox))
line_from_count+=1
f.write(img_name +'\n')
else: # dectect the file name
line_from_count+=1
# ----------------------------------------------------origin----------------------------------------------
def get_Pnet_data():
if not os.path.exists(pos_save_dir):
os.makedirs(pos_save_dir)
if not os.path.exists(part_save_dir):
os.makedirs(part_save_dir)
if not os.path.exists(neg_save_dir):
os.makedirs(neg_save_dir)
f1 = open(os.path.join('./anno_store', 'pos_12.txt'), 'w')
f2 = open(os.path.join('./anno_store', 'neg_12.txt'), 'w')
f3 = open(os.path.join('./anno_store', 'part_12.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
n_idx = 0 # negative
d_idx = 0 # dont care
idx = 0
box_idx = 0
for annotation in annotations:
annotation = annotation.strip().split(' ')
# annotation[0]文件名
im_path = os.path.join(im_dir, annotation[0])
# print(im_path)
# print(os.path.exists(im_path))
bbox = list(map(float, annotation[1:]))
# annotation[1:]人脸坐标,一张脸4个值,对应两个点的坐标
boxes = np.array(bbox, dtype=np.int32).reshape(-1, 4)
# -1处的值为人脸数目
if boxes.shape[0]==0:
continue
# 若无人脸则跳过本次循环
img = cv2.imread(im_path)
# print(img.shape)
# exit()
# 计数
idx += 1
if idx % 100 == 0:
print("%s images done, pos: %s part: %s neg: %s" % (idx, p_idx, d_idx, n_idx))
# 图片三通道
height, width, channel = img.shape
neg_num = 0
# 取50次不同的框
while neg_num < 50:
size = np.random.randint(12, min(width, height) / 2)
nx = np.random.randint(0, width - size)
ny = np.random.randint(0, height - size)
crop_box = np.array([nx, ny, nx + size, ny + size])
Iou = IoU(crop_box, boxes) # IoU为 重合部分 / 两框之和 ,越大越好
cropped_im = img[ny: ny + size, nx: nx + size, :] # 裁去多余部分并resize成 12*12
resized_im = cv2.resize(cropped_im, (12, 12), interpolation=cv2.INTER_LINEAR)
if np.max(Iou) < 0.3:
# Iou with all gts must below 0.3
save_file = os.path.join(neg_save_dir, "%s.jpg" % n_idx)
f2.write(save_file + ' 0\n')
cv2.imwrite(save_file, resized_im)
n_idx += 1
neg_num += 1
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
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) < 40 or x1 < 0 or y1 < 0:
continue
if w < 12 or h < 12:
continue
# generate negative examples that have overlap with gt
for i in range(5):
size = np.random.randint(12, min(width, height) / 2)
# delta_x and delta_y are offsets of (x1, y1)
delta_x = np.random.randint(max(-size, -x1), w)
delta_y = np.random.randint(max(-size, -y1), h)
nx1 = max(0, x1 + delta_x)
ny1 = max(0, y1 + delta_y)
if nx1 + size > width or ny1 + size > height:
continue
crop_box = np.array([nx1, ny1, nx1 + size, ny1 + size])
Iou = IoU(crop_box, boxes)
cropped_im = img[ny1: ny1 + size, nx1: nx1 + size, :]
resized_im = cv2.resize(cropped_im, (12, 12), interpolation=cv2.INTER_LINEAR)
if np.max(Iou) < 0.3:
# Iou with all gts must below 0.3
save_file = os.path.join(neg_save_dir, "%s.jpg" % n_idx)
f2.write(save_file + ' 0\n')
cv2.imwrite(save_file, resized_im)
n_idx += 1
# generate positive examples and part faces
for i in range(20):
size = np.random.randint(int(min(w, h) * 0.8), np.ceil(1.25 * max(w, h)))
# delta here is the offset of box center
delta_x = np.random.randint(-w * 0.2, w * 0.2)
delta_y = np.random.randint(-h * 0.2, h * 0.2)
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)
cropped_im = img[int(ny1): int(ny2), int(nx1): int(nx2), :]
resized_im = cv2.resize(cropped_im, (12, 12), interpolation=cv2.INTER_LINEAR)
box_ = box.reshape(1, -1)
if IoU(crop_box, box_) >= 0.65:
save_file = os.path.join(pos_save_dir, "%s.jpg" % p_idx)
f1.write(save_file + ' 1 %.2f %.2f %.2f %.2f\n' % (offset_x1, offset_y1, offset_x2, offset_y2))
cv2.imwrite(save_file, resized_im)
p_idx += 1
elif IoU(crop_box, box_) >= 0.4:
save_file = os.path.join(part_save_dir, "%s.jpg" % d_idx)
f3.write(save_file + ' -1 %.2f %.2f %.2f %.2f\n' % (offset_x1, offset_y1, offset_x2, offset_y2))
cv2.imwrite(save_file, resized_im)
d_idx += 1
box_idx += 1
#print("%s images done, pos: %s part: %s neg: %s" % (idx, p_idx, d_idx, n_idx))
f1.close()
f2.close()
f3.close()
def assembel_Pnet_data():
anno_list = []
anno_list.append(pnet_postive_file)
anno_list.append(pnet_part_file)
anno_list.append(pnet_neg_file)
# anno_list.append(pnet_landmark_file)
chose_count = assemble_data(imglist_filename_pnet ,anno_list)
print("PNet train annotation result file path:%s" % imglist_filename_pnet)
# -----------------------------------------------------------------------------------------------------------------------------------------------#
def gen_rnet_data(data_dir, anno_file, pnet_model_file, prefix_path='', use_cuda=True, vis=False):
"""
:param data_dir: train data
:param anno_file:
:param pnet_model_file:
:param prefix_path:
:param use_cuda:
:param vis:
:return:
"""
# load trained pnet model
pnet, _, _ = create_mtcnn_net(p_model_path = pnet_model_file, use_cuda = use_cuda)
mtcnn_detector = MtcnnDetector(pnet = pnet, min_face_size = 12)
# load original_anno_file, length = 12880
imagedb = ImageDB(anno_file, mode = "test", prefix_path = prefix_path)
imdb = imagedb.load_imdb()
image_reader = TestImageLoader(imdb, 1, False)
all_boxes = list()
batch_idx = 0
print('size:%d' %image_reader.size)
for databatch in image_reader:
if batch_idx % 100 == 0:
print ("%d images done" % batch_idx)
im = databatch
t = time.time()
# obtain boxes and aligned boxes
boxes, boxes_align = mtcnn_detector.detect_pnet(im=im)
if boxes_align is None:
all_boxes.append(np.array([]))
batch_idx += 1
continue
if vis:
rgb_im = cv2.cvtColor(np.asarray(im), cv2.COLOR_BGR2RGB)
vision.vis_two(rgb_im, boxes, boxes_align)
t1 = time.time() - t
print('cost time ',t1)
t = time.time()
all_boxes.append(boxes_align)
batch_idx += 1
# if batch_idx == 100:
# break
# print("shape of all boxes {0}".format(all_boxes))
# time.sleep(5)
# save_path = model_store_path()
# './model_store'
save_path = './model_store'
if not os.path.exists(save_path):
os.mkdir(save_path)
save_file = os.path.join(save_path, "detections_%d.pkl" % int(time.time()))
with open(save_file, 'wb') as f:
cPickle.dump(all_boxes, f, cPickle.HIGHEST_PROTOCOL)
# save_file = './model_store/detections_1588751332.pkl'
gen_rnet_sample_data(data_dir, anno_file, save_file, prefix_path)
def gen_rnet_sample_data(data_dir, anno_file, det_boxs_file, prefix_path):
"""
:param data_dir:
:param anno_file: original annotations file of wider face data
:param det_boxs_file: detection boxes file
:param prefix_path:
:return:
"""
neg_save_dir = os.path.join(data_dir, "24/negative")
pos_save_dir = os.path.join(data_dir, "24/positive")
part_save_dir = os.path.join(data_dir, "24/part")
for dir_path in [neg_save_dir, pos_save_dir, part_save_dir]:
# print(dir_path)
if not os.path.exists(dir_path):
os.makedirs(dir_path)
# load ground truth from annotation file
# format of each line: image/path [x1,y1,x2,y2] for each gt_box in this image
with open(anno_file, 'r') as f:
annotations = f.readlines()
image_size = 24
net = "rnet"
im_idx_list = list()
gt_boxes_list = list()
num_of_images = len(annotations)
print ("processing %d images in total" % num_of_images)
for annotation in annotations:
annotation = annotation.strip().split(' ')
im_idx = os.path.join(prefix_path, annotation[0])
# im_idx = annotation[0]
boxes = list(map(float, annotation[1:]))
boxes = np.array(boxes, dtype=np.float32).reshape(-1, 4)
im_idx_list.append(im_idx)
gt_boxes_list.append(boxes)
# './anno_store'
save_path = './anno_store'
if not os.path.exists(save_path):
os.makedirs(save_path)
f1 = open(os.path.join(save_path, 'pos_%d.txt' % image_size), 'w')
f2 = open(os.path.join(save_path, 'neg_%d.txt' % image_size), 'w')
f3 = open(os.path.join(save_path, 'part_%d.txt' % image_size), 'w')
# print(det_boxs_file)
det_handle = open(det_boxs_file, 'rb')
det_boxes = cPickle.load(det_handle)
# an image contain many boxes stored in an array
print(len(det_boxes), num_of_images)
# assert len(det_boxes) == num_of_images, "incorrect detections or ground truths"
# index of neg, pos and part face, used as their image names
n_idx = 0
p_idx = 0
d_idx = 0
image_done = 0
for im_idx, dets, gts in zip(im_idx_list, det_boxes, gt_boxes_list):
# if (im_idx+1) == 100:
# break
gts = np.array(gts, dtype=np.float32).reshape(-1, 4)
if gts.shape[0]==0:
continue
if image_done % 100 == 0:
print("%d images done" % image_done)
image_done += 1
if dets.shape[0] == 0:
continue
img = cv2.imread(im_idx)
# change to square
dets = convert_to_square(dets)
dets[:, 0:4] = np.round(dets[:, 0:4])
neg_num = 0
for box in dets:
x_left, y_top, x_right, y_bottom, _ = box.astype(int)
width = x_right - x_left + 1
height = y_bottom - y_top + 1
# ignore box that is too small or beyond image border
if width < 20 or x_left < 0 or y_top < 0 or x_right > img.shape[1] - 1 or y_bottom > img.shape[0] - 1:
continue
# compute intersection over union(IoU) between current box and all gt boxes
Iou = IoU(box, gts)
cropped_im = img[y_top:y_bottom + 1, x_left:x_right + 1, :]
resized_im = cv2.resize(cropped_im, (image_size, image_size),
interpolation=cv2.INTER_LINEAR)
# save negative images and write label
# Iou with all gts must below 0.3
if np.max(Iou) < 0.3 and neg_num < 60:
# save the examples
save_file = os.path.join(neg_save_dir, "%s.jpg" % n_idx)
# print(save_file)
f2.write(save_file + ' 0\n')
cv2.imwrite(save_file, resized_im)
n_idx += 1
neg_num += 1
else:
# find gt_box with the highest iou
idx = np.argmax(Iou)
assigned_gt = gts[idx]
x1, y1, x2, y2 = assigned_gt
# compute bbox reg label
offset_x1 = (x1 - x_left) / float(width)
offset_y1 = (y1 - y_top) / float(height)
offset_x2 = (x2 - x_right) / float(width)
offset_y2 = (y2 - y_bottom) / float(height)
# save positive and part-face images and write labels
if np.max(Iou) >= 0.65:
save_file = os.path.join(pos_save_dir, "%s.jpg" % p_idx)
f1.write(save_file + ' 1 %.2f %.2f %.2f %.2f\n' % (
offset_x1, offset_y1, offset_x2, offset_y2))
cv2.imwrite(save_file, resized_im)
p_idx += 1
elif np.max(Iou) >= 0.4:
save_file = os.path.join(part_save_dir, "%s.jpg" % d_idx)
f3.write(save_file + ' -1 %.2f %.2f %.2f %.2f\n' % (
offset_x1, offset_y1, offset_x2, offset_y2))
cv2.imwrite(save_file, resized_im)
d_idx += 1
f1.close()
f2.close()
f3.close()
def model_store_path():
return os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(__file__))))+"/model_store"
def get_Rnet_data(pnet_model):
gen_rnet_data(traindata_store, annotation_file, pnet_model_file = pnet_model, prefix_path = prefix_path, use_cuda = True)
def assembel_Rnet_data():
anno_list = []
anno_list.append(rnet_postive_file)
anno_list.append(rnet_part_file)
anno_list.append(rnet_neg_file)
# anno_list.append(pnet_landmark_file)
chose_count = assemble_data(imglist_filename_rnet ,anno_list)
print("RNet train annotation result file path:%s" % imglist_filename_rnet)
#-----------------------------------------------------------------------------------------------------------------------------------------------#
def gen_onet_data(data_dir, anno_file, pnet_model_file, rnet_model_file, prefix_path='', use_cuda=True, vis=False):
pnet, rnet, _ = create_mtcnn_net(p_model_path=pnet_model_file, r_model_path=rnet_model_file, use_cuda=use_cuda)
mtcnn_detector = MtcnnDetector(pnet=pnet, rnet=rnet, min_face_size=12)
imagedb = ImageDB(anno_file,mode="test",prefix_path=prefix_path)
imdb = imagedb.load_imdb()
image_reader = TestImageLoader(imdb,1,False)
all_boxes = list()
batch_idx = 0
print('size:%d' % image_reader.size)
for databatch in image_reader:
if batch_idx % 50 == 0:
print("%d images done" % batch_idx)
im = databatch
t = time.time()
# pnet detection = [x1, y1, x2, y2, score, reg]
p_boxes, p_boxes_align = mtcnn_detector.detect_pnet(im=im)
t0 = time.time() - t
t = time.time()
# rnet detection
boxes, boxes_align = mtcnn_detector.detect_rnet(im=im, dets=p_boxes_align)
t1 = time.time() - t
print('cost time pnet--',t0,' rnet--',t1)
t = time.time()
if boxes_align is None:
all_boxes.append(np.array([]))
batch_idx += 1
continue
if vis:
rgb_im = cv2.cvtColor(np.asarray(im), cv2.COLOR_BGR2RGB)
vision.vis_two(rgb_im, boxes, boxes_align)
all_boxes.append(boxes_align)
batch_idx += 1
save_path = './model_store'
if not os.path.exists(save_path):
os.mkdir(save_path)
save_file = os.path.join(save_path, "detections_%d.pkl" % int(time.time()))
with open(save_file, 'wb') as f:
cPickle.dump(all_boxes, f, cPickle.HIGHEST_PROTOCOL)
gen_onet_sample_data(data_dir,anno_file,save_file,prefix_path)
def gen_onet_sample_data(data_dir,anno_file,det_boxs_file,prefix):
neg_save_dir = os.path.join(data_dir, "48/negative")
pos_save_dir = os.path.join(data_dir, "48/positive")
part_save_dir = os.path.join(data_dir, "48/part")
for dir_path in [neg_save_dir, pos_save_dir, part_save_dir]:
if not os.path.exists(dir_path):
os.makedirs(dir_path)
# load ground truth from annotation file
# format of each line: image/path [x1,y1,x2,y2] for each gt_box in this image
with open(anno_file, 'r') as f:
annotations = f.readlines()
image_size = 48
net = "onet"
im_idx_list = list()
gt_boxes_list = list()
num_of_images = len(annotations)
print("processing %d images in total" % num_of_images)
for annotation in annotations:
annotation = annotation.strip().split(' ')
im_idx = os.path.join(prefix,annotation[0])
boxes = list(map(float, annotation[1:]))
boxes = np.array(boxes, dtype=np.float32).reshape(-1, 4)
im_idx_list.append(im_idx)
gt_boxes_list.append(boxes)
save_path = './anno_store'
if not os.path.exists(save_path):
os.makedirs(save_path)
f1 = open(os.path.join(save_path, 'pos_%d.txt' % image_size), 'w')
f2 = open(os.path.join(save_path, 'neg_%d.txt' % image_size), 'w')
f3 = open(os.path.join(save_path, 'part_%d.txt' % image_size), 'w')
det_handle = open(det_boxs_file, 'rb')
det_boxes = cPickle.load(det_handle)
print(len(det_boxes), num_of_images)
# assert len(det_boxes) == num_of_images, "incorrect detections or ground truths"
# index of neg, pos and part face, used as their image names
n_idx = 0
p_idx = 0
d_idx = 0
image_done = 0
for im_idx, dets, gts in zip(im_idx_list, det_boxes, gt_boxes_list):
if image_done % 100 == 0:
print("%d images done" % image_done)
image_done += 1
if gts.shape[0]==0:
continue
if dets.shape[0] == 0:
continue
img = cv2.imread(im_idx)
dets = convert_to_square(dets)
dets[:, 0:4] = np.round(dets[:, 0:4])
for box in dets:
x_left, y_top, x_right, y_bottom = box[0:4].astype(int)
width = x_right - x_left + 1
height = y_bottom - y_top + 1
# ignore box that is too small or beyond image border
if width < 20 or x_left < 0 or y_top < 0 or x_right > img.shape[1] - 1 or y_bottom > img.shape[0] - 1:
continue
# compute intersection over union(IoU) between current box and all gt boxes
Iou = IoU(box, gts)
cropped_im = img[y_top:y_bottom + 1, x_left:x_right + 1, :]
resized_im = cv2.resize(cropped_im, (image_size, image_size),
interpolation=cv2.INTER_LINEAR)
# save negative images and write label
if np.max(Iou) < 0.3:
# Iou with all gts must below 0.3
save_file = os.path.join(neg_save_dir, "%s.jpg" % n_idx)
f2.write(save_file + ' 0\n')
cv2.imwrite(save_file, resized_im)
n_idx += 1
else:
# find gt_box with the highest iou
idx = np.argmax(Iou)
assigned_gt = gts[idx]
x1, y1, x2, y2 = assigned_gt
# compute bbox reg label
offset_x1 = (x1 - x_left) / float(width)
offset_y1 = (y1 - y_top) / float(height)
offset_x2 = (x2 - x_right) / float(width)
offset_y2 = (y2 - y_bottom) / float(height)
# save positive and part-face images and write labels
if np.max(Iou) >= 0.65:
save_file = os.path.join(pos_save_dir, "%s.jpg" % p_idx)
f1.write(save_file + ' 1 %.2f %.2f %.2f %.2f\n' % (
offset_x1, offset_y1, offset_x2, offset_y2))
cv2.imwrite(save_file, resized_im)
p_idx += 1
elif np.max(Iou) >= 0.4:
save_file = os.path.join(part_save_dir, "%s.jpg" % d_idx)
f3.write(save_file + ' -1 %.2f %.2f %.2f %.2f\n' % (
offset_x1, offset_y1, offset_x2, offset_y2))
cv2.imwrite(save_file, resized_im)
d_idx += 1
f1.close()
f2.close()
f3.close()
def model_store_path():
return os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(__file__))))+"/model_store"
def get_Onet_data(pnet_model, rnet_model):
gen_onet_data(traindata_store, annotation_file, pnet_model_file = pnet_model, rnet_model_file = rnet_model,prefix_path=prefix_path,use_cuda = True, vis = False)
def assembel_Onet_data():
anno_list = []
anno_list.append(onet_postive_file)
anno_list.append(onet_part_file)
anno_list.append(onet_neg_file)
anno_list.append(onet_landmark_file)
chose_count = assemble_data(imglist_filename_onet ,anno_list)
print("ONet train annotation result file path:%s" % imglist_filename_onet)
def gen_landmark_48(anno_file, data_dir, prefix = ''):
size = 48
image_id = 0
landmark_imgs_save_dir = os.path.join(data_dir,"48/landmark")
if not os.path.exists(landmark_imgs_save_dir):
os.makedirs(landmark_imgs_save_dir)
anno_dir = './anno_store'
if not os.path.exists(anno_dir):
os.makedirs(anno_dir)
landmark_anno_filename = "landmark_48.txt"
save_landmark_anno = os.path.join(anno_dir,landmark_anno_filename)
# print(save_landmark_anno)
# time.sleep(5)
f = open(save_landmark_anno, 'w')
# dstdir = "train_landmark_few"
with open(anno_file, 'r') as f2:
annotations = f2.readlines()
num = len(annotations)
print("%d total images" % num)
l_idx =0
idx = 0
# image_path bbox landmark(5*2)
for annotation in annotations:
# print imgPath
annotation = annotation.strip().split(' ')
assert len(annotation)==15,"each line should have 15 element"
im_path = os.path.join('./data_set/face_landmark/CNN_FacePoint/train/',annotation[0].replace("\\", "/"))
gt_box = list(map(float, annotation[1:5]))
# gt_box = [gt_box[0], gt_box[2], gt_box[1], gt_box[3]]
gt_box = np.array(gt_box, dtype=np.int32)
landmark = list(map(float, annotation[5:]))
landmark = np.array(landmark, dtype=np.float)
img = cv2.imread(im_path)
# print(im_path)
assert (img is not None)
height, width, channel = img.shape
# crop_face = img[gt_box[1]:gt_box[3]+1, gt_box[0]:gt_box[2]+1]
# crop_face = cv2.resize(crop_face,(size,size))
idx = idx + 1
if idx % 100 == 0:
print("%d images done, landmark images: %d"%(idx,l_idx))
# print(im_path)
# print(gt_box)
x1, x2, y1, y2 = gt_box
gt_box[1] = y1
gt_box[2] = x2
# time.sleep(5)
# gt's width
w = x2 - x1 + 1
# gt's height
h = y2 - y1 + 1
if max(w, h) < 40 or x1 < 0 or y1 < 0:
continue
# random shift
for i in range(10):
bbox_size = np.random.randint(int(min(w, h) * 0.8), np.ceil(1.25 * max(w, h)))
delta_x = np.random.randint(-w * 0.2, w * 0.2)
delta_y = np.random.randint(-h * 0.2, h * 0.2)
nx1 = max(x1 + w / 2 - bbox_size / 2 + delta_x, 0)
ny1 = max(y1 + h / 2 - bbox_size / 2 + delta_y, 0)
nx2 = nx1 + bbox_size
ny2 = ny1 + bbox_size
if nx2 > width or ny2 > height:
continue
crop_box = np.array([nx1, ny1, nx2, ny2])
cropped_im = img[int(ny1):int(ny2) + 1, int(nx1):int(nx2) + 1, :]
resized_im = cv2.resize(cropped_im, (size, size),interpolation=cv2.INTER_LINEAR)
offset_x1 = (x1 - nx1) / float(bbox_size)
offset_y1 = (y1 - ny1) / float(bbox_size)
offset_x2 = (x2 - nx2) / float(bbox_size)
offset_y2 = (y2 - ny2) / float(bbox_size)
offset_left_eye_x = (landmark[0] - nx1) / float(bbox_size)
offset_left_eye_y = (landmark[1] - ny1) / float(bbox_size)
offset_right_eye_x = (landmark[2] - nx1) / float(bbox_size)
offset_right_eye_y = (landmark[3] - ny1) / float(bbox_size)
offset_nose_x = (landmark[4] - nx1) / float(bbox_size)
offset_nose_y = (landmark[5] - ny1) / float(bbox_size)
offset_left_mouth_x = (landmark[6] - nx1) / float(bbox_size)
offset_left_mouth_y = (landmark[7] - ny1) / float(bbox_size)
offset_right_mouth_x = (landmark[8] - nx1) / float(bbox_size)
offset_right_mouth_y = (landmark[9] - ny1) / float(bbox_size)
# cal iou
iou = IoU(crop_box.astype(np.float), np.expand_dims(gt_box.astype(np.float), 0))
# print(iou)
if iou > 0.65:
save_file = os.path.join(landmark_imgs_save_dir, "%s.jpg" % l_idx)
cv2.imwrite(save_file, resized_im)
f.write(save_file + ' -2 %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f \n' % \
(offset_x1, offset_y1, offset_x2, offset_y2, \
offset_left_eye_x,offset_left_eye_y,offset_right_eye_x,offset_right_eye_y,offset_nose_x,offset_nose_y,offset_left_mouth_x,offset_left_mouth_y,offset_right_mouth_x,offset_right_mouth_y))
# print(save_file)
# print(save_landmark_anno)
l_idx += 1
f.close()
def parse_args():
parser = argparse.ArgumentParser(description='Get data',
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument('--net', dest='net', help='which net to show', type=str)
parser.add_argument('--pnet_path', default="./model_store/pnet_epoch_20.pt",help='path to pnet model', type=str)
parser.add_argument('--rnet_path', default="./model_store/rnet_epoch_20.pt",help='path to rnet model', type=str)
parser.add_argument('--use_cuda', default=True,help='use cuda', type=bool)
args = parser.parse_args()
return args
#-----------------------------------------------------------------------------------------------------------------------------------------------#
if __name__ == '__main__':
args = parse_args()
dir = 'anno_store'
if not os.path.exists(dir):
os.makedirs(dir)
if args.net == "pnet":
wider_face(txt_from_path, anno_file)
get_Pnet_data()
assembel_Pnet_data()
elif args.net == "rnet":
get_Rnet_data(args.pnet_path)
assembel_Rnet_data()
elif args.net == "onet":
get_Onet_data(args.pnet_path, args.rnet_path)
gen_landmark_48(annotation_file_lm, traindata_store, prefix_path_lm)
assembel_Onet_data()