Пример #1
0
def visual(clist, cdir, num_pts):
    if not cdir.exists(): os.makedirs(str(cdir))
    shape = 256
    transform = transforms.Compose(
        [transforms.PreCrop(0.2),
         transforms.TrainScale2WH((shape, shape))])
    data = datasets.GeneralDataset(transform, 2, 1, 'gaussian', 'test')
    data.load_list(clist, num_pts, True)
    for i, tempx in enumerate(data):
        image = tempx[0]
        heats = models.variable2np(tempx[1]).transpose(1, 2, 0)
        xheat = generate_color_from_heatmaps(heats, index=-1)
        xheat = PIL.Image.fromarray(np.uint8(xheat * 255))

        cimage = overlap_two_pil_image(image, xheat)

        basename = osp.basename(data.datas[i]).split('.')[0]
        basename = str(cdir) + '/' + basename + '-{:}.jpg'

        image.save(basename.format('ori'))
        xheat.save(basename.format('heat'))
        cimage.save(basename.format('over'))

        if i % PRINT_GAP == 0:
            print('--->>> process the {:4d}/{:4d}-th image'.format(
                i, len(data)))
Пример #2
0
def evaluation_image(eval_loader, net, log, save_path, opt):
    if not osp.isdir(save_path): os.makedirs(save_path)
    if opt.debug_save:
        debug_save_dir = osp.join(save_path, 'debug-eval')
        if not os.path.isdir(debug_save_dir): os.makedirs(debug_save_dir)
    else: debug_save_dir = None
    print_log(
        ' ==>start evaluation image dataset, save into {} with the error bar : {}, using the last stage, DEBUG SAVE DIR : {}'
        .format(save_path, opt.error_bar, debug_save_dir), log)

    # switch to eval mode
    net.eval()
    # calculate the time
    batch_time, end = AverageMeter(), time.time()
    # save the evaluation results
    eval_meta = Eval_Meta()
    # save the number of points
    num_pts, scale_eval = opt.num_pts, opt.scale_eval

    for i, (inputs, target, mask, points, image_index, label_sign,
            ori_size) in enumerate(eval_loader):

        # inputs : Batch, Squence, Channel, Height, Width
        target = target.cuda(async=True)
        mask = mask.cuda(async=True)

        # forward, batch_locs [1 x points] [batch, 2]
        batch_cpms, batch_locs, batch_scos, generated = net(inputs)
        assert batch_locs.size(0) == batch_scos.size(0) and batch_locs.size(
            0) == inputs.size(0)
        assert batch_locs.size(1) == num_pts + 1 and batch_scos.size(
            1) == num_pts + 1
        assert batch_locs.size(2) == 2 and len(batch_scos.size()) == 2
        np_batch_locs, np_batch_scos = variable2np(batch_locs), variable2np(
            batch_scos)
        image_index = np.squeeze(variable2np(image_index)).tolist()
        if isinstance(image_index, numbers.Number): image_index = [image_index]
        sign_list = variable2np(label_sign).astype('bool').squeeze(1).tolist()
        # recover the ground-truth label
        real_sizess = variable2np(ori_size)

        for ibatch, imgidx in enumerate(image_index):
            locations, scores = np_batch_locs[ibatch, :-1, :], np_batch_scos[
                ibatch, :-1]
            if len(scores.shape) == 1: scores = np.expand_dims(scores, axis=1)
            xpoints = eval_loader.dataset.labels[imgidx].get_points()
            assert real_sizess[ibatch, 0] > 0 and real_sizess[
                ibatch,
                1] > 0, 'The ibatch={}, imgidx={} is not right.'.format(
                    ibatch, imgidx)
            scale_h, scale_w = real_sizess[ibatch, 0] * 1. / inputs.size(
                -2), real_sizess[ibatch, 1] * 1. / inputs.size(-1)
            locations[:,
                      0], locations[:,
                                    1] = locations[:, 0] * scale_w + real_sizess[
                                        ibatch,
                                        2], locations[:,
                                                      1] * scale_h + real_sizess[
                                                          ibatch, 3]
            assert xpoints.shape[1] == num_pts and locations.shape[
                0] == num_pts and scores.shape[
                    0] == num_pts, 'The number of points is {} vs {} vs {} vs {}'.format(
                        num_pts, xpoints.shape, locations.shape, scores.shape)
            # recover the original resolution
            locations = np.concatenate((locations, scores), axis=1)
            image_path = eval_loader.dataset.datas[imgidx]
            face_size = eval_loader.dataset.face_sizes[imgidx]
            image_name = osp.basename(image_path)
            locations = locations.transpose(1, 0)
            eval_meta.append(locations, xpoints, image_path, face_size)

            if opt.error_bar is not None:
                errorpath = osp.join(save_path, image_name)
                save_error_image(image_path,
                                 xpoints,
                                 locations,
                                 opt.error_bar,
                                 errorpath,
                                 radius=5,
                                 color=(30, 255, 30),
                                 rev_color=(255, 30, 30),
                                 fontScale=10,
                                 text_color=(255, 255, 255))
        if opt.debug_save:
            print_log(
                'DEBUG --- > [{:03d}/{:03d}] '.format(i, len(eval_loader)),
                log)
            main_debug_save(debug_save_dir, eval_loader, image_index, inputs,
                            batch_locs, target, points, sign_list, batch_cpms,
                            generated, log)

        # measure elapsed time
        batch_time.update(time.time() - end)
        need_hour, need_mins, need_secs = convert_secs2time(
            batch_time.avg * (len(eval_loader) - i - 1))
        end = time.time()

        if i % opt.print_freq_eval == 0 or i + 1 == len(eval_loader):
            print_log(
                '  Evaluation: [{:03d}/{:03d}] Time {:6.3f} ({:6.3f}) Need [{:02d}:{:02d}:{:02d}]'
                .format(i, len(eval_loader), batch_time.val, batch_time.avg,
                        need_hour, need_mins, need_secs) +
                ' locations.shape={}'.format(np_batch_locs.shape), log)

    return eval_meta
