From a3c59a4dbdaba7cf6ae280a0663b5471ee0f4662 Mon Sep 17 00:00:00 2001 From: Robin Krens Date: Sat, 27 Jan 2024 15:05:50 +0100 Subject: [PATCH] init: setup haptic extractor with PIL and matplotlib --- haptic-extractor.py | 156 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 156 insertions(+) create mode 100644 haptic-extractor.py diff --git a/haptic-extractor.py b/haptic-extractor.py new file mode 100644 index 0000000..9119a93 --- /dev/null +++ b/haptic-extractor.py @@ -0,0 +1,156 @@ +# +# haptic-extractor.py [option] input_image output +# +# Options +# -v Generate a vertical profile through the image. +# -s generate a 150x100 thummbnail image (default 300x200 pixels) +# -g Draw the profile in green instead of red +# -b Draw the profile in blue instead of red +# +#### +from PIL import Image +import matplotlib.pyplot as plt +import numpy as np +import signal +import sys +import os + +PROGNAME = os.path.basename(sys.argv[0]) +PROGDIR = os.path.dirname(os.path.abspath(sys.argv[0])) + +def usage(message): + """Output the script comments as docs""" + print(f"{PROGNAME}: {' '.join(sys.argv[1:])}") + with open(os.path.join(PROGDIR, PROGNAME), 'r') as script_file: + lines = script_file.readlines()[2:] + for line in lines: + if line.startswith('###'): + break + line = line.strip().lstrip('#').lstrip() + print(line) + + sys.exit(1) + +def error(message): + """Output an error message and exit""" + print(f"{PROGNAME}: {message}") + sys.exit(1) + +COLOR = 'red' +VERTICAL = SMALLER = False + +args = iter(sys.argv[1:]) +for arg in args: + if arg in ('--help', '-h'): + usage() + elif arg == '-v': + VERTICAL = True + elif arg == '-s': + SMALLER = True + elif arg == '-g': + COLOR = 'green' + elif arg == '-b': + COLOR = 'blue' + elif arg in ('-', '--'): + break + elif arg.startswith('-'): + usage(f"Unknown option \"{arg}\"") + else: + break + +if len(sys.argv) == 1: + usage("Missing input_image") + +# Check for too many arguments +if len(sys.argv) > 3: + usage("Too many arguments") + +# Temporary working images with auto-clean-up on exit +input_image = f"/tmp/im_profile_{os.getpid()}.miff" + +def cleanup_handler(signum, frame): + """Cleanup function to be executed on exit""" + os.remove(input_image) + sys.exit(0) + +# Register the cleanup function +#for sig in [0, 1, 2, 3]: +# signal.signal(sig, cleanup_handler) + +try: + input_image_path = sys.argv[1] + output_image_path = "./im_profile_strip.png" + + image = Image.open(input_image_path) + + # Apply the specified vertical transformation + if VERTICAL: + image = image.transpose(Image.Transpose.ROTATE_90) + + # Crop the image to a 1xwidth size at the center of the height + width, height = image.size + strip_height = 1 + top = (height - strip_height) // 2 + bottom = top + strip_height + image = image.crop((0, top, width, bottom)) + + # Save the result + image.save(output_image_path, format="PNG") + +except Exception as e: + print(f"Error: {e}") + sys.exit(1) + +image = Image.open("./im_profile_strip.png") +image = image.convert('L') + +# Resize the image to a 1xN size +#gsize_w = 300 # Replace with your desired gsize_w +#image = image.resize((300, 1), resample=Image.BICUBIC) + +# Convert the image to a NumPy array +image_array = np.array(image) +image_flat = image_array.flatten() + +# Check the bit depth of the image +bit_depth = image_array.dtype.itemsize * 8 + +# Print the values in a format similar to the original script +for value in image_array.flatten(): + print(value, end=' ') + +print(f"\nBit Depth: {bit_depth} bits") + +# plt.plot(image_flat, linestyle='-', linewidth=2, color='blue') + +gsize_w = 100 + +fig, ax = plt.subplots(figsize=(4, 2.25)) # Adjust the figure size as needed + +# Plot the grayscale line plot +ax.plot(image_flat, linestyle='-', linewidth=2, color='gray') + +# Customize x and y ticks +ax.set_xticks([0, 25, 50]) +ax.set_yticks([]) +ax.set_xticklabels([]) +ax.set_yticklabels([]) + +# Add the original image at the bottom +#axins = ax.inset_axes([0, -0.3, 1, 0.3]) +#axins.imshow(image, cmap='gray') + +# Remove x and y tick labels from the inset_axes +#axins.set_xticks([]) +#axins.set_yticks([]) + +fig.subplots_adjust(bottom=0, top=1, hspace=0) + +bottom_image_ax = fig.add_axes([0.05, 0.0, 1, 0.01]) +bottom_image_ax.imshow(image, cmap='gray') +bottom_image_ax.axis('off') + +plt.savefig('output_plot.png', dpi=300, bbox_inches='tight') + +# Show the plot +# plt.show() -- 2.7.4