from math import * import Image import ImageTk import Tkinter import _chaos class Box: def __init__(self, imagefile, threshold): self.image = Image.open(imagefile) W, H = self.image.size bdry_string = _chaos.boundary(self.image.tostring(), W, H, threshold) boundary = Image.fromstring('L', self.image.size, bdry_string) if Tkinter._default_root: self.window = Tkinter.Toplevel(Tkinter._default_root) else: self.window = Tkinter.Tk() self.window.title('Boundary of %s at threshold %d'% (imagefile, threshold)) self.canvas = Tkinter.Canvas(self.window, width=W, height=H+20) self.canvas.pack() self.bitmap = ImageTk.PhotoImage(boundary) self.canvas.create_image(0,0, anchor=Tkinter.NW, image=self.bitmap) boxcount = _chaos.boxcount(bdry_string, W, H, 255) data = [] for i in range(len(boxcount)): try: data.append( (-(i+1)*log(2), log(boxcount[i]) ) ) except OverflowError: pass self.regression = Regression(300,200,data) comment = 'Box dimension is approximately %.3f'%self.regression.a self.canvas.create_text(20, H+6, anchor=Tkinter.NW, text=comment) class Regression: def __init__(self, width, height, data): self.width, self.height = width, height self.x_min, self.x_max, self.y_min, self.y_max = 0,0,0,0 for datum in data: x, y = datum self.x_min = min(self.x_min, x) self.x_max = max(self.x_max, x) self.y_min = min(self.y_min, y) self.y_max = max(self.y_max, y) try: self.x_scale = (self.width - 20)/(self.x_max - self.x_min) except ZeroDivision: self.x_scale = 1.0 try: self.y_scale = (self.height - 20)/(self.y_max - self.y_min) except ZeroDivision: self.y_scale = 1.0 if Tkinter._default_root: self.window = Tkinter.Toplevel(Tkinter._default_root) else: self.window = Tkinter.Tk() self.window.title('Least squares regression') self.canvas = Tkinter.Canvas(self.window, width=self.width, height=self.height) self.canvas.pack() points = [] self.dots = [] for datum in data: x, y = self.pixels(datum[0],datum[1]) self.dots.append(self.canvas.create_oval(x-2, y-2, x+2, y+2, fill='red')) points += [x,y] self.graph = self.canvas.create_line(*points) self.a, self.b = self.least_squares(data) X0, Y0 = self.pixels(data[0][0], self.a*data[0][0]+self.b) Xn, Yn = self.pixels(data[-1][0], self.a*data[-1][0]+self.b) self.line = self.canvas.create_line(X0,Y0,Xn,Yn, fill='blue') comment = 'Least squares slope is approximately %.3f'%self.a self.canvas.create_text(20, self.height-14, fill='blue', anchor=Tkinter.NW, text=comment) def pixels(self, x, y): return [int(10+(x - self.x_min)*self.x_scale), int(10+(self.y_max - y)*self.y_scale)] def least_squares(self, data): X, Y, XY, XX = 0.0, 0.0, 0.0, 0.0 n = float(len(data)) for point in data: x, y = point X += x Y += y XY += x*y XX += x*x a = (n*XY - X*Y)/(n*XX - X*X) b = (XX*Y - X*XY)/(n*XX - X*X) return (a,b)