2020年度卒研セミナー(2020/10/15)

デリバリーのための地図アプリの提案(松尾氏)

本日、開発に必要な機材を貸与する(MacBook Airと書籍)。

DNNによる室内人数のカウント(金子氏)

Google Colaboratory上で動作するYOLOv3の実装は終了した。 本日、その概略を説明する。

IoTによる傘の取り違い防止システム(福留氏)

Androidアプリ・ラズパイ間のBluetooth通信について、参考になりそうなページのURLをまとめたので、 福留氏のサポートページを見てほしい。

DNNを用いた3Dモデルの生成支援システム(西村氏)

PIFuのデモプログラム動作するように改良中である。 できれば最終的には、Google Colaboratory上で動作させたい。


改良中のメインプログラム(eval.py)
import torchvision.transforms as transforms
import torch
from HGPIFuNet import HGPIFuNet
from ResBlkPIFuNet import ResBlkPIFuNet
   
class Evaluator:
    def __init__(self, p, projection_mode='orthogonal'):
        self.p = p
        self.load_size = self.p['loadSize']
        self.to_tensor = transforms.Compose([
            transforms.Resize(self.load_size),
            transforms.ToTensor(),
            transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))
        ])
        # set cuda
        cuda = torch.device('cuda:{0}'.format(self.p['gpu_id'])) if torch.cuda.is_available() else torch.device('cpu')
   
        # create net
        netG = HGPIFuNet(p, projection_mode).to(device=cuda)
        print('Using Network: ', netG.name)
   
        if self.p['load_netG_checkpoint_path']:
            netG.load_state_dict(torch.load(self.p['load_netG_checkpoint_path'], map_location=cuda))
  
        if self.p['load_netC_checkpoint_path'] is not None:
            print('loading for net C ...', self.p['load_netC_checkpoint_path'])
            netC = ResBlkPIFuNet(p).to(device=cuda)
            netC.load_state_dict(torch.load(self.p['load_netC_checkpoint_path'], map_location=cuda))
        else:
            netC = None
  
        os.makedirs(p['results_path'], exist_ok=True)
        os.makedirs('{0}/{1}'.format(p['results_path'], p['name']), exist_ok=True)
  
        opt_log = os.path.join(p['results_path'], p['name'], 'opt.txt')
        with open(opt_log, 'w') as outfile:
            outfile.write(json.dumps(vars(p), indent=2))
  
        self.cuda = cuda
        self.netG = netG
        self.netC = netC
  