Пример #3
0
def main_debug_save(debug_save_dir, loader, image_index, input_vars, batch_locs, target, points, sign_list, batch_cpms, generations, log):
  mean, std = [0.485, 0.456, 0.406], [0.229, 0.224, 0.225]
  batch_size, num_pts = batch_locs.size(0), batch_locs.size(1)
  assert batch_size == len(image_index)
  print_log('Save-dir : {} : check {}'.format(debug_save_dir, image_index), log)
  for idx, imgid in enumerate(image_index):
    basename = osp.basename( loader.dataset.datas[imgid] )
    basename = basename.split('.')[0]
    print_log('Start visualization done for [{:03d}/{:03d}] : {:5} | {:}'.format(idx, len(image_index), imgid, loader.dataset.datas[imgid]), log)
    ## Save all images
    images = [input_vars[idx], generations[0][idx], generations[1][idx]]
    _pil_images = []
    for iG, xinput in enumerate(images):
      xinput = xinput.clone()
      Xinput = []
      for t, m, s in zip(xinput, mean, std):
        t = torch.mul(t, s)
        t = torch.add(t, m)
        Xinput.append( t )
      xinput = torch.stack(Xinput)
      if xinput.is_cuda: xinput = xinput.cpu()
      image = transforms.ToPILImage()(xinput.data)
      debug_save_path = os.path.join(debug_save_dir, '{}-G{}.png'.format(basename, iG))
      image.save(debug_save_path)
      _pil_images.append( image )
      """
      debug_loc = []
      for ipts in range(num_pts):
        temploc = models.variable2np( batch_locs[idx][ipts] )
        debug_loc.append( temploc )
      debug_loc = np.array( debug_loc )
      debug_save_path = os.path.join(debug_save_dir, '{}-ans-points.png'.format(basename))
      pimage = draw_image_with_pts(image, debug_loc.transpose(1,0), radius=1, linewidth=1, fontScale=12, window=None)
      pimage.save(debug_save_path)
      """
    image = _pil_images[0]
    debug_save_path = os.path.join(debug_save_dir, '{}-GG.png'.format(basename))
    overlap_two_pil_image(_pil_images[1], _pil_images[2]).save(debug_save_path)
    # save the back ground heatmap
    for icpm in range(len(batch_cpms)):
      cpms = batch_cpms[icpm][idx]
      xtarget = models.variable2np( cpms )
      xtarget = xtarget.transpose(1,2,0)
      xheatmaps = generate_color_from_heatmaps(xtarget, index=-1)
      cimage = PIL.Image.fromarray(np.uint8(xheatmaps*255))
      cimage = overlap_two_pil_image(image, cimage)
      debug_save_path = os.path.join(debug_save_dir, '{:}-BG-{}.png'.format(basename, icpm))
      cimage.save(debug_save_path)

      xheatmaps = generate_color_from_heatmaps(xtarget, index=0)
      cimage = PIL.Image.fromarray(np.uint8(xheatmaps*255))
      cimage = overlap_two_pil_image(image, cimage)
      debug_save_path = os.path.join(debug_save_dir, '{:}-B0-{}.png'.format(basename, icpm))
      cimage.save(debug_save_path)

    # save the ground truth heatmap
    if sign_list[idx] and False:
      xtarget = models.variable2np( target[idx] )
      xtarget = xtarget.transpose(1,2,0)
      xheatmaps = generate_color_from_heatmaps(xtarget)
      all_images = []
      for pid in range(len(xheatmaps)):
        cimage = PIL.Image.fromarray(np.uint8(xheatmaps[pid]*255))
        cimage = overlap_two_pil_image(center_img, cimage)
        all_images.append( cimage )
      debug_save_path = os.path.join(debug_save_dir, '{}-gt-heatmap.png'.format(basename))
      all_images = merge_images(all_images, 10)
      all_images.save( debug_save_path )
  
      # debug save for points
      cpoints = models.variable2np( points[idx] )
      debug_save_path = os.path.join(debug_save_dir, '{}-gt-points.png'.format(basename))
      point_image = draw_image_with_pts(center_img, cpoints.transpose(1,0), radius=1, linewidth=1, fontScale=12, window=lk_window)
      point_image.save(debug_save_path)
      
      print_log('Calculate gt-visualization done for [{:03d}/{:03d}] : {:5} | {:}'.format(idx, len(image_index), imgid, loader.dataset.datas[imgid]), log)
    else:
      print_log('Skip the ground truth heatmap debug saving', log)
