from ImageAligner import ImageAligner from ImageSource import ImageSource import cv2 image_source = ImageSource(); #Change this to your location loaded = image_source.load_images("./sources") if(loaded): output_img = ImageAligner().align_image(image_source.primary_image, image_source.secondary_images[0]); cv2.imwrite('./sources/original_warp.png', output_img) output_image = image_source.primary_image for row in range(len(output_img)): for col in range(len(output_img[0])): if output_img[row][col][0] > 0: output_image[row][col] = output_img[row][col] cv2.imwrite('./sources/simple_merge.png', output_image)
# initialize the raspberry pi camera resolution = (arguments.width, arguments.height) picamera = PiCamera(resolution=resolution, framerate=arguments.fps) picamera.resolution = resolution picamera.annotate_background = Color('black') LOGGER.info('camera initialized with x={},y={},fps={}'.format(arguments.width, arguments.height, arguments.fps)) # start the webserver LOGGER.info('setting up environment') mjpg_http_server = MjpegHttpServer(socket_port=8088, bind_address='0.0.0.0') mjpg_http_server.start() LOGGER.info('started webserver') # initialze the stuff processing the images from the mjpg image_source = ImageSource(**{'fps': arguments.fps, 'camera': picamera}) LOGGER.info('started webcam process') mjpg_http_server.start_polling_images(image_source) except KeyboardInterrupt as e: LOGGER.info('got ctrl+c from user') except Exception as e: LOGGER.exception('caught an exception') traceback.print_exc() except ArgumentError as e: LOGGER.exception(e.message) finally: LOGGER.info('have a nice day') if mjpg_http_server is not None: mjpg_http_server.close()
def __init__(self, args): self.args = args self.script_parser = ScriptParser(args) self.image_source = ImageSource(args) self.codec = cv2.VideoWriter_fourcc(*args.codec)
class Animator: def __init__(self, args): self.args = args self.script_parser = ScriptParser(args) self.image_source = ImageSource(args) self.codec = cv2.VideoWriter_fourcc(*args.codec) def parse_script(self): temporal_dict = self.script_parser.parse_script() if len(temporal_dict) == 0: raise ValueError("Script contains no state") self.temporal_dict = temporal_dict if self.args.print_states: temporal_dict.print() return self def animate(self): if self.args.store_new: if self.args.verbose: print("Finding/Generating frames") self.image_source.create_frames(self.temporal_dict.states) if self.args.create_texture: self.create_texture() else: self.create_video() return self def create_texture(self): if self.args.verbose: print("Collecting frames") image_list = list(self.frames) if self.args.verbose: print(f"Creating texture from {len(image_list)} frames") texture = self.stitch_images(image_list) self.save_texture(texture) def save_texture(self, texture): #Defaults to saving texture in full resolution if self.args.texture_dimensions is None: if self.args.verbose: print("Saving full resolution texture") cv2.imwrite(str(self.args.output_path), texture) return #Otherwise we pull out path information to give each produced texture a proper filename original_path = self.args.output_path stem = str(original_path.stem) suffix = str(original_path.suffix) for width, height in self.args.texture_dimensions: if self.args.verbose: print(f"Saving {width}x{height} texture") new_path = str( original_path.with_name(f"{stem}_{width}x{height}{suffix}")) resized = cv2.resize(texture, (width, height), interpolation=cv2.INTER_AREA ) #TODO: make interpolation a CL argument cv2.imwrite(new_path, resized) def create_video(self): if self.args.verbose: print("Writing frames to video") with self.video_writer as video: for frame in self.frames: video.write(frame) @property @contextmanager def video_writer(self): frame = next(self.frames) height, width, layers = frame.shape writer = cv2.VideoWriter(str(self.args.output_path), self.codec, self.args.fps, (width, height)) try: yield writer finally: cv2.destroyAllWindows() writer.release() @property def frames(self): for state in self.temporal_dict.states: yield self.image_source.get_image(state) def stitch_images(self, images): image_matrix = self.get_image_matrix(images) return cv2.vconcat([cv2.hconcat(rows) for rows in image_matrix]) def get_image_matrix(self, images): n = len(images) layout = self.args.texture_layout if layout == "square": width = ceil(n**0.5) height = ceil(n / width) elif layout == "horizontal": width = n height = 1 elif layout == "vertical": width = 1 height = n if n != width * height: images = self.pad_with_blank(images, width, height) return [images[i:i + width] for i in range(0, n, width)] def pad_with_blank(self, images, width, height): image_height, image_width, _ = images[0].shape blank_image = np.zeros((image_height, image_width, 3), np.uint8) padding = [blank_image] * ((width * height) - len(images)) return images + padding
def __init__(self): self.command_line_executor = CommandLineExecutor(self) self.image_aligner = ImageAligner() self.image_blender = ImageBlender() self.image_source = ImageSource()
class AppInstance: """ Class to bind everything together. """ def __init__(self): self.command_line_executor = CommandLineExecutor(self) self.image_aligner = ImageAligner() self.image_blender = ImageBlender() self.image_source = ImageSource() def run_as_commandline_app(self, commands): self.command_line_executor.parse_commands(commands) pending_commands = True while pending_commands: pending_commands = self.command_line_executor.execute_next_command() def run_as_gui_app(self): pass def align_nth_secondary_image(self, secondary_image_index): primary_image = self.image_source.get_primary_image() secondary_image = self.image_source.get_secondary_image(secondary_image_index) if primary_image is None or secondary_image is None: print "[ERROR] AppInstance::align_nth_secondary_image() - primary or secondary image is None" return aligned_image = self.image_aligner.align_image(primary_image, secondary_image) self.image_source.set_aligned_secondary_image(aligned_image, secondary_image_index) if DISPLAY_INTERMEDIATE_RESULTS: window_title = "Intermediate Aligning Result (#" + str(secondary_image_index) + ")" cv2.namedWindow(window_title, cv2.WINDOW_AUTOSIZE) cv2.imshow(window_title, aligned_image) if not os.path.exists(INTERMEDIATE_RESULTS_FOLDER): os.makedirs(INTERMEDIATE_RESULTS_FOLDER) cv2.imwrite(INTERMEDIATE_RESULTS_FOLDER + "/" + window_title + ".jpg", aligned_image) def blend_nth_secondary_image(self, secondary_image_index, x, y, width, height): previous_result_image = self.image_source.get_result_image() secondary_image = self.image_source.get_aligned_secondary_image(secondary_image_index) if previous_result_image is None or secondary_image is None: print "[ERROR] AppInstance::blend_nth_secondary_image() - primary or secondary image is None" return mask_size = (previous_result_image.shape[0], previous_result_image.shape[1]) mask_coordinates = (x, y, width, height) # Create a mask mask = self.image_blender.create_rectangular_mask(mask_size, mask_coordinates) if DISPLAY_INTERMEDIATE_RESULTS: window_title = "Intermediate Blending Mask (#" + str(secondary_image_index) + ")" cv2.namedWindow(window_title, cv2.WINDOW_AUTOSIZE) cv2.imshow(window_title, mask) if not os.path.exists(INTERMEDIATE_RESULTS_FOLDER): os.makedirs(INTERMEDIATE_RESULTS_FOLDER) cv2.imwrite(INTERMEDIATE_RESULTS_FOLDER + "/" + window_title + ".jpg", mask) # Blend the previous result with the secondary image new_result_image = self.image_blender.blend(previous_result_image, secondary_image, mask) if new_result_image is None: print "[ERROR] AppInstance::blend_nth_secondary_image() - blend result is None" return # Update result image in image source self.image_source.set_result_image(new_result_image) if DISPLAY_INTERMEDIATE_RESULTS: window_title = "Intermediate Blending Result (#" + str(secondary_image_index) + ")" cv2.namedWindow(window_title, cv2.WINDOW_AUTOSIZE) cv2.imshow(window_title, new_result_image) if not os.path.exists(INTERMEDIATE_RESULTS_FOLDER): os.makedirs(INTERMEDIATE_RESULTS_FOLDER) cv2.imwrite(INTERMEDIATE_RESULTS_FOLDER + "/" + window_title + ".jpg", new_result_image) def save_result(self, filename): result_image = self.image_source.get_result_image() window_title = "Final Result" cv2.namedWindow(window_title, cv2.WINDOW_AUTOSIZE) cv2.imshow(window_title, result_image) cv2.imwrite(filename, result_image)