def createDefaultParam():
    p = {}
    p['dataroot'] = './data' # path to images (data folder)
    p['loadSize'] = 512 # load size of input image
  
    p['name'] = 'example' # name of the experiment. It decides where to store samples and models
    p['debug'] = False # debug mode or not
    p['num_views'] = 1 # How many views to use for multiview network
    p['random_multiview'] = False # Select random multiview combination
  
    p['gpu_id'] = 0 # gpu id for cuda
    p['gpu_ids'] = '0' # gpu ids: e.g. 0  0,1,2, 0,2, -1 for CPU mode
    p['num_threads'] = 1 # sthreads for loading data
    p['serial_batches'] = False # if true, takes images in order to make batches, otherwise takes them randomly
    p['pin_memory'] = False # pin_memory
    p['batch_size'] = 2 # input batch size
    p['learning_rate'] = 1e-3 # adam learning rate
    p['learning_rateC'] = 1e-3 # adam learning rate
    p['num_epoch'] = 100 # num epoch to train
    p['freq_plot'] = 10 # freqency of the error plot
    p['freq_save'] = 50 # freqency of the save_checkpoints
    p['freq_save_ply'] = 100 # freqency of the save ply
    p['no_gen_mesh'] = False
    p['no_num_eval'] = False 
    p['resume_epoch'] = -1 # epoch resuming the training
    p['continue_train'] = False # continue training: load the latest model
  
    p['resolution'] = 256 # of grid in mesh reconstruction
    p['test_folder_path'] = None # the folder of test image
  
    p['sigma'] = 5.0 # perturbation standard deviation for positions
    p['num_sample_inout'] = 5000 # of sampling points
    p['num_sample_color'] = 0 # of sampling points
    p['z_size'] = 200.0 # z normalization factor
  
    p['norm'] = 'group' # instance normalization or batch normalization or group normalization
    p['norm_color'] = 'instance' # instance normalization or batch normalization or group normalization
  
    p['num_stack'] = 4 # of hourglass
    p['num_hourglass'] = 2 # of stacked layer of hourglass
    p['skip_hourglass'] = False # skip connection in hourglass
    p['hg_down'] = 'ave_pool' # ave pool || conv64 || conv128
    p['hourglass_dim'] = 256 # 256 | 512
  
    p['mlp_dim'] = [257, 1024, 512, 256, 128, 1] # of dimensions of mlp
    p['mlp_dim_color'] = [513, 1024, 512, 256, 128, 3] # of dimensions of color mlp
    p['use_tanh'] = False # using tanh after last conv of image_filter network
  
    p['random_flip'] = False # if random flip
    p['random_trans'] = False # if random flip
    p['random_scale'] = False # if random flip
    p['no_residual'] = False # no skip connection in mlp
    p['schedule'] = [60, 80] # Decrease learning rate at these epochs
    p['gamma'] = 0.1 # LR is multiplied by gamma on schedule
    p['color_loss_type'] = 'l1' # mse | l1
  
    p['val_test_error'] = False # validate errors of test data
    p['val_train_error'] = False # validate errors of train data
    p['gen_test_mesh'] = False # generate test mesh
    p['gen_train_mesh'] = False # generate train mesh
    p['all_mesh'] = False # generate meshs from all hourglass output
    p['num_gen_mesh_test'] = 1 # how many meshes to generate during testing
  
    p['checkpoints_path'] = './checkpoints' # path to save checkpoints
    p['load_netG_checkpoint_path'] = None # path to save checkpoints
    p['load_netC_checkpoint_path'] = None # path to save checkpoints
    p['results_path'] = './results' # path to save results ply
    p['load_checkpoint_path'] = None # path to save results ply
    p['single'] = '' # single data for training
    p['mask_path'] = None # path for input mask
    p['img_path'] = None # path for input image
  
    p['aug_alstd'] = 0.0 # augmentation pca lighting alpha std
    p['aug_bri'] = 0.0 # augmentation brightness
    p['aug_con'] = 0.0 # augmentation contrast
    p['aug_sat'] = 0.0 # augmentation saturation
    p['aug_hue'] = 0.0 # augmentation hue
    p['aug_blur'] = 0.0 # augmentation blur
    return p
  
if __name__ == '__main__':
    param = createDefaultParam()
   
    param['name'] = 'pifu_demo'
    param['batch_size'] = 1
    param['mlp_dim'] = [257, 1024, 512, 256, 128, 1]
    param['mlp_dim_color'] = [513, 1024, 512, 256, 128, 3]
    param['num_stack'] = 4
    param['num_hourglass'] = 2
    param['resolution'] = 256
    param['hg_down'] = 'ave_pool'
    param['norm'] = 'group'
    param['norm_color'] = 'group'
    param['test_folder_path'] = './sample_images'
    param['load_netG_checkpoint_path'] = './checkpoints/net_G'
    param['load_netC_checkpoint_path'] = './checkpoints/net_C'
  
    evaluator = Evaluator(param)
    

メインプログラムのオリジナル(eval.py)
import sys
import os
   
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
ROOT_PATH = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
   
import time
import json
import numpy as np
import torch
from torch.utils.data import DataLoader
   
from lib.options import BaseOptions
from lib.mesh_util import *
from lib.sample_util import *
from lib.train_util import *
from lib.model import *
   
