def build_dataset(path_list, box_path_list, is_train=True): filenames = [] landmarks = [] faceboxes = [] for i in range(len(path_list)): filenames_dir = glob.glob(path_list[i] + "*.jpg") filenames_dir += glob.glob(path_list[i] + "*.png") box_dict = pickle.load(open(box_path_list[i], 'rb')) for j in range(len(filenames_dir)): filenames.append(filenames_dir[j]) pts_filename = filenames_dir[j][:-3] + "pts" landmarks.append(loadFromPts(pts_filename)) basename = os.path.basename(filenames_dir[j]) faceboxes.append(box_dict[basename]) if is_train: with open('data/train_filenames.pkl', 'wb') as f: pickle.dump(filenames, f, pickle.HIGHEST_PROTOCOL) with open('data/train_faceboxes.pkl', 'wb') as f: pickle.dump(faceboxes, f, pickle.HIGHEST_PROTOCOL) with open('data/train_landmarks.pkl', 'wb') as f: pickle.dump(landmarks, f, pickle.HIGHEST_PROTOCOL) else: with open('data/valid_filenames.pkl', 'wb') as f: pickle.dump(filenames, f, pickle.HIGHEST_PROTOCOL) with open('data/valid_faceboxes.pkl', 'wb') as f: pickle.dump(faceboxes, f, pickle.HIGHEST_PROTOCOL) with open('data/valid_landmarks.pkl', 'wb') as f: pickle.dump(landmarks, f, pickle.HIGHEST_PROTOCOL)
def PrepareData(self, imageDirs, boundingBoxFiles, meanShape, startIdx, nImgs, mirrorFlag): filenames = [] # pic文件名list landmarks = [] # 坐标点文件名list boundingBoxes = [] for i in range(len(imageDirs)): # 训练数据来自lfpw,helen,afw这3个数据集,文件夹长度为3。 filenamesInDir = glob.glob(imageDirs[i] + "*.jpg") filenamesInDir += glob.glob( imageDirs[i] + "*.png" ) # 打开第一个文件夹的所有jpg和png图片,文件路径 '../data/images/lfpw/trainset\\image_0020.png' if boundingBoxFiles is not None: # boundingBoxDict = pickle.load(open(boundingBoxFiles[i], 'rb'), encoding='latin1') for j in range(len(filenamesInDir)): filenames.append( filenamesInDir[j]) # 将每1个pic的路径,加入filenames所维护的list中 ptsFilename = filenamesInDir[j][:-3] + "pts" landmarks.append( utils.loadFromPts(ptsFilename) ) # 将每个图片标注信息的pts路径,写入list:'../data/images/lfpw/trainset\\image_0001.pts' if boundingBoxFiles is not None: basename = path.basename(filenamesInDir[j]) boundingBoxes.append(boundingBoxDict[basename]) filenames = filenames[startIdx:startIdx + nImgs] landmarks = landmarks[startIdx:startIdx + nImgs] boundingBoxes = boundingBoxes[startIdx:startIdx + nImgs] mirrorList = [False for i in range(nImgs)] if mirrorFlag: mirrorList = mirrorList + [True for i in range(nImgs)] filenames = np.concatenate((filenames, filenames)) landmarks = np.vstack((landmarks, landmarks)) # 6096个pic对应的特征点信息 boundingBoxes = np.vstack((boundingBoxes, boundingBoxes)) self.origLandmarks = landmarks # 将读取到的信息,写到对应的mageServer的属性成员上 self.filenames = filenames self.mirrors = mirrorList self.meanShape = meanShape self.boundingBoxes = boundingBoxes
def PrepareData(self, imageDirs, boundingBoxFiles, meanShape, startIdx, nImgs, mirrorFlag): filenames = [ ] # 이 목록은 filenamesInDir과 완전히 동일하므로 제거 할 수 있습니다. <<< 此list和filenamesInDir完全一样,可以去除 landmarks = [] # 이 리스트는 특징점 좌표를 저장하는 데 사용됩니다. <<< 此list用于存储特征点坐标 boundingBoxes = [] # 이 목록은 bbx를 저장하는 데 사용됩니다. <<< 此list用于存储bbx # import pdb; pdb.set_trace() for i in range(len(imageDirs)): filenamesInDir = glob.glob(imageDirs[i] + "*.jpg") filenamesInDir += glob.glob(imageDirs[i] + "*.png") # import pdb; pdb.set_trace() if boundingBoxFiles is not None: boundingBoxDict = pickle.load(open(boundingBoxFiles[i], 'rb')) for j in range(len(filenamesInDir)): filenames.append(filenamesInDir[j]) ptsFilename = filenamesInDir[j][:-3] + "pts" landmarks.append(utils.loadFromPts(ptsFilename)) if boundingBoxFiles is not None: basename = path.basename(filenamesInDir[j]) boundingBoxes.append(boundingBoxDict[basename]) filenames = filenames[startIdx:startIdx + nImgs] landmarks = landmarks[startIdx:startIdx + nImgs] boundingBoxes = boundingBoxes[startIdx:startIdx + nImgs] mirrorList = [False for i in range(nImgs)] if mirrorFlag: mirrorList = mirrorList + [True for i in range(nImgs)] filenames = np.concatenate((filenames, filenames)) landmarks = np.vstack((landmarks, landmarks)) boundingBoxes = np.vstack((boundingBoxes, boundingBoxes)) self.origLandmarks = landmarks self.filenames = filenames self.mirrors = mirrorList self.meanShape = meanShape self.boundingBoxes = boundingBoxes
def PrepareData(self, imageDirs, boundingBoxFiles, meanShape, startIdx, nImgs, mirrorFlag): filenames = [] landmarks = [] boundingBoxes = [] for i in range(len(imageDirs)): filenamesInDir = glob.glob(imageDirs[i] + "*.jpg") filenamesInDir += glob.glob(imageDirs[i] + "*.png") if boundingBoxFiles is not None: boundingBoxDict = pickle.load(open(boundingBoxFiles[i], 'rb'), encoding='latin1') for j in range(len(filenamesInDir)): filenames.append(filenamesInDir[j]) ptsFilename = filenamesInDir[j][:-3] + "pts" landmarks.append(utils.loadFromPts(ptsFilename)) if boundingBoxFiles is not None: basename = path.basename(filenamesInDir[j]) boundingBoxes.append(boundingBoxDict[basename]) filenames = filenames[startIdx:startIdx + nImgs] landmarks = landmarks[startIdx:startIdx + nImgs] boundingBoxes = boundingBoxes[startIdx:startIdx + nImgs] mirrorList = [False for i in range(nImgs)] if mirrorFlag: mirrorList = mirrorList + [True for i in range(nImgs)] filenames = np.concatenate((filenames, filenames)) landmarks = np.vstack((landmarks, landmarks)) boundingBoxes = np.vstack((boundingBoxes, boundingBoxes)) self.origLandmarks = landmarks self.filenames = filenames self.mirrors = mirrorList self.meanShape = meanShape self.boundingBoxes = boundingBoxes
def __getitem__( self, i ): # __getitem__ to support the indexing such that dataset[i] can be used to get ith sample # 1. load image and kps image = cv2.imread(self.imglists[i]) image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) h, w, c = image.shape kps_path = self.imglists[i][:-4] + '.pts' kps = loadFromPts(kps_path) # 2. data augmentation if self.phase == 'train': # rotate angle = random.randint(-self.r, self.r) r_kps = rotatepoints(kps, [w / 2, h / 2], angle) # 逆时针旋转angle度 # norm kps to [0,res] #旋转之后的kps的方框 left = np.min(r_kps[:, 0]) # 所有行的第0列 right = np.max(r_kps[:, 0]) top = np.min(r_kps[:, 1]) # 所有行的第1列 bot = np.max(r_kps[:, 1]) r_kps -= [left, top] # 坐标转换到[0,-] r_kps[:, 0] *= self.res / (right - left) # 坐标转换到[0,res] r_kps[:, 1] *= self.res / (bot - top) # scale s = random.uniform(0.9, 1.2) # uniform()方法将随机生成浮点数,它在 [x, y) 范围内 # make scale around center dx = (1 - s) * self.res * 0.5 # res*0.5-s*res*0.5 缩放前的中心-缩放后的中心 s_kps = r_kps * s + [dx, dx] # translation dx = random.uniform(-self.res * 0.1, self.res * 0.1) dy = random.uniform(-self.res * 0.1, self.res * 0.1) t_kps = s_kps + [dx, dy] # procrustes analysis 从两组关键点间分析出变换矩阵用于图像的变换 d, Z, tform = procrustes( t_kps, kps ) # a dict specifying the rotation, translation and scaling that maps X --> Y M = np.zeros([2, 3], dtype=np.float32) M[:2, :2] = tform['rotation'].T * tform['scale'] M[:, 2] = tform['translation'] img = cv2.warpAffine(image, M, (self.res, self.res)) # 仿射变换 将图像按照关键点变换 new_kps = np.dot( kps, tform['rotation']) * tform['scale'] + tform['translation'] else: # enlarge box box = get_gtbox(kps) box = enlarge_box(box, 0.05) xmin, ymin, xmax, ymax = box src = np.array([[xmin, ymin], [xmin, ymax], [xmax, ymin], [xmax, ymax]]) dst = np.array([[0, 0], [0, self.res - 1], [self.res - 1, 0], [self.res - 1, self.res - 1]]) # procrustes analysis d, Z, tform = procrustes(dst, src) M = np.zeros([2, 3], dtype=np.float32) M[:2, :2] = tform['rotation'].T * tform['scale'] M[:, 2] = tform['translation'] img = cv2.warpAffine(image, M, (self.res, self.res)) new_kps = np.dot( kps, tform['rotation']) * tform['scale'] + tform['translation'] if self.phase == 'train': # flip if random.random() > 0.5: img = img[:, ::-1] # 左右翻转 new_kps = flippoints(new_kps, self.res) # resize if random.random() > 0.8: new_res = int(self.res * 0.75) img = cv2.resize(img, (new_res, new_res)) img = cv2.resize(img, (self.res, self.res)) if self.target_type == 'heatmap': num_points = kps.shape[0] new_kps = new_kps.astype(np.int32) target = np.zeros([num_points, self.res, self.res]) for n in range(num_points): target[n] = draw_gaussian(target[n], new_kps[n], sigma=self.gamma) # 构造训练的heatmap的标签 target = torch.from_numpy( target).float() # 将numpy格式转换成torch.tensor格式 else: target = torch.from_numpy(new_kps).float() # 回归landmark # img to tensor img = self.transform( img.copy() ) # transforms.ToTensor() Converts a PIL Image or numpy.ndarray (H x W x C) in the range [0, 255] to #a torch.FloatTensor of shape (C x H x W) in the range [0.0, 1.0]. if self.phase == 'train': img[0, :, :].mul_(random.uniform(0.7, 1.3)).clamp_(0, 1) img[1, :, :].mul_(random.uniform(0.7, 1.3)).clamp_(0, 1) img[2, :, :].mul_(random.uniform(0.7, 1.3)).clamp_(0, 1) return img, target, torch.from_numpy(new_kps), tform
plt.figure() plt.grid() plt.xlim([0, 0.35]) plt.ylim([0, 1]) plt.plot(np.concatenate([[0], sorted_error]), np.arange(num_images+1, dtype=np.float)/num_images, color='darkorange', lw=2, label='cumulative curve') plt.savefig('images/plot2.png', format='png') ''' # print(evaluateBatchError(Ytest.reshape([-1, 68, 2]), Landmark.reshape([-1, 68, 2]), Batch_size)) for i in range(num_images): A_temp = np.linalg.inv(A[i]) t_temp = np.dot(np.reshape(-t[i], (1, 2)), A_temp) landmark = Landmark[i] landmark = np.reshape(np.dot(landmark, A_temp) + t_temp, [68, 2]) ptsFilename = testSet.filenames[i][:-3] + "pts" groundtruth = utils.loadFromPts(ptsFilename) error = evaluateError(landmark, groundtruth) # print(error) errs.append(np.mean(error)) ''' img = cv2.imread(testSet.filenames[i]) for point in range(68): cv2.circle(img,( int(landmark[point][0]), int(landmark[point][1])),1,(0,255,255),3); cv2.imwrite(os.path.join("../data/vis",testSet.filenames[i][-14:]),img) ''' sorted_error = np.sort(errs, axis=0) plt.figure()
def PrepareData(self, imageDirs, boundingBoxFiles, meanShape, startIdx, nImgs, mirrorFlag): """获取训练集的boundingbox\imagelist\meanshape\landmark\mirrors存入相应成员变量中 Args: imageDirs: 训练集所有图片所在路径 boudingBoxFiles: boudingBoxFile文件路径 .pkl文件 meanshape: 均值图像 startIdx: 从训练集中选取此次训练的第一个图像的id nImgs: 此次训练的图像个数 mirrorFlag: 还不懂是干什么用的 """ pass print('Preparing Data......') filenames = [] landmarks = [] boundingBoxes = [] # 获取图片名列表、lanmark标注列表、boundingbox列表分别存入以上三个变量中 for i in range(len(imageDirs)): print('Preparing Data......%dth dataset.....'%(i)) filenamesInDir = glob.glob(imageDirs[i] + "*.jpg") filenamesInDir += glob.glob(imageDirs[i] + "*.png") # open() rb: 以二进制的格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式,返回一个file对象 # .pkl文件就是对于每一个图片创建一个dict元素,key为图片名去掉后缀,value为bounding box的四个顶点的坐标 # pickle.load() 最后返回一个dictionary if boundingBoxFiles is not None: boundingBoxDict = pickle.load(open(boundingBoxFiles[i], 'rb'), encoding='iso-8859-1') for j in range(len(filenamesInDir)): print('Preparing Data......%dth image.....'%(j)) filenames.append(filenamesInDir[j]) # 获取标注点文件名.pts,将landmark转换为x,y坐标的array数组录入到landmarks中 68*2 ptsFilename = filenamesInDir[j][:-3] + "pts" landmarks.append(utils.loadFromPts(ptsFilename)) if boundingBoxFiles is not None: basename = path.basename(filenamesInDir[j]) boundingBoxes.append(boundingBoxDict[basename]) filenames = filenames[startIdx : startIdx + nImgs] landmarks = landmarks[startIdx : startIdx + nImgs] boundingBoxes = boundingBoxes[startIdx : startIdx + nImgs] mirrorList = [False for i in range(nImgs)] if mirrorFlag: #最后得到的是一个2倍的images长度的mirrorlist,前面的mirrorlist值为false即不做镜像变换,后面的为true做镜像变换 mirrorList = mirrorList + [True for i in range(nImgs)] # 拼接 axis default is 0,即按行拼接 filenames = np.concatenate((filenames, filenames)) # 按行拼接返回数组,作用同上 landmarks = np.vstack((landmarks, landmarks)) boundingBoxes = np.vstack((boundingBoxes, boundingBoxes)) # prepare data 进行一系列的初始化 self.origLandmarks = landmarks self.filenames = filenames # self.mirrors 代表是否被镜像了 self.mirrors = mirrorList self.meanShape = meanShape self.boundingBoxes = boundingBoxes print('Preparing Data finished.')
def PrepareData(self, imageDirs, boundingBoxFiles, meanShape, startIdx, nImgs, mirrorFlag): filenames = [] #此list和filenamesInDir完全一样,可以去除 landmarks = [] #此list用于存储特征点坐标 boundingBoxes = [] #此list用于存储bbx # import pdb; pdb.set_trace() ''' # skip the missing pic missing = [] missingfile = open('missing.txt') lines = missingfile.readlines() for line in lines: if line[-1] == "\n": missing.append(line[:-1]) else: missing.append(line) # print(len(missing)) # print(missing) ''' for i in range(len(imageDirs)): filenamesInDir = glob.glob(imageDirs[i] + "*.jpg") filenamesInDir += glob.glob(imageDirs[i] + "*.png") # import pdb; pdb.set_trace() if boundingBoxFiles is not None: # boundingBoxDict = pickle.load(open(boundingBoxFiles[i], 'rb'),encoding='bytes') boundingBoxDict = pickle.load(open(boundingBoxFiles[i], 'rb'), encoding='latin1') # print(boundingBoxDict) for j in range(len(filenamesInDir)): # print(filenamesInDir[j]) ''' index = filenamesInDir[j].rfind("/") picname = filenamesInDir[j][index+1:] if picname in missing: # print(picname) continue ''' filenames.append(filenamesInDir[j]) ptsFilename = filenamesInDir[j][:-3] + "pts" landmarks.append(utils.loadFromPts(ptsFilename)) if boundingBoxFiles is not None: basename = path.basename(filenamesInDir[j]) if boundingBoxDict.get(basename) == None: print(basename) continue boundingBoxes.append(boundingBoxDict[basename]) # nImgs = len(filenames) # 在原作者代码中,nImgs=2,所以只能用两张图片,翻转+pertubation=40张图片进行训练。 # print(nImgs) filenames = filenames[startIdx:startIdx + nImgs] landmarks = landmarks[startIdx:startIdx + nImgs] boundingBoxes = boundingBoxes[startIdx:startIdx + nImgs] mirrorList = [False for i in range(nImgs)] if mirrorFlag: mirrorList = mirrorList + [True for i in range(nImgs)] filenames = np.concatenate((filenames, filenames)) landmarks = np.vstack((landmarks, landmarks)) # 合并 boundingBoxes = np.vstack((boundingBoxes, boundingBoxes)) self.origLandmarks = landmarks self.filenames = filenames self.mirrors = mirrorList self.meanShape = meanShape self.boundingBoxes = boundingBoxes