def transfer_image_style(self, request, context): """Python wrapper to AdaIN Style Transfer written in lua. Receives gRPC request, treats the inputs and creates a thread that executes the lua command.""" # Lua command call arguments. Key = argument name, value = tuple(type, required?, default_value) arguments = { "content": ("image", True, None), "style": ("image", True, None), # "mask": ("image", False, None), Not supported yet, will add once dApp and gRPC work "contentSize": ("int", False, 0), "styleSize": ("int", False, 0), "preserveColor": ("bool", False, None), "alpha": ("double", False, None), # "styleInterpWeights": ???, Not supported yet, will add once dApp and gRPC work "crop": ("bool", False, None), "saveExt": ("string", False, "jpg") } # Treat inputs and assemble lua commands base_command = "th test.lua " command, file_index_str = self.treat_inputs(base_command, request, arguments) command += "-{} {}".format( "outputDir", self.temp_dir) # pre-defined for the service log.debug("Lua command generated: {}".format(command)) # Call style transfer (Lua) process = subprocess.Popen(command.split(), stdout=subprocess.PIPE) process.communicate() # Get output file path output_image_path = self.temp_dir + "contentimage_" + file_index_str \ + "_stylized_styleimage_" + file_index_str + "." + self.saveExt self.created_images.append(output_image_path) # Prepare gRPC output message self.result = Image() self.result.data = service.jpg_to_base64( output_image_path, open_file=True).decode("utf-8") log.debug("Output image generated. Service successfully completed.") # TODO: Clear temp images even if an error occurs for image in self.created_images: service.clear_file(image) return self.result
input_image = \ "https://www.gettyimages.ie/gi-resources/images/Homepage/Hero/UK/CMS_Creative_164657191_Kingfisher.jpg" model = "proSR" scale = 2 # create a stub (client) stub = grpc_bt_grpc.SuperResolutionStub(channel) print("Stub created.") # create a valid request message request = grpc_bt_pb2.SuperResolutionRequest(input=input_image, model=model, scale=scale) # make the call response = stub.increase_image_resolution(request) print("Response received: {}".format(response)) # et voilà output_file_path = "./super_resolution_test_output.jpg" if response.data: base64_to_jpg(response.data, output_file_path) clear_file(output_file_path) print("Service completed!") else: print("Service failed! No data received.") exit(1) except Exception as e: print(e) exit(1)
def transfer_image_style(self, request, context): """Python wrapper to AdaIN Style Transfer written in lua. Receives gRPC request, treats the inputs and creates a thread that executes the lua command.""" # Lua command call arguments. Key = argument name, value = tuple(type, required?, default_value) arguments = { "content": ("image", True, None), "style": ("image", True, None), # "mask": ("image", False, None), Not supported yet, will add once dApp and gRPC work "contentSize": ("int", False, 0), "styleSize": ("int", False, 0), "preserveColor": ("bool", False, None), "alpha": ("double", False, None), # "styleInterpWeights": ???, Not supported yet, will add once dApp and gRPC work "crop": ("bool", False, None), "saveExt": ("string", False, "jpg") } # Treat inputs and assemble lua commands base_command = "th ./service/original-lua-code/test.lua " command, content_file_index_str, style_file_index_str = self.treat_inputs( base_command, request, arguments) command += "-{} {}".format( "outputDir", self.temp_dir) # pre-defined for the service log.debug("Lua command generated: {}".format(command)) # Initializing parameters to reduce image size if necessary content_image_path = self.temp_dir + "contentimage_" + content_file_index_str + "." + self.saveExt style_image_path = self.temp_dir + "styleimage_" + style_file_index_str + "." + self.saveExt # Get output file path output_image_path = self.temp_dir + "contentimage_" + content_file_index_str \ + "_stylized_styleimage_" + style_file_index_str + "." + self.saveExt starting_quality = 95 current_quality = starting_quality reduce_quality_to = 9 / 10 # of input quality reduce_size_to = 4 / 5 # of input size number_of_attempts = 10 resize_output_to_original = False # Retrieving original image size content_image = PIL_Image.open(content_image_path) original_content_size = content_image.size content_image.close() for resize_attempts in range(1, number_of_attempts + 1): # Call style transfer (Lua) process = subprocess.Popen(command.split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE) subprocess_output, subprocess_error = process.communicate() log.debug("Lua subprocess output: {}".format(subprocess_output)) if subprocess_error: log.debug("Lua subprocess error: {}".format(subprocess_error)) try: output_image = PIL_Image.open(output_image_path) self.created_images.append(output_image_path) if resize_output_to_original: output_image = output_image.resize(original_content_size, PIL_Image.ANTIALIAS) output_image.save(output_image_path, quality=starting_quality) break # return output except Exception as e: # TODO: how to identify? log.error(str(e)) process.kill() # Opening content and style images and resizing them according to the number of attempts content_image = PIL_Image.open(content_image_path) style_image = PIL_Image.open(style_image_path) current_content_size = content_image.size current_style_size = style_image.size new_content_size = tuple( round(dim * reduce_size_to) for dim in current_content_size) new_style_size = tuple( round(dim * reduce_size_to) for dim in current_style_size) content_image = content_image.resize(new_content_size, PIL_Image.ANTIALIAS) style_image = style_image.resize(new_style_size, PIL_Image.ANTIALIAS) current_quality = round(current_quality * reduce_quality_to) content_image.save(content_image_path, quality=current_quality) style_image.save(style_image_path, quality=current_quality) content_image.close() style_image.close() log.info( "Could not process image in current size. Reducing content image size from " + str(current_content_size) + " to " + str(new_content_size) + ", style image size from " + str(current_style_size) + " to " + str(new_style_size) + " and trying again. Also reducing JPG quality by " + str(round(1 - reduce_quality_to, 2)) + ".") if "out of memory".encode() in subprocess_error: for image in self.created_images: service.clear_file(image) error = subprocess_error.split(b"\n")[1] log.error(error) raise Exception(error) # Prepare gRPC output message self.result = Image() self.result.data = service.jpg_to_base64( output_image_path, open_file=True).decode("utf-8") log.debug("Output image generated. Service successfully completed.") for image in self.created_images: service.clear_file(image) return self.result
def _exit_handler(self): log.debug('Deleting temporary images before exiting.') for image in self.created_images: service.clear_file(image)
def increase_image_resolution(self, request, context): """Increases the resolution of a given image (request.image) """ # Store the names of the images to delete them afterwards created_images = [] # Python command call arguments. Key = argument name, value = tuple(type, required?, default_value) arguments = { "input": ("image", True, None), "model": ("string", True, None), "scale": ("int", False, 2) } # Treat inputs and assemble command base_command = "python3.6 ./service/increase_resolution.py " try: command, file_index_str = self.treat_inputs( base_command, request, arguments, created_images) except HTTPError as e: error_message = "Error downloading the input image \n" + e.read() log.error(error_message) self.result.data = error_message return self.result except Exception as e: log.error(e) self.result.data = e return self.result command += "--{} {}".format( "output", self.output_dir) # pre-defined for the service log.debug("Python command generated: {}".format(command)) # Call super resolution. If it fails, log error, delete files and exit. process = subprocess.Popen(command.split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE) try: process.communicate() except Exception as e: self.result.data = e log.debug("Returning on exception!") log.error(e) for image in created_images: service.clear_file(image) return self.result # Get output file path log.debug("Returning on service complete!") input_filename = os.path.split(created_images[0])[1] log.debug("Input file name: {}".format(input_filename)) output_image_path = self.output_dir + '/' + input_filename log.debug("Output image path: {}".format(output_image_path)) created_images.append(output_image_path) # Prepare gRPC output message self.result = Image() if input_filename.split('.')[1] == 'png': log.debug("Encoding from PNG.") self.result.data = service.png_to_base64(output_image_path).decode( "utf-8") else: log.debug("Encoding from JPG.") self.result.data = service.jpg_to_base64( output_image_path, open_file=True).decode("utf-8") log.debug("Output image generated. Service successfully completed.") for image in created_images: service.serviceUtils.clear_file(image) return self.result