I am trying to clean up and make the following code more efficient -
https://gist.github.com/eWizardII/6757364
from PIL import Image
import numpy as np
from PIL import ImageChops
import subprocess
import math
import datetime
from PIL import ImageFont
from PIL import ImageDraw
from collections import deque
def image_entropy(prev, curr, smasumm, values):
im1 = Image.open(prev)
im2 = Image.open(curr)
img = ImageChops.difference(im1, im2)
w, h = img.size
a = np.array(img.convert('RGB')).reshape((w * h, 3))
h, e = np.histogramdd(a, bins=(16,) * 3, range=((0, 256),) * 3)
prob = h / np.sum(h) # normalize
prob = prob[prob > 0] # remove zeros
comp = -np.sum(prob * np.log2(prob))
framsd = SD(values, smasumm)
information = 'ENT: ' + str('{0:.2f}'.format(comp)) + ' SMA: ' + str('{0:.2f}'.format(smasumm)) + ' LB: ' + str(
'{0:.2f}'.format(smasumm - framsd)) + ' UB: ' + str('{0:.2f}'.format(smasumm + framsd))
cimg = Image.open(curr)
draw = ImageDraw.Draw(cimg)
font = ImageFont.truetype("arial.ttf", 24)
draw.text((0, 0), information, (0, 255, 0), font=font)
cimg.save(curr)
return comp
def SD(values, mean):
size = len(values)
sumsd = 0.0
for n in range(0, size):
sumsd += math.sqrt((values[n] - mean) ** 2)
return math.sqrt((1.0 / (size - 1)) * (sumsd / size))
try:
print "Initial Image ..."
time = datetime.datetime.now()
filename = "image_"
subprocess.call(
"raspistill -t 1000 -ex night -awb auto -w 720 -h 480 -o %s" % filename + '1.jpg',
shell=True)
prev = filename + '1.jpg'
i = 1
summ = smasumm = 0.0
period = n = 10
values = deque([0.0] * period)
while True:
time = datetime.datetime.now()
filename = "image_" + str(i) + ".jpg"
subprocess.call(
"raspistill -t 1000 -ex night -awb auto -w 720 -h 480 -o %s" % filename,
shell=True)
i += 1
curr = filename
sma = image_entropy(prev, curr, smasumm, values)
values.append(sma)
summ += sma - values.popleft()
smasumm = summ / n
prev = curr
print(datetime.datetime.now() - time)
except KeyboardInterrupt:
print " Quit"
I believe my biggest bottleneck is in using the subprocess.call
in Python but I don't know of any way to improve up such a call - in the long run when I know the program works properly I'll try and transition to Java/C; but this is easier for my immediate application and debugging. Any help or advice would be appreciated thanks in addition to any improvements in the other aspects of the code.