Add vibe-coded image anonymizer

This commit is contained in:
jaseg 2026-02-05 17:58:33 +01:00
parent 7c9fd005d0
commit a57bc565cf
2 changed files with 156 additions and 60 deletions

99
anonymize_images.py Normal file
View file

@ -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()

117
paper.tex
View file

@ -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}\\