From a57bc565cfd03f658db6fc9f5bcf923413e46f81 Mon Sep 17 00:00:00 2001 From: jaseg Date: Thu, 5 Feb 2026 17:58:33 +0100 Subject: [PATCH] Add vibe-coded image anonymizer --- anonymize_images.py | 99 +++++++++++++++++++++++++++++++++++++ paper.tex | 117 +++++++++++++++++++++----------------------- 2 files changed, 156 insertions(+), 60 deletions(-) create mode 100644 anonymize_images.py diff --git a/anonymize_images.py b/anonymize_images.py new file mode 100644 index 0000000..90d3ef6 --- /dev/null +++ b/anonymize_images.py @@ -0,0 +1,99 @@ +#!/usr/bin/env python3 +""" +Script to anonymize survey images by overlaying a black bar at the bottom. +The black bar is 50% of image width and 25% of image height, horizontally centered. +""" + +from PIL import Image, ImageDraw +import os +import sys + +def anonymize_image(input_path, output_path, img_id, internal=False): + """ + Add a black bar to the bottom of an image. + Bar dimensions: 50% width, 25% height, centered horizontally at bottom. + """ + # Open the image + img = Image.open(input_path) + width, height = img.size + + # Calculate bar dimensions + bar_width = int(width * 0.8) + if internal: + bar_height = height * (0.45 if img_id in ['01', '02', '15', '24', '27'] else 0.35) + else: + bar_height = height * (0.4 if img_id in ['31', '32'] else 0.28) + bar_height = int(bar_height) + + # Calculate bar position (centered horizontally, at bottom) + bar_x = (width - bar_width) // 2 + bar_y = height - bar_height + + # Create a drawing context + draw = ImageDraw.Draw(img) + + # Draw black rectangle + draw.rectangle( + [(bar_x, bar_y), (bar_x + bar_width, height)], + fill='black' + ) + + # Save the anonymized image + img.save(output_path, quality=95) + print(f"Processed: {input_path} -> {output_path}") + +def main(): + # List of image IDs to process for external survey images + image_ids = [ + '02', '03', '04', '05', '06', + '08', '09', '10', '11', '12', + '13', '14', '15', '16', '17', + '18', '19', '20', '21', '22', + '23', '24', '25', '27', '28', + '29', '30', '31', '32' + ] + + # Internal survey images to process (with their number prefixes) + # Excluding H30, H31, H32 as requested + internal_images = [ + ('01', '09'), ('02', '20'), ('03', '11'), ('04', '03'), ('05', '10'), + ('06', '08'), ('08', '24'), ('09', '13'), ('10', '23'), ('11', '17'), + ('12', '19'), ('13', '02'), ('14', '00'), ('14', '01'), ('15', '04'), + ('16', '05'), ('17', '22'), ('18', '21'), ('19', '26'), ('20', '12'), + ('21', '15'), ('22', '16'), ('23', '07'), ('24', '06'), ('25', '25'), + ('27', '18'), ('28', '14') + ] + + # Directory containing images + figures_dir = 'figures' + + # Process external survey images + print("Processing external survey images...") + for img_id in image_ids: + input_filename = os.path.join(figures_dir, f"survey_diag_S{img_id}.jpg") + output_filename = os.path.join(figures_dir, f"survey_diag_S{img_id}_anon.jpg") + + if os.path.exists(input_filename): + try: + anonymize_image(input_filename, output_filename, img_id, internal=False) + except Exception as e: + print(f"Error processing {input_filename}: {e}", file=sys.stderr) + else: + print(f"Warning: {input_filename} not found", file=sys.stderr) + + # Process internal survey images + print("\nProcessing internal survey images...") + for specimen_id, number in internal_images: + input_filename = os.path.join(figures_dir, f"survey_internal_{number}_S{specimen_id}.jpg") + output_filename = os.path.join(figures_dir, f"survey_internal_{number}_S{specimen_id}_anon.jpg") + + if os.path.exists(input_filename): + try: + anonymize_image(input_filename, output_filename, specimen_id, internal=True) + except Exception as e: + print(f"Error processing {input_filename}: {e}", file=sys.stderr) + else: + print(f"Warning: {input_filename} not found", file=sys.stderr) + +if __name__ == "__main__": + main() diff --git a/paper.tex b/paper.tex index fe04c5d..143f372 100644 --- a/paper.tex +++ b/paper.tex @@ -59,10 +59,7 @@ %} \author{ -{\rm Author}\\ -Institution -\and -{\rm Author}\\ +{\rm Authors}\\ Institution } @@ -410,35 +407,35 @@ devices we selected for this study. \begin{figure} \setlength{\tabcolsep}{0mm} \begin{tabular}[c]{ccccc} - \surveypic{02}{survey_diag_S02.jpg}& - \surveypic{03}{survey_diag_S03.jpg}& - \surveypic{04}{survey_diag_S04.jpg}& - \surveypic{05}{survey_diag_S05.jpg}& - \surveypic{06}{survey_diag_S06.jpg}\\ - \surveypic{08}{survey_diag_S08.jpg}& - \surveypic{09}{survey_diag_S09.jpg}& - \surveypic{10}{survey_diag_S10.jpg}& - \surveypic{11}{survey_diag_S11.jpg}& - \surveypic{12}{survey_diag_S12.jpg}\\ - \surveypic{13}{survey_diag_S13.jpg}& - \surveypic{14}{survey_diag_S14.jpg}& - \surveypic{15}{survey_diag_S15.jpg}& - \surveypic{16}{survey_diag_S16.jpg}& - \surveypic{17}{survey_diag_S17.jpg}\\ - \surveypic{18}{survey_diag_S18.jpg}& - \surveypic{19}{survey_diag_S19.jpg}& - \surveypic{20}{survey_diag_S20.jpg}& - \surveypic{21}{survey_diag_S21.jpg}& - \surveypic{22}{survey_diag_S22.jpg}\\ - \surveypic{23}{survey_diag_S23.jpg}& - \surveypic{24}{survey_diag_S24.jpg}& - \surveypic{25}{survey_diag_S25.jpg}& - \surveypic{27}{survey_diag_S27.jpg}& - \surveypic{28}{survey_diag_S28.jpg}\\ - \surveypic{29}{survey_diag_S29.jpg}& - \surveypic{30}{survey_diag_S30.jpg}& - \surveypic{31}{survey_diag_S31.jpg}& - \surveypic{32}{survey_diag_S32.jpg}& + \surveypic{02}{survey_diag_S02_anon.jpg}& + \surveypic{03}{survey_diag_S03_anon.jpg}& + \surveypic{04}{survey_diag_S04_anon.jpg}& + \surveypic{05}{survey_diag_S05_anon.jpg}& + \surveypic{06}{survey_diag_S06_anon.jpg}\\ + \surveypic{08}{survey_diag_S08_anon.jpg}& + \surveypic{09}{survey_diag_S09_anon.jpg}& + \surveypic{10}{survey_diag_S10_anon.jpg}& + \surveypic{11}{survey_diag_S11_anon.jpg}& + \surveypic{12}{survey_diag_S12_anon.jpg}\\ + \surveypic{13}{survey_diag_S13_anon.jpg}& + \surveypic{14}{survey_diag_S14_anon.jpg}& + \surveypic{15}{survey_diag_S15_anon.jpg}& + \surveypic{16}{survey_diag_S16_anon.jpg}& + \surveypic{17}{survey_diag_S17_anon.jpg}\\ + \surveypic{18}{survey_diag_S18_anon.jpg}& + \surveypic{19}{survey_diag_S19_anon.jpg}& + \surveypic{20}{survey_diag_S20_anon.jpg}& + \surveypic{21}{survey_diag_S21_anon.jpg}& + \surveypic{22}{survey_diag_S22_anon.jpg}\\ + \surveypic{23}{survey_diag_S23_anon.jpg}& + \surveypic{24}{survey_diag_S24_anon.jpg}& + \surveypic{25}{survey_diag_S25_anon.jpg}& + \surveypic{27}{survey_diag_S27_anon.jpg}& + \surveypic{28}{survey_diag_S28_anon.jpg}\\ + \surveypic{29}{survey_diag_S29_anon.jpg}& + \surveypic{30}{survey_diag_S30_anon.jpg}& + \surveypic{31}{survey_diag_S31_anon.jpg}& + \surveypic{32}{survey_diag_S32_anon.jpg}& \end{tabular} \caption[Tamper sensing mesh survey specimen external photos]{External photos of all survey specimens.} \label{fig_hsm_survey_sample_pics} @@ -538,33 +535,33 @@ cutting and prying, and applying heat from a heat gun as necessary to soften pol \begin{figure} \setlength{\tabcolsep}{0mm} \begin{tabular}[c]{ccccc} - \surveypic{01}{survey_internal_09_S01.jpg}& - \surveypic{02}{survey_internal_20_S02.jpg}& - \surveypic{03}{survey_internal_11_S03.jpg}& - \surveypic{04}{survey_internal_03_S04.jpg}& - \surveypic{05}{survey_internal_10_S05.jpg}\\ - \surveypic{06}{survey_internal_08_S06.jpg}& - \surveypic{08}{survey_internal_24_S08.jpg}& - \surveypic{09}{survey_internal_13_S09.jpg}& - \surveypic{10}{survey_internal_23_S10.jpg}& - \surveypic{11}{survey_internal_17_S11.jpg}\\ - \surveypic{12}{survey_internal_19_S12.jpg}& - \surveypic{13}{survey_internal_02_S13.jpg}& - \surveypic{14}{survey_internal_00_S14.jpg}& - \surveypic{14}{survey_internal_01_S14.jpg}& - \surveypic{15}{survey_internal_04_S15.jpg}\\ - \surveypic{16}{survey_internal_05_S16.jpg}& - \surveypic{17}{survey_internal_22_S17.jpg}& - \surveypic{18}{survey_internal_21_S18.jpg}& - \surveypic{19}{survey_internal_26_S19.jpg}& - \surveypic{20}{survey_internal_12_S20.jpg}\\ - \surveypic{21}{survey_internal_15_S21.jpg}& - \surveypic{22}{survey_internal_16_S22.jpg}& - \surveypic{23}{survey_internal_07_S23.jpg}& - \surveypic{24}{survey_internal_06_S24.jpg}& - \surveypic{25}{survey_internal_25_S25.jpg}\\ - \surveypic{27}{survey_internal_18_S27.jpg}& - \surveypic{28}{survey_internal_14_S28.jpg}& + \surveypic{01}{survey_internal_09_S01_anon.jpg}& + \surveypic{02}{survey_internal_20_S02_anon.jpg}& + \surveypic{03}{survey_internal_11_S03_anon.jpg}& + \surveypic{04}{survey_internal_03_S04_anon.jpg}& + \surveypic{05}{survey_internal_10_S05_anon.jpg}\\ + \surveypic{06}{survey_internal_08_S06_anon.jpg}& + \surveypic{08}{survey_internal_24_S08_anon.jpg}& + \surveypic{09}{survey_internal_13_S09_anon.jpg}& + \surveypic{10}{survey_internal_23_S10_anon.jpg}& + \surveypic{11}{survey_internal_17_S11_anon.jpg}\\ + \surveypic{12}{survey_internal_19_S12_anon.jpg}& + \surveypic{13}{survey_internal_02_S13_anon.jpg}& + \surveypic{14}{survey_internal_00_S14_anon.jpg}& + \surveypic{14}{survey_internal_01_S14_anon.jpg}& + \surveypic{15}{survey_internal_04_S15_anon.jpg}\\ + \surveypic{16}{survey_internal_05_S16_anon.jpg}& + \surveypic{17}{survey_internal_22_S17_anon.jpg}& + \surveypic{18}{survey_internal_21_S18_anon.jpg}& + \surveypic{19}{survey_internal_26_S19_anon.jpg}& + \surveypic{20}{survey_internal_12_S20_anon.jpg}\\ + \surveypic{21}{survey_internal_15_S21_anon.jpg}& + \surveypic{22}{survey_internal_16_S22_anon.jpg}& + \surveypic{23}{survey_internal_07_S23_anon.jpg}& + \surveypic{24}{survey_internal_06_S24_anon.jpg}& + \surveypic{25}{survey_internal_25_S25_anon.jpg}\\ + \surveypic{27}{survey_internal_18_S27_anon.jpg}& + \surveypic{28}{survey_internal_14_S28_anon.jpg}& \surveypic{30}{survey_internal_29_S30.jpg}& \surveypic{31}{survey_internal_27_S31.jpg}& \surveypic{32}{survey_internal_28_S32.jpg}\\