def __init__(self, configJson, basePath=""): minJson = os.path.join( basePath, configJson["minJson"]) if "minJson" in configJson else None maxJson = os.path.join( basePath, configJson["maxJson"]) if "maxJson" in configJson else None self._baseFace = VamFace( os.path.join(basePath, configJson["baseJson"]), minJson, maxJson) self._baseFace.trimToAnimatable() self._paramShape = None angles = set() self._input_params = [] if "inputs" in configJson: inputs = configJson["inputs"] for param in inputs: try: paramName = param["name"] paramList = [] for paramParam in param["params"]: paramList.append({ "name": paramParam["name"], "value": paramParam["value"] }) if paramParam["name"] == "angle": angles.add(float(paramParam["value"])) self._input_params.append({ "name": paramName, "params": paramList }) except: print("Error parsing parameter") self._output_params = [] if "outputs" in configJson: outputs = configJson["outputs"] for param in outputs: try: paramName = param["name"] paramList = [] for paramParam in param["params"]: paramList.append({ "name": paramParam["name"], "value": paramParam["value"] }) if paramParam["name"] == "angle": angles.add(float(paramParam["value"])) self._output_params.append({ "name": paramName, "params": paramList }) except: print("Error parsing parameter") self._angles = list(angles) self._angles.sort()
def __init__(self, paramConfig, requiredAngles, relatedFiles, baseFace): self._config = paramConfig self._encodings = [] self._vamFaces = [] self._angles = requiredAngles self._angles.sort() self._facebuckets = {} self._baseFace = baseFace self._generators = { "encoding": self._encodingParams, "json": self._jsonParams, "eye_mouth_ratio": self._eye_mouth_ratio_params, "mouth_chin_ratio": self._mouth_chin_ratio_params, "eye_height_width_ratio": self._eye_height_width_ratio_params, "nose_height_width_ratio": self._nose_height_width_ratio_params, "brow_height_width_ratio": self._brow_height_width_ratio_params, "brow_chin_ratio": self._brow_chin_ratio_params, "custom_action": self._custom_action } for angle in self._angles: self._facebuckets[angle] = [] # Read all encodings in from the file list for file in relatedFiles: try: if isinstance(file, EncodedFace): newFace = file else: newFace = EncodedFace.createFromFile(file) self._encodings.append(newFace) except: try: vamFace = VamFace(file) vamFace.matchMorphs(baseFace) self._vamFaces.append(vamFace) except: continue # Now put the encodings into the bucket with the closest angle for encoding in self._encodings: nearestBucket = abs(self._angles[0]) for angle in self._angles: if abs(abs(encoding.getAngle()) - abs(angle)) < abs( abs(encoding.getAngle()) - abs(nearestBucket)): nearestBucket = abs(angle) self._facebuckets[nearestBucket].append(encoding)
def main( args ): if args.pydev: print("Enabling debugging with pydev") import pydevd pydevd.settrace(suspend=False) templateFace = VamFace( args.templateJson ) invertTemplate = args.invertTemplate templateFace.trimToAnimatable() fromFace = VamFace( args.fromJson, discardExtra = False ) fileFilter = args.filter inputDir = args.toJsonDir outputDir = args.outputJsonDir for root, subdirs, files in os.walk(inputDir): print("Entering directory {}".format(root)) for file in fnmatch.filter(files, fileFilter): try: toName = os.path.splitext(file)[0] outDir = root.lstrip(inputDir) outDir = outDir.lstrip('/') outDir = outDir.lstrip('\\') outDir = os.path.join( outputDir, outDir ) outName = "{}_mergedWith_{}.json".format( os.path.splitext(file)[0], os.path.splitext(os.path.basename(args.fromJson))[0]) toFace = VamFace( os.path.join(root, file), discardExtra = False ) newFace = VamFace.mergeFaces( templateFace=templateFace, toFace=toFace, fromFace=fromFace, invertTemplate = invertTemplate, copyNonMorphs = True) try: os.makedirs(outDir) except: pass outputName = os.path.join(outDir, outName ) newFace.save( outputName ) print( "Generated {}".format(outputName ) ) except Exception as e: print("Error merging {} - {}".format(file, str(e)))
def main(args): if args.pydev: print("Enabling debugging with pydev") import pydevd pydevd.settrace(suspend=False) inputPath = args.inputPath outputName = args.outputName face = None encoding = None for root, subdirs, files in os.walk(inputPath): outCsvFile = os.path.join(root, outputName) outFile = None print("Entering {}".format(root)) for file in fnmatch.filter(files, '*.json'): # Check if we have all support encodings for this json basename = os.path.splitext(file)[0] encodingFiles = [ "{}_angle0.encoding".format(basename), "{}_angle35.encoding".format(basename) ] hasAllFiles = True for idx, encodingFile in enumerate(encodingFiles): encodingFile = os.path.join(root, encodingFile) encodingFiles[idx] = encodingFile if not os.path.exists(encodingFile): hasAllFiles = False break if not hasAllFiles: print("Skipping {} since it does not have all encoding files". format(file)) continue # Have all encodings? Read them in outArray = [] for encodingFile in encodingFiles: encoding = open(encodingFile).read().splitlines() outArray.extend(encoding) face = VamFace(os.path.join(root, file)) outArray.extend(face.morphFloats) if outFile is None: print("Creating {}".format(outCsvFile)) outFile = open(outCsvFile, 'w') writer = csv.writer(outFile, lineterminator='\n') writer.writerow(outArray) if not args.recursive: # Don't go any further down if not recursive! break
def main(args): if args.pydev: print("Enabling debugging with pydev") import pydevd pydevd.settrace(suspend=False) # Delay heavy imports from keras.models import load_model # Work around low-memory GPU issue import tensorflow as tf config = tf.ConfigProto() config.gpu_options.allow_growth = True session = tf.Session(config=config) modelFile = args.modelFile inputGlob = args.inputEncoding outputDir = args.outputDir baseJson = args.baseJson archiveDir = args.archiveDir face = VamFace(baseJson) face.trimToAnimatable() model = load_model(modelFile) modelName = os.path.splitext(os.path.basename(modelFile))[0] if archiveDir: try: os.makedirs(archiveDir) except: pass for entry in glob.glob(inputGlob): try: encodingFile = "{}_angle0.encoding".format( os.path.splitext(entry)[0]) encodingFile1 = "{}_angle35.encoding".format( os.path.splitext(entry)[0]) outArray = [] if os.path.exists(encodingFile) and os.path.exists(encodingFile1): with open(encodingFile) as f: encoding = f.read().splitlines() outArray = encoding with open(encodingFile1) as f: encoding = f.read().splitlines() outArray.extend(encoding) else: print("Missing encoding file {} or {}".format( encodingFile, encodingFile1)) dataSet = numpy.array([outArray]) predictions = model.predict(dataSet) rounded = [float(round(x, 5)) for x in predictions[0]] face.importFloatList(rounded) entryName = os.path.splitext(os.path.basename(entry))[0] outputFile = "{}_{}.json".format(entryName, modelName) outputFile = os.path.join(outputDir, outputFile) if args.archiveDir and os.path.exists(outputFile): dateString = datetime.datetime.now().strftime( "%Y-%m-%d_%H_%M_%S") backupFileName = os.path.splitext( os.path.basename(outputFile))[0] backupFileName = os.path.join( args.archiveDir, "{}_{}.json".format(backupFileName, dateString)) print("Backing up {} to {}".format(outputFile, backupFileName)) shutil.copyfile(outputFile, backupFileName) face.save(outputFile) print("Prediction saved to {}".format(outputFile)) except Exception as e: print("Failed to process {}: {}".format(entry, e))
def main( args ): global testJsonPath global outputPath if args.pydev: print("Enabling debugging with pydev") import pydevd pydevd.settrace(suspend=False) inputPath = args.inputJsonPath #outputPath = args.outputPath outputPath = "-" testJsonPath = args.testJsonPath numThreads = args.numThreads recursive = args.recursive fileFilter = args.filter print( "Input path: {}\nOutput path: {}\n\n".format( inputPath, outputPath ) ) # Initialize the Vam window vamWindow = VamWindow() # Locating the buttons via image comparison does not reliably work. These coordinates are the 'Window' coordinates # found via AutoHotKey's Window Spy, cooresponding to the Load Preset button and the location of the test file vamWindow.setClickLocations([(130,39), (248,178)]) print("Initializing worker processes...") poolWorkQueue = multiprocessing.Queue(maxsize=200) doneEvent = multiprocessing.Event() if numThreads > 1: pool = [] for idx in range(numThreads): proc = multiprocessing.Process(target=worker_process_func, args=(idx, poolWorkQueue, doneEvent) ) proc.start() pool.append( proc ) else: pool = None doneEvent.set() angles = [0, 35, 65] for root, subdirs, files in os.walk(inputPath): print("Entering directory {}".format(root)) for file in fnmatch.filter(files, fileFilter): print("Processing {}".format(file)) try: alreadyDone = False for angle in angles: fileName = "{}_angle{}.png".format( os.path.splitext(file)[0], angle) fileName = os.path.join( root,fileName) if os.path.exists(fileName): alreadyDone = True print("Output file already exists. Skipping.") break if alreadyDone: continue if (GetKeyState(VK_CAPITAL) or GetKeyState(VK_SCROLL)): print("WARNING: Suspending script due to Caps Lock or Scroll Lock being on. Push CTRL+PAUSE/BREAK or mash CTRL+C to exit script.") while GetKeyState(VK_CAPITAL) or GetKeyState(VK_SCROLL): time.sleep(1) # Get screenshots of face and submit them to worker threads inputFile = os.path.join( root, file ) face = VamFace(inputFile) for angle in angles: face.setRotation(angle) face.save( testJsonPath ) vamWindow.loadLook() time.sleep(.3) img = vamWindow.getScreenShot() outputFileName = "{}_angle{}.png".format( os.path.splitext(os.path.basename(inputFile))[0], angle) outputFileName = os.path.join( root, outputFileName ) poolWorkQueue.put( (img, outputFileName)) if pool is None: worker_process_func(0, poolWorkQueue, doneEvent) except: print("Failed to process {}".format(file)) if not recursive: break print("Generator done!") doneEvent.set() if pool: for proc in pool: proc.join()
class Config: CONFIG_VERSION = 1 def __init__(self, configJson, basePath=""): minJson = os.path.join( basePath, configJson["minJson"]) if "minJson" in configJson else None maxJson = os.path.join( basePath, configJson["maxJson"]) if "maxJson" in configJson else None self._baseFace = VamFace( os.path.join(basePath, configJson["baseJson"]), minJson, maxJson) self._baseFace.trimToAnimatable() self._paramShape = None angles = set() self._input_params = [] if "inputs" in configJson: inputs = configJson["inputs"] for param in inputs: try: paramName = param["name"] paramList = [] for paramParam in param["params"]: paramList.append({ "name": paramParam["name"], "value": paramParam["value"] }) if paramParam["name"] == "angle": angles.add(float(paramParam["value"])) self._input_params.append({ "name": paramName, "params": paramList }) except: print("Error parsing parameter") self._output_params = [] if "outputs" in configJson: outputs = configJson["outputs"] for param in outputs: try: paramName = param["name"] paramList = [] for paramParam in param["params"]: paramList.append({ "name": paramParam["name"], "value": paramParam["value"] }) if paramParam["name"] == "angle": angles.add(float(paramParam["value"])) self._output_params.append({ "name": paramName, "params": paramList }) except: print("Error parsing parameter") self._angles = list(angles) self._angles.sort() @staticmethod def createFromFile(fileName): data = open(fileName).read() jsonData = json.loads(data) if "config_version" in jsonData and jsonData[ "config_version"] is not Config.CONFIG_VERSION: raise Exception( "Config version mismatch! File was {}, reader was {}".format( jsonData["config_version"], Config.CONFIG_VERSION)) return Config(jsonData, os.path.dirname(fileName)) def getBaseFace(self): return self._baseFace def getShape(self): return self._paramShape def getAngles(self): return self._angles def generateParams(self, relatedFiles): if self._paramShape is None: paramGen = ParamGenerator(self._input_params, self._angles, relatedFiles, self._baseFace) inputParams = paramGen.getParams() inputLen = len(inputParams) paramGen = ParamGenerator(self._output_params, self._angles, relatedFiles, self._baseFace) outputParams = paramGen.getParams() outputLen = len(outputParams) self._paramShape = (inputLen, outputLen) outParams = inputParams + outputParams else: paramGen = ParamGenerator(self._input_params + self._output_params, self._angles, relatedFiles, self._baseFace) outParams = paramGen.getParams() return outParams