Пример #4
0
def train(train_loader, net, criterion, optimizer, epoch, opt, log):
  batch_time = AverageMeter()
  data_time = AverageMeter()
  forward_time = AverageMeter()
  visible_points = AverageMeter()
  losses = AverageMeter()
  # switch to train mode
  net.module.set_mode('train')
  criterion.train()

  if opt.debug_save:
    debug_save_dir = os.path.join(opt.save_path, 'debug-train-{:02d}'.format(epoch))
    if not os.path.isdir(debug_save_dir): os.makedirs(debug_save_dir)

  end = time.time()
  for i, (inputs, target, mask, points, image_index, label_sign, _) in enumerate(train_loader):
    # inputs : Batch, Squence, Channel, Height, Width
    # data prepare
    target = target.cuda(async=True)
    # get the real mask
    mask.masked_scatter_((1-label_sign).unsqueeze(-1).unsqueeze(-1), torch.ByteTensor(mask.size()).zero_())
    mask_var   = mask.cuda(async=True)

    batch_size, num_pts = inputs.size(0), mask.size(1)-1
    image_index = variable2np(image_index).squeeze(1).tolist()
    # check the label indicator, whether is has annotation or not
    sign_list = variable2np(label_sign).astype('bool').squeeze(1).tolist()

    # measure data loading time
    data_time.update(time.time() - end)
    cvisible_points = torch.sum(mask[:,:-1,:,:]) * 1. / batch_size
    visible_points.update(cvisible_points, batch_size)

    # batch_cpms is a list for CPM stage-predictions, each element should be [Batch, Squence, C, H, W]
    # batch_locs and batch_scos are two sequence-list of point-list, each element is [Batch, 2] / [Batch, 1]
    # batch_next and batch_back are two sequence-list of point-list, each element is [Batch, 2] / [Batch, 2]
    batch_cpms, batch_locs, batch_scos, generated = net(inputs)
    
    forward_time.update(time.time() - end)

    total_labeled_cpm = int(np.sum(sign_list))

    # collect all cpm stages for the middle frame
    cpm_loss, each_stage_loss_values = compute_stage_loss(criterion, target, batch_cpms, mask_var, total_labeled_cpm, opt.weight_of_idt)
  
    # measure accuracy and record loss
    losses.update(cpm_loss.item(), batch_size)
    # compute gradient and do SGD step
    optimizer.zero_grad()
    cpm_loss.backward()
    optimizer.step()

    # measure elapsed time
    batch_time.update(time.time() - end)
    need_hour, need_mins, need_secs = convert_secs2time(batch_time.avg * (len(train_loader)-i-1))
    last_time = '[{:02d}:{:02d}:{:02d}]'.format(need_hour, need_mins, need_secs)
    end = time.time()

    if i % opt.print_freq == 0 or i+1 == len(train_loader):
      print_log('  Epoch: [{:03d}/{:03d}][{:03d}/{:03d}]  '
                'Time {batch_time.val:5.2f} ({batch_time.avg:5.2f}) '
                'Data {data_time.val:5.2f} ({data_time.avg:5.2f}) '
                'Forward {forward_time.val:5.2f} ({forward_time.avg:5.2f}) '
                'Loss {loss.val:6.3f} ({loss.avg:6.3f})  '.format(
                    epoch, opt.epochs, i, len(train_loader), batch_time=batch_time,
                    data_time=data_time, forward_time=forward_time, loss=losses)
                  + last_time + show_stage_loss(each_stage_loss_values) \
                  + ' In={} Tar={} Mask={}'.format(convert_size2str(inputs.size()), convert_size2str(target.size()), convert_size2str(mask_var.size())) \
                  + ' Vis-PTS : {:2d} ({:.1f})'.format(int(visible_points.val), visible_points.avg), log)

    # Just for debug and show the intermediate results.
    if opt.debug_save:
      print_log('DEBUG --- > [{:03d}/{:03d}] '.format(i, len(train_loader)), log)
      main_debug_save(debug_save_dir, train_loader, image_index, inputs, batch_locs, target, points, sign_list, batch_cpms, generated, log)
  
  return losses.avg