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 __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 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 getLooksFromPath(seedJsonPath, recursive=True): from Utils.Face.vam import VamFace lookList = [] for root, subdirs, files in os.walk(seedJsonPath): for file in files: if file.endswith(('.json')): try: newFace = VamFace(os.path.join(root, file)) lookList.append(newFace) except: pass if not recursive: break return lookList
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): 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(idx=args.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, args)) proc.start() pool.append(proc) else: pool = None doneEvent.set() angles = [0, 35] skipCnt = 0 screenshots = deque(maxlen=2) for root, subdirs, files in os.walk(inputPath): print("Entering directory {}".format(root)) for file in fnmatch.filter(files, fileFilter): try: anglesToProcess = [] + angles 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) or os.path.exists( "{}.failed".format(fileName)): anglesToProcess.remove(angle) if len(anglesToProcess) == 0: skipCnt += 1 #print("Nothing to do for {}".format(file)) continue print("Processing {} (after skipping {})".format( file, skipCnt)) skipCnt = 0 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 anglesToProcess: face.setRotation(angle) face.save(testJsonPath) vamWindow.loadLook() start = time.time() threshold = 850000000 minTime = .3 screenshots.append(vamWindow.getScreenShot()) while True: screenshots.append(vamWindow.getScreenShot()) diff = ImageChops.difference(screenshots[0], screenshots[1]) imageStat = ImageStat.Stat(diff) s = sum(imageStat.sum2) # Todo: Calculate where blue box will be pix = diff.getpixel((574, 582)) if s < threshold and sum( pix) < 50 and time.time() - start >= minTime: break #print( "{} < {}: {}, {} {}".format(s, threshold, s < threshold, pix, sum(pix) ) ) outputFileName = "{}_angle{}.png".format( os.path.splitext(os.path.basename(inputFile))[0], angle) outputFileName = os.path.join(root, outputFileName) poolWorkQueue.put((screenshots.pop(), outputFileName)) if pool is None: worker_process_func(0, poolWorkQueue, doneEvent, args) except Exception as e: print("Failed to process {} - {}".format(file, str(e))) if not recursive: break print("Generator done!") doneEvent.set() if pool: for proc in pool: proc.join()
def main(args): if args.pydev: print("Enabling debugging with pydev") import pydevd pydevd.settrace(suspend=False) inputPath = args.inputJsonPath basePath = args.baseJsonPath outputPath = args.outputPath dirRotateInterval = args.rotateDirectoryInterval baseFace = VamFace(basePath) baseFace.trimToAnimatable() # Read in all of the files from inputpath inputFaces = [] print("Loading input faces from {}".format(inputPath)) for entry in glob.glob(os.path.join(inputPath, '*.json')): try: newFace = VamFace(entry) # Only keep the relevant morphs morphCnt = len(newFace.morphFloats) newFace.matchMorphs(baseFace) inputFaces.append(newFace) except: print("Error loading {}".format(entry)) print("Loaded {} faces".format(len(inputFaces))) if len(inputFaces) == 0: print("No starting point faces were loaded!") exit(-1) faceCnt = 0 print("Generating variations") mutateChance = .6 mateChance = .7 faceVariants = [] + inputFaces nextRotation = faceCnt + dirRotateInterval rotatedOutputPath = getNextDir(outputPath) while faceCnt < args.numFaces: #for face1 in faceVariants: face1 = faceVariants[random.randint(0, len(faceVariants) - 1)] # Randomly take parameters from the other face shouldMate = random.random() < mateChance shouldMutate = random.random() < mutateChance if shouldMate or shouldMutate: newFace = copy.deepcopy(face1) if shouldMate: mateIdx = random.randint(0, len(faceVariants) - 1) mate(newFace, faceVariants[mateIdx], random.randint(1, len(newFace.morphFloats))) # Randomly apply mutations to the current face if shouldMutate: mutate(newFace, random.randint(0, random.randint(1, 50))) newFace.save( os.path.join( rotatedOutputPath, "face_variant_{}_{}.json".format(faceCnt, random.randint(0, 99999)))) faceVariants.append(newFace) faceCnt += 1 if faceCnt % 500 == 0: print("{}/{}".format(faceCnt, args.numFaces)) if faceCnt >= nextRotation: nextRotation = faceCnt + dirRotateInterval rotatedOutputPath = getNextDir(outputPath)
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()