Added copy function to be able to place files to outdir before modification. Added verbose output about what it going to happen. Added table header for output. Removed obsolete "Processing..." message, as it was never visible.
		
			
				
	
	
		
			96 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			96 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
| #!/usr/bin/env python
 | |
| # -*- coding: utf-8 -*-
 | |
| 
 | |
| """Iterates over a bunch of .jpg or .cr2 files and matches 
 | |
| DateTimeOriginal from Exif tag to DateTime in a csv log 
 | |
| of a GeigerMuellerCounter and writes its value to the UserComment
 | |
| Exif tag in µS/h"""
 | |
| 
 | |
| from datetime import datetime
 | |
| import os
 | |
| import shutil
 | |
| import csv
 | |
| import argparse
 | |
| import pyexiv2
 | |
| 
 | |
| # SIFACTOR for GQ Geiger counters
 | |
| 
 | |
| # 300  series: 0.0065   µSv/h / CPM
 | |
| # 320  series: 0.0065   µSv/h / CPM
 | |
| # 500  series: 0.0065   µSv/h / CPM
 | |
| # 500+ series: 0.0065   µSv/h / CPM for the first tube
 | |
| # 600  series: 0.0065   µSv/h / CPM
 | |
| # 600+ series: 0.002637 µSv/h / CPM
 | |
| 
 | |
| # Configure argument parser for cli options
 | |
| parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter, 
 | |
|                                  description='''A tool that writes 
 | |
|     radiation levels (and optionally geocoordinates) to image files 
 | |
|     and extracts the infos from external sources.''')
 | |
| parser.add_argument('-si', '--sifactor', type=float, default=0.0065, 
 | |
|                     help='Factor to multiply recorded CPM with.')
 | |
| parser.add_argument('csv', metavar='CSV', type=str, 
 | |
|                     help='Geiger counter history file in CSV format.')
 | |
| parser.add_argument('photos', metavar='Photo', type=str, nargs='+', 
 | |
|                     help='One or multiple photo image files to process.')
 | |
| parser.add_argument('-o', '--outdir', type=str, default='.', 
 | |
|                     help='Directory to output processed photos')
 | |
| 
 | |
| args = parser.parse_args()
 | |
| 
 | |
| # Inform the user about what is going to happen
 | |
| if args.outdir == ".":
 | |
|     print('Modifying photos in place (overwrite)')
 | |
| else:
 | |
|     print('Modifying photos in', str(args.outdir), '(copy)')
 | |
| # Print table header
 | |
| print('{:<15} {:<20} {:<22}'.format('filename', 'date / time', 'Exif UserComment'))
 | |
| 
 | |
| for srcphoto in args.photos:
 | |
|     # Get image file name out of path
 | |
|     photo_basename = os.path.basename(srcphoto)
 | |
| 
 | |
|     # Decide whether to modify photo in place or to copy it to outdir first
 | |
|     # Then set the destination file as 'photo' to work on
 | |
|     if args.outdir == ".":
 | |
|         photo = srcphoto
 | |
|     else:
 | |
|         # be os aware and use the correct directory delimiter for destfile
 | |
|         dstphoto = os.path.join(args.outdir, photo_basename)
 | |
|         shutil.copy(srcphoto, dstphoto)
 | |
|         photo = dstphoto
 | |
| 
 | |
|     # Load Exif data from image
 | |
|     metadata = pyexiv2.ImageMetadata(photo)
 | |
|     metadata.read()
 | |
|     tag = metadata['Exif.Photo.DateTimeOriginal']
 | |
|     # tag.value creates datetime object in pictime
 | |
|     pictime = tag.value
 | |
|     
 | |
|     # Import GeigerCounter log
 | |
|     with open(args.csv, "r") as f:
 | |
|         csvreader = csv.reader(filter(lambda row: row[0] != '#', f), 
 | |
|                                delimiter=',', skipinitialspace=True)
 | |
| 
 | |
|         print('Processing file:', photo_basename, end='\r')
 | |
|         for _, csvrawtime, csvrawcpm, _ in csvreader:
 | |
|             csvtime = datetime.fromisoformat(csvrawtime)
 | |
|             # Process image if its timestamp is found in CSV log (compares 2 datetime objects)
 | |
|             if csvtime == pictime:
 | |
|                 rad = round(float(csvrawcpm) * args.sifactor, 2)
 | |
| 
 | |
|                 # Set key, value for new UserComment
 | |
|                 key = 'Exif.Photo.UserComment'
 | |
|                 new_comment = 'Radiation ☢ ' + str(rad) + ' µS/h'
 | |
|                 metadata[key] = pyexiv2.ExifTag(key, new_comment)
 | |
|                 
 | |
|                 # print found radiation levels
 | |
|                 print('{:<15} {:<20} {:<22}'.format(photo_basename, str(pictime), new_comment))
 | |
|                 # Write Exif tags to file
 | |
|                 metadata.write()
 | |
|                 break
 | |
|         else:
 | |
|             print('{:<15} {:<20} {:<22}'.format(photo_basename, str(pictime), 'NOT FOUND!'))
 | |
|     # close CSV file
 | |
|     f.close()
 |