from PIL import Image
import torchvision.transforms as transforms
import glob
import tqdm
   
# get options
opt = BaseOptions().parse()
   
class Evaluator:
    def __init__(self, opt, projection_mode='orthogonal'):
        self.opt = opt
        self.load_size = self.opt.loadSize
        self.to_tensor = transforms.Compose([
            transforms.Resize(self.load_size),
            transforms.ToTensor(),
            transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))
        ])
        # set cuda
        cuda = torch.device('cuda:%d' % opt.gpu_id) if torch.cuda.is_available() else torch.device('cpu')
   
        # create net
        netG = HGPIFuNet(opt, projection_mode).to(device=cuda)
        print('Using Network: ', netG.name)
  
        if opt.load_netG_checkpoint_path:
            netG.load_state_dict(torch.load(opt.load_netG_checkpoint_path, map_location=cuda))
  
        if opt.load_netC_checkpoint_path is not None:
            print('loading for net C ...', opt.load_netC_checkpoint_path)
            netC = ResBlkPIFuNet(opt).to(device=cuda)
            netC.load_state_dict(torch.load(opt.load_netC_checkpoint_path, map_location=cuda))
        else:
            netC = None
  
        os.makedirs(opt.results_path, exist_ok=True)
        os.makedirs('%s/%s' % (opt.results_path, opt.name), exist_ok=True)
   
        opt_log = os.path.join(opt.results_path, opt.name, 'opt.txt')
        with open(opt_log, 'w') as outfile:
            outfile.write(json.dumps(vars(opt), indent=2))
  
        self.cuda = cuda
        self.netG = netG
        self.netC = netC
  
    def load_image(self, image_path, mask_path):
        # Name
        img_name = os.path.splitext(os.path.basename(image_path))[0]
        # Calib
        B_MIN = np.array([-1, -1, -1])
        B_MAX = np.array([1, 1, 1])
        projection_matrix = np.identity(4)
        projection_matrix[1, 1] = -1
        calib = torch.Tensor(projection_matrix).float()
        # Mask
        mask = Image.open(mask_path).convert('L')
        mask = transforms.Resize(self.load_size)(mask)
        mask = transforms.ToTensor()(mask).float()
        # image
        image = Image.open(image_path).convert('RGB')
        image = self.to_tensor(image)
        image = mask.expand_as(image) * image
        return {
            'name': img_name,
            'img': image.unsqueeze(0),
            'calib': calib.unsqueeze(0),
            'mask': mask.unsqueeze(0),
            'b_min': B_MIN,
            'b_max': B_MAX,
        }
  
    def eval(self, data, use_octree=False):
        '''
        Evaluate a data point
        :param data: a dict containing at least ['name'], ['image'], ['calib'], ['b_min'] and ['b_max'] tensors.
        :return:
        '''
        opt = self.opt
        with torch.no_grad():
            self.netG.eval()
            if self.netC:
                self.netC.eval()
            save_path = '%s/%s/result_%s.obj' % (opt.results_path, opt.name, data['name'])
            if self.netC:
                gen_mesh_color(opt, self.netG, self.netC, self.cuda, data, save_path, use_octree=use_octree)
            else:
                gen_mesh(opt, self.netG, self.cuda, data, save_path, use_octree=use_octree)
   
if __name__ == '__main__':
    evaluator = Evaluator(opt)
  
    test_images = glob.glob(os.path.join(opt.test_folder_path, '*'))
    test_images = [f for f in test_images if ('png' in f or 'jpg' in f) and (not 'mask' in f)]
    test_masks = [f[:-4]+'_mask.png' for f in test_images]
  
    print("num; ", len(test_masks))
  
    for image_path, mask_path in tqdm.tqdm(zip(test_images, test_masks)):
        try:
            print(image_path, mask_path)
            data = evaluator.load_image(image_path, mask_path)
            evaluator.eval(data, True)
        except Exception as e:
           print("error:", e.args)