init: setup haptic extractor with PIL and matplotlib
authorRobin Krens <robin@robinkrens.nl>
Sat, 27 Jan 2024 14:05:50 +0000 (15:05 +0100)
committerRobin Krens <robin@robinkrens.nl>
Sat, 27 Jan 2024 14:05:50 +0000 (15:05 +0100)
haptic-extractor.py [new file with mode: 0644]

diff --git a/haptic-extractor.py b/haptic-extractor.py
new file mode 100644 (file)
index 0000000..9119a93
--- /dev/null
@@ -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()