#!/usr/bin/python
# ##############################################################################
# Filename: image2date.py
# Author: Joshua Kugler, joshua@eeinternet.com
# Copyright Information: (C) 2007, EEInternet, Joshua Kugler
# License Information: Public Domain
# Synopsis: Extracts an area from an image, and does OCR to obtain the date
# Comments: Requires gocr to be installed
# Info: $Id: image2date.py 56 2007-10-11 20:08:01Z jkugler $
# ##############################################################################
def err(msg, do_exit=True):
import sys
sys.stderr.write(msg + '\n')
if do_exit:
sys.stdout.write('')
sys.exit(1)
def do_ocr(filename, left, top, right, bottom, date_format, output_format, strip_chars='', invert=True, debug=False, ocr='gocr'):
import os
import subprocess
import tempfile
import time
import Image
import ImageChops
try:
im = Image.open(filename)
except IOError, e:
err('Cannot open image file %s: %s' % (filename, e.strerror))
im = im.crop((left, top, right , bottom))
# Converts to black and white because OCR works better that way.
im = im.convert('L')
# Web cams need seem to like light-on-dark text, so we usually invert
if invert:
im = ImageChops.invert(im)
# Get a temporary file so we can save the image.
(fd, tf) = tempfile.mkstemp(suffix='.ppm', dir='/tmp')
im.save(tf)
os.close(fd)
try:
ocr_output = subprocess.Popen([ocr, tf], stdout=subprocess.PIPE).communicate()[0]
except OSError, e:
os.remove(tf)
err('Could not execute OCR program "%s": %s' % (ocr, str(e)))
os.remove(tf)
ocr_output = ocr_output.strip()
# Fixes a glitch whereby gocr recognizes two ones as 'll'
# Seems to do fine with single ones. Odd.
ocr_output = ocr_output.replace('ll','11')
if debug:
err("Raw OCR: '%s'" % ocr_output, False)
if strip_chars:
ocr_output = ocr_output.replace(strip_chars,'')
if debug:
err("Stripped OCR: %s" % ocr_output, False)
try:
time_data = time.strptime(ocr_output, date_format)
except ValueError, e:
err('Cannot decode time """%s""": %s' % (ocr_output, str(e)))
if debug:
err('Time data: %s' % str(time_data), False)
formatted_filename = time.strftime(output_format, time_data)
return(formatted_filename)
def main():
import optparse
import sys
usage = 'image2date --date-format=DATE_FORMAT --left=N --right=N --bottom=N [options] FILENAME'
_VERSION_ = '1.0'
parser = optparse.OptionParser(usage=usage, version = '%prog ' + _VERSION_)
parser.add_option('--date-format', dest='date_format',
help='Format of the date being extracted. See documentation of Python time module for more information', default=None)
parser.add_option('--output-format', dest='output_format',
help='Format of the date printed. See documenation of Python time module for more information', default='%Y-%m-%d-%H-%M')
parser.add_option('--strip-chars', dest='strip_chars', help='Characters to strip from the OCRed text', default='')
parser.add_option('--debug', action='store_true', dest='debug', help='Output the OCRed text and other information', default=False)
parser.add_option('--invert', dest='invert', type='int', help='Invert the image before performing OCR (1) or not (0). Defaults to 1.', default = 1)
parser.add_option('--left', dest='left', type='int', help='The left side of the box containing the date/time (in pixels)', default=0)
parser.add_option('--top', dest='top', type='int', help='The top of the box containing the date/time (in pixels)', default=0)
parser.add_option('--right', dest='right', type='int', help='The right side of the box containing the date/time (in pixels)', default=0)
parser.add_option('--bottom', dest='bottom', type='int', help='The bottom of the box containing the date/time (in pixels)', default=0)
parser.add_option('--ocr', dest='ocr', help='The binary to execute to perform the OCR. Must accept a filename as its only argument, and print the result to STDOUT. Defaults to gocr.', default='gocr')
(options, args) = parser.parse_args()
# Do a bunch of checks to makes sure we have all the options we need
if not options.date_format:
err('You must supply the format for the date in the image')
if not (options.left and options.right and options.bottom):
err('You must supply the coordinates of the left, right, and bottom of the box containing the date/time')
if len(args) < 1:
err('You must supply the filename of the image on which to perform the OCR operation')
result = do_ocr(args[0], options.left, options.top, options.right , options.bottom,
options.date_format, options.output_format, options.strip_chars,
options.invert, options.debug, options.ocr)
sys.stdout.write(result)
if _name_ == "_main_":
main()