Path: blob/master/samplelib/SampleGeneratorFacePerson.py
628 views
import copy1import multiprocessing2import traceback34import cv25import numpy as np67from core import mplib8from core.joblib import SubprocessGenerator, ThisThreadGenerator9from facelib import LandmarksProcessor10from samplelib import (SampleGeneratorBase, SampleLoader, SampleProcessor,11SampleType)12131415class Index2DHost():16"""17Provides random shuffled 2D indexes for multiprocesses18"""19def __init__(self, indexes2D):20self.sq = multiprocessing.Queue()21self.cqs = []22self.clis = []23self.thread = threading.Thread(target=self.host_thread, args=(indexes2D,) )24self.thread.daemon = True25self.thread.start()2627def host_thread(self, indexes2D):28indexes_counts_len = len(indexes2D)2930idxs = [*range(indexes_counts_len)]31idxs_2D = [None]*indexes_counts_len32shuffle_idxs = []33shuffle_idxs_2D = [None]*indexes_counts_len34for i in range(indexes_counts_len):35idxs_2D[i] = indexes2D[i]36shuffle_idxs_2D[i] = []3738sq = self.sq3940while True:41while not sq.empty():42obj = sq.get()43cq_id, cmd = obj[0], obj[1]4445if cmd == 0: #get_1D46count = obj[2]4748result = []49for i in range(count):50if len(shuffle_idxs) == 0:51shuffle_idxs = idxs.copy()52np.random.shuffle(shuffle_idxs)53result.append(shuffle_idxs.pop())54self.cqs[cq_id].put (result)55elif cmd == 1: #get_2D56targ_idxs,count = obj[2], obj[3]57result = []5859for targ_idx in targ_idxs:60sub_idxs = []61for i in range(count):62ar = shuffle_idxs_2D[targ_idx]63if len(ar) == 0:64ar = shuffle_idxs_2D[targ_idx] = idxs_2D[targ_idx].copy()65np.random.shuffle(ar)66sub_idxs.append(ar.pop())67result.append (sub_idxs)68self.cqs[cq_id].put (result)6970time.sleep(0.001)7172def create_cli(self):73cq = multiprocessing.Queue()74self.cqs.append ( cq )75cq_id = len(self.cqs)-176return Index2DHost.Cli(self.sq, cq, cq_id)7778# disable pickling79def __getstate__(self):80return dict()81def __setstate__(self, d):82self.__dict__.update(d)8384class Cli():85def __init__(self, sq, cq, cq_id):86self.sq = sq87self.cq = cq88self.cq_id = cq_id8990def get_1D(self, count):91self.sq.put ( (self.cq_id,0, count) )9293while True:94if not self.cq.empty():95return self.cq.get()96time.sleep(0.001)9798def get_2D(self, idxs, count):99self.sq.put ( (self.cq_id,1,idxs,count) )100101while True:102if not self.cq.empty():103return self.cq.get()104time.sleep(0.001)105106'''107arg108output_sample_types = [109[SampleProcessor.TypeFlags, size, (optional) {} opts ] ,110...111]112'''113class SampleGeneratorFacePerson(SampleGeneratorBase):114def __init__ (self, samples_path, debug=False, batch_size=1,115sample_process_options=SampleProcessor.Options(),116output_sample_types=[],117person_id_mode=1,118**kwargs):119120super().__init__(debug, batch_size)121self.sample_process_options = sample_process_options122self.output_sample_types = output_sample_types123self.person_id_mode = person_id_mode124125raise NotImplementedError("Currently SampleGeneratorFacePerson is not implemented.")126127samples_host = SampleLoader.mp_host (SampleType.FACE, samples_path)128samples = samples_host.get_list()129self.samples_len = len(samples)130131if self.samples_len == 0:132raise ValueError('No training data provided.')133134unique_person_names = { sample.person_name for sample in samples }135persons_name_idxs = { person_name : [] for person_name in unique_person_names }136for i,sample in enumerate(samples):137persons_name_idxs[sample.person_name].append (i)138indexes2D = [ persons_name_idxs[person_name] for person_name in unique_person_names ]139index2d_host = Index2DHost(indexes2D)140141if self.debug:142self.generators_count = 1143self.generators = [iter_utils.ThisThreadGenerator ( self.batch_func, (samples_host.create_cli(), index2d_host.create_cli(),) )]144else:145self.generators_count = np.clip(multiprocessing.cpu_count(), 2, 4)146self.generators = [iter_utils.SubprocessGenerator ( self.batch_func, (samples_host.create_cli(), index2d_host.create_cli(),) ) for i in range(self.generators_count) ]147148self.generator_counter = -1149150def __iter__(self):151return self152153def __next__(self):154self.generator_counter += 1155generator = self.generators[self.generator_counter % len(self.generators) ]156return next(generator)157158def batch_func(self, param ):159samples, index2d_host, = param160bs = self.batch_size161162while True:163person_idxs = index2d_host.get_1D(bs)164samples_idxs = index2d_host.get_2D(person_idxs, 1)165166batches = None167for n_batch in range(bs):168person_id = person_idxs[n_batch]169sample_idx = samples_idxs[n_batch][0]170171sample = samples[ sample_idx ]172try:173x, = SampleProcessor.process ([sample], self.sample_process_options, self.output_sample_types, self.debug)174except:175raise Exception ("Exception occured in sample %s. Error: %s" % (sample.filename, traceback.format_exc() ) )176177if batches is None:178batches = [ [] for _ in range(len(x)) ]179180batches += [ [] ]181i_person_id = len(batches)-1182183for i in range(len(x)):184batches[i].append ( x[i] )185186batches[i_person_id].append ( np.array([person_id]) )187188yield [ np.array(batch) for batch in batches]189190@staticmethod191def get_person_id_max_count(samples_path):192return SampleLoader.get_person_id_max_count(samples_path)193194"""195if self.person_id_mode==1:196samples_len = len(samples)197samples_idxs = [*range(samples_len)]198shuffle_idxs = []199elif self.person_id_mode==2:200persons_count = len(samples)201202person_idxs = []203for j in range(persons_count):204for i in range(j+1,persons_count):205person_idxs += [ [i,j] ]206207shuffle_person_idxs = []208209samples_idxs = [None]*persons_count210shuffle_idxs = [None]*persons_count211212for i in range(persons_count):213samples_idxs[i] = [*range(len(samples[i]))]214shuffle_idxs[i] = []215elif self.person_id_mode==3:216persons_count = len(samples)217218person_idxs = [ *range(persons_count) ]219shuffle_person_idxs = []220221samples_idxs = [None]*persons_count222shuffle_idxs = [None]*persons_count223224for i in range(persons_count):225samples_idxs[i] = [*range(len(samples[i]))]226shuffle_idxs[i] = []227228if self.person_id_mode==2:229if len(shuffle_person_idxs) == 0:230shuffle_person_idxs = person_idxs.copy()231np.random.shuffle(shuffle_person_idxs)232person_ids = shuffle_person_idxs.pop()233234235batches = None236for n_batch in range(self.batch_size):237238if self.person_id_mode==1:239if len(shuffle_idxs) == 0:240shuffle_idxs = samples_idxs.copy()241np.random.shuffle(shuffle_idxs) ###242243idx = shuffle_idxs.pop()244sample = samples[ idx ]245246try:247x, = SampleProcessor.process ([sample], self.sample_process_options, self.output_sample_types, self.debug)248except:249raise Exception ("Exception occured in sample %s. Error: %s" % (sample.filename, traceback.format_exc() ) )250251if type(x) != tuple and type(x) != list:252raise Exception('SampleProcessor.process returns NOT tuple/list')253254if batches is None:255batches = [ [] for _ in range(len(x)) ]256257batches += [ [] ]258i_person_id = len(batches)-1259260for i in range(len(x)):261batches[i].append ( x[i] )262263batches[i_person_id].append ( np.array([sample.person_id]) )264265266elif self.person_id_mode==2:267person_id1, person_id2 = person_ids268269if len(shuffle_idxs[person_id1]) == 0:270shuffle_idxs[person_id1] = samples_idxs[person_id1].copy()271np.random.shuffle(shuffle_idxs[person_id1])272273idx = shuffle_idxs[person_id1].pop()274sample1 = samples[person_id1][idx]275276if len(shuffle_idxs[person_id2]) == 0:277shuffle_idxs[person_id2] = samples_idxs[person_id2].copy()278np.random.shuffle(shuffle_idxs[person_id2])279280idx = shuffle_idxs[person_id2].pop()281sample2 = samples[person_id2][idx]282283if sample1 is not None and sample2 is not None:284try:285x1, = SampleProcessor.process ([sample1], self.sample_process_options, self.output_sample_types, self.debug)286except:287raise Exception ("Exception occured in sample %s. Error: %s" % (sample1.filename, traceback.format_exc() ) )288289try:290x2, = SampleProcessor.process ([sample2], self.sample_process_options, self.output_sample_types, self.debug)291except:292raise Exception ("Exception occured in sample %s. Error: %s" % (sample2.filename, traceback.format_exc() ) )293294x1_len = len(x1)295if batches is None:296batches = [ [] for _ in range(x1_len) ]297batches += [ [] ]298i_person_id1 = len(batches)-1299300batches += [ [] for _ in range(len(x2)) ]301batches += [ [] ]302i_person_id2 = len(batches)-1303304for i in range(x1_len):305batches[i].append ( x1[i] )306307for i in range(len(x2)):308batches[x1_len+1+i].append ( x2[i] )309310batches[i_person_id1].append ( np.array([sample1.person_id]) )311312batches[i_person_id2].append ( np.array([sample2.person_id]) )313314elif self.person_id_mode==3:315if len(shuffle_person_idxs) == 0:316shuffle_person_idxs = person_idxs.copy()317np.random.shuffle(shuffle_person_idxs)318person_id = shuffle_person_idxs.pop()319320if len(shuffle_idxs[person_id]) == 0:321shuffle_idxs[person_id] = samples_idxs[person_id].copy()322np.random.shuffle(shuffle_idxs[person_id])323324idx = shuffle_idxs[person_id].pop()325sample1 = samples[person_id][idx]326327if len(shuffle_idxs[person_id]) == 0:328shuffle_idxs[person_id] = samples_idxs[person_id].copy()329np.random.shuffle(shuffle_idxs[person_id])330331idx = shuffle_idxs[person_id].pop()332sample2 = samples[person_id][idx]333334if sample1 is not None and sample2 is not None:335try:336x1, = SampleProcessor.process ([sample1], self.sample_process_options, self.output_sample_types, self.debug)337except:338raise Exception ("Exception occured in sample %s. Error: %s" % (sample1.filename, traceback.format_exc() ) )339340try:341x2, = SampleProcessor.process ([sample2], self.sample_process_options, self.output_sample_types, self.debug)342except:343raise Exception ("Exception occured in sample %s. Error: %s" % (sample2.filename, traceback.format_exc() ) )344345x1_len = len(x1)346if batches is None:347batches = [ [] for _ in range(x1_len) ]348batches += [ [] ]349i_person_id1 = len(batches)-1350351batches += [ [] for _ in range(len(x2)) ]352batches += [ [] ]353i_person_id2 = len(batches)-1354355for i in range(x1_len):356batches[i].append ( x1[i] )357358for i in range(len(x2)):359batches[x1_len+1+i].append ( x2[i] )360361batches[i_person_id1].append ( np.array([sample1.person_id]) )362363batches[i_person_id2].append ( np.array([sample2.person_id]) )364"""365366367