diff --git a/Build Instructions.txt b/Build Instructions.txt new file mode 100644 index 0000000..b9d4b95 --- /dev/null +++ b/Build Instructions.txt @@ -0,0 +1,4 @@ +Use command: +python gui.py + +in the command line to invoke the application. \ No newline at end of file diff --git a/Classif-test.py b/Classif-test.py new file mode 100644 index 0000000..ea2519f --- /dev/null +++ b/Classif-test.py @@ -0,0 +1,49 @@ +from PIL import Image +import numpy +import pylab +#from PIL import Image +from numpy import * +import tifwork as tw +import scipy.misc + + +arr=array(Image.open('guiTry.jpeg')) +(row,col,z) = arr.shape +arr2 = numpy.zeros(arr.shape,int) +print arr.shape + +print arr[:,:,0].min(),arr[:,:,0].mean(),arr[:,:,0].max() +print arr[:,:,1].min(),arr[:,:,1].mean(),arr[:,:,1].max() +print arr[:,:,2].min(),arr[:,:,2].mean(),arr[:,:,2].max() +# standard deviation from each band for each class will be required +# the deviation will be about the mean of the brightness value of all the bands +# 12 , 54, 67 +# mean = 44 + + +classes = [[(0,17),(0,65),(0,57)], [(17,47),(0,65),(0,57)]] +print classes[0][0][1] +print arr[0,0,0] in range(classes[0][0][0],classes[0][0][1]) +x = 0 +y = 0 + +for x in range (0,row): + for y in range (0,col): + if ((arr[x,y,0] in range(classes[0][0][0],classes[0][0][1])) and (arr[x,y,1] in range(classes[0][1][0],classes[0][1][1])) and(arr[x,y,2] in range(classes[0][2][0],classes[0][2][1]))): + arr[x,y,:] = (255,0,0) + if ((arr[x,y,0] in range(classes[1][0][0],classes[1][0][1])) and (arr[x,y,1] in range(classes[1][1][0],classes[1][1][1])) and(arr[x,y,2] in range(classes[1][2][0],classes[1][2][1]))): + arr[x,y,:] = (0,255,0) + else: + arr[x,y,:] = (255,255,255) + +scipy.misc.imsave('haha.jpg',arr) +''' +[12 , 13 +87, 23] +[32 , 13 +84, 23] +[62 , 13 +87, 23] + +''' + diff --git a/FastCMeans.py b/FastCMeans.py new file mode 100644 index 0000000..fe5d7d3 --- /dev/null +++ b/FastCMeans.py @@ -0,0 +1,90 @@ +# Segment N-dimensional grayscale image into c classes using a memory +# efficient implementation of the c-means (aka k-means) clustering +# algorithm. The computational efficiency is achieved by using the +# histogram of the image intensities during the clustering process instead +# of the raw image data. +# +# INPUT ARGUMENTS: +# - im : N-dimensional grayscale image in integer format. +# - c : positive interger greater than 1 specifying the number of +# clusters. c=2 is the default setting. Alternatively, c can be +# specified as a k-by-1 array of initial cluster (aka prototype) +# centroids. +# +# OUTPUT : +# - L : label image of the same size as the input image. For example, +# L==i represents the region associated with prototype C(i), +# where i=[1,k] (k = number of clusters). +# - C : 1-by-k array of cluster centroids. +# - LUT : L-by-1 array that specifies the intensity-class relations, +# where L is the dynamic intensity range of the input image. +# Specifically, LUT(1) corresponds to class assigned to +# min(im(:)) and LUT(L) corresponds to the class assigned to +# max(im(:)). See 'apply_LUT' function for more info. +# + +import numpy as np +import LUT2label as label + + + +def FastCMeans(im, c): + + # Intensity range + + Imin = float(np.min(im[:])) + Imax = float(np.max(im[:])) + I = np.transpose(np.array(np.arange(Imin,Imax+1))) + + I = I[:, np.newaxis] + + # Compute intensity histogram + + H = np.histogram(im.flatten(),I.flatten()) + (H1, H2) = H + #H1 = H1.flatten() + #H2 = H2.flatten() + H1 = H1[:, np.newaxis] + #H2 = H2[:, np.newaxis] + #print 'H1 and H2 Size: ', H1.shape, H2.shape + #print H1.shape + H = np.copy(np.append(H1,[1])) + H = H[:, np.newaxis] + + + # Initialize cluster centroids + + if np.size(c) > 1: + C = c + c = np.size(c) + else: + dl = (Imax - Imin)/c + C = np.arange(Imin + dl/2, Imax+1, dl) + + # Update cluster centroids + + IH = I * H + dC = float(np.inf) + + while (dC > 1.0E-6): + + C0 = np.copy(C) + + # Distance to the centroids + D = np.abs(I - C) + + # Classify by proximity + Dmin = np.min(D,1) + LUT = np.argmin(D,1) + + for j in range(0,c): + index = LUT==j + C[j] = np.sum(IH[index]) / np.sum(H[index]) + + # Change in centroids + #print (C-C0) + dC = np.max(np.abs(C-C0)) + + L = label.LUT2label(im,LUT) + return (L,C,LUT) + diff --git a/FastFCMeans.py b/FastFCMeans.py new file mode 100644 index 0000000..3139387 --- /dev/null +++ b/FastFCMeans.py @@ -0,0 +1,153 @@ +# Segment N-dimensional grayscale image into c classes using a memory +# efficient implementation of the fuzzy c-means (FCM) clustering algorithm. +# The computational efficiency is achieved by using the histogram of the +# image intensities during the clustering process instead of the raw image +# data. +# +# INPUT ARGUMENTS: +# - im : N-dimensional grayscale image in integer format. +# - c : positive interger greater than 1 specifying the number of +# clusters. c=2 is the default setting. Alternatively, c can be +# specified as a k-by-1 array of initial cluster (aka prototype) +# centroids. +# - q : fuzzy weighting exponent. q must be a real number greater than +# 1.1. q=2 is the default setting. Increasing q leads to an +# increased amount of fuzzification, while reducing q leads to +# crispier class memberships. +# +# OUTPUT : +# - L : label image of the same size as the input image. For example, +# L==i represents the region associated with prototype C(i), +# where i=[1,k] (k = number of clusters). +# - C : 1-by-k array of cluster centroids. +# - U : L-by-k array of fuzzy class memberships, where k is the number +# of classes and L is the intensity range of the input image, +# such that L=numel(min(im(:)):max(im(:))). +# - LUT : L-by-1 array that specifies the defuzzified intensity-class +# relations, where L is the dynamic intensity range of the input +# image. Specifically, LUT(1) corresponds to class assigned to +# min(im(:)) and LUT(L) corresponds to the class assigned to +# max(im(:)). See 'apply_LUT' function for more info. +# - H : image histogram. If I=min(im(:)):max(im(:)) are the intensities +# present in the input image, then H(i) is the number of image +# pixels/voxels that have intensity I(i). +# + + +import numpy as np +import matplotlib.pyplot as plt +import tifwork as tw +import scipy.misc +import LUT2label as label +import FastCMeans as fc + +def FastFCMeans(im, c, q): + + #intensity range + + Imin = float(np.min(im[:])) + Imax = float(np.max(im[:])) + I = np.transpose(np.array(np.arange(Imin,Imax+1))) + + I = I[:, np.newaxis] + + #print 'I size ', I.shape + + #print Imin, Imax + + # Compute intensity histogram + + H = np.histogram(im.flatten(),I.flatten()) + + (H1, H2) = H + + #H1 = H1.flatten() + #H2 = H2.flatten() + + H1 = H1[:, np.newaxis] + H2 = H2[:, np.newaxis] + + #print 'H1 and H2 Size: ', H1.shape, H2.shape + + + + H = np.copy(np.append(H1,[1])) + H = H[:, np.newaxis] + + + + #print H.shape + + #plt.show() + #print H + + #Initialize Cluster Centroids + + if np.size(c) > 1: + C = c + c = np.size(c) + else: + + (l,C,lut) = fc.FastCMeans(im,c) + + #Update Fuzzy Memberships and cluster centroids + + #I = repmat(I,[1 c]) + I = np.tile(I,np.array([1,c])) + + #print ' I shape ', I.shape + + dC = np.inf + + eps = np.finfo(float).eps + + #print 'Epsilon is ', eps + + while (dC > 1E-6): + + C0 = np.copy(C) + #Distance to the centroids + D = np.abs(I-C) + D = D**(2/(q-1)) + eps + + #compute fuzzy memberships + + recipSum = np.sum(1/D,1) + recipSum = recipSum[:, np.newaxis] + + + U = D * recipSum + + U = 1/(U+ eps) + + #update the centroids + + UH = (U**q) * H + + s1 = np.sum(UH * I,0) + s1 = s1[:,np.newaxis] + s2 = np.sum(UH,0).astype(float) + s2 = s2[:, np.newaxis] + + s1 = np.transpose(s1) + s2 = np.transpose(s2) + C = s1 /s2 + + + C = np.sort(C) + #Change in centroids + dC = np.max(np.abs(C-C0)) + + #Defuzzify and create a label image + + Umax = np.max(U,1) + #Umax = Umax[:,np.newaxis] + #print Umax + LUT = np.argmax(U,1) + #print LUT2label + + L = label.LUT2label(im,LUT) + + return (L,C,U,LUT,H) + + diff --git a/GUI/back_imageGUI.py b/GUI/back_imageGUI.py new file mode 100644 index 0000000..7450526 --- /dev/null +++ b/GUI/back_imageGUI.py @@ -0,0 +1,58 @@ + +import Tkinter as tk +from Tkinter import * +from tkMessageBox import * +import ttk +import tkFileDialog +from PIL import Image +import tifwork +import sys +import matplotlib +matplotlib.use('TkAgg') + +from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg +from matplotlib.backend_bases import key_press_handler +import matplotlib.pyplot as plt +import matplotlib.image as mpimg +from matplotlib.figure import Figure + +#from tkFileDialog import askopenfilename + +# implement the default mpl key bindings +#import Image, ImageTk + + +def imdisplay(filename,title): + openImFile(filename,title) + +def openImFile(filename,title): + Root1 = tk.Tk() + Root1.wm_title(title) + Root1.geometry("600x600") + fx = Figure(figsize=(5,4), dpi=100) + ax = fx.add_subplot(111) + img=mpimg.imread(filename) + plt.gray() + ax.imshow(img) + + canvasx = FigureCanvasTkAgg(fx, master=Root1) + canvasx.show() + canvasx.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1) + toolbar = NavigationToolbar2TkAgg( canvasx, Root1 ) + toolbar.update() + canvasx._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=1) + + def on_key_event(event): + print('you pressed %s'%event.key) + key_press_handler(event, canvasx, toolbar) + + def _quitx(): + Root1.quit() # stops mainloop + Root1.destroy() + button1 = tk.Button(master=Root1, text='Quit', command=_quitx) + button1.pack(side=tk.BOTTOM) + + fx.canvas.mpl_connect('key_press_event', on_key_event) + Root1.mainloop() + +# a tk.DrawingArea diff --git a/GUI/imageGUI.py b/GUI/imageGUI.py new file mode 100644 index 0000000..68798ab --- /dev/null +++ b/GUI/imageGUI.py @@ -0,0 +1,60 @@ + +import Tkinter as tk +from Tkinter import * +from tkMessageBox import * +import ttk +import tkFileDialog +from PIL import Image +import tifwork +import sys +import matplotlib +matplotlib.use('TkAgg') + +from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg +from matplotlib.backend_bases import key_press_handler +import matplotlib.pyplot as plt +import matplotlib.image as mpimg +from matplotlib.figure import Figure +import matplotlib.cm as cm +#from tkFileDialog import askopenfilename + +# implement the default mpl key bindings +#import Image, ImageTk + + +def imdisplay(filename,title,x=0): + openImFile(filename,title,x) + +def openImFile(filename,title,x): + Root1 = tk.Tk() + Root1.wm_title(title) + Root1.geometry("600x600") + fx = Figure(figsize=(5,4), dpi=100) + ax = fx.add_subplot(111) + img=mpimg.imread(filename) + if (x == 0): + ax.imshow(img) + else: + ax.imshow(img,cmap = cm.Greys_r) + + canvasx = FigureCanvasTkAgg(fx, master=Root1) + canvasx.draw() + canvasx.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1) + toolbar = NavigationToolbar2TkAgg( canvasx, Root1 ) + toolbar.update() + canvasx._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=1) + + def on_key_event(event): + print('you pressed %s'%event.key) + key_press_handler(event, canvasx, toolbar) + + def _quitx(): + Root1.quit() # stops mainloop + Root1.destroy() + button1 = tk.Button(master=Root1, text='Quit', command=_quitx) + button1.pack(side=tk.BOTTOM) + + fx.canvas.mpl_connect('key_press_event', on_key_event) + + +# a tk.DrawingArea diff --git a/GUI/rectest.py b/GUI/rectest.py new file mode 100644 index 0000000..154ea41 --- /dev/null +++ b/GUI/rectest.py @@ -0,0 +1,409 @@ + +import Tkinter as tk +from Tkinter import * +from tkMessageBox import * +import ttk +import tkFileDialog +from PIL import Image +import tifwork +import sys +import matplotlib + + +matplotlib.use('TkAgg') +from Tkinter import * +from tkFileDialog import askopenfilename +from numpy import arange, sin, pi +from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg +# implement the default mpl key bindings +from matplotlib.backend_bases import key_press_handler +import matplotlib.pyplot as plt +import matplotlib.image as mpimg +from matplotlib.figure import Figure +from pylab import * +import Image, ImageTk +import tktable + + + + + + +global mastercount +global slavecount +mastercount=0 +slavecount=0 + + +global list_Master +global list_Slave +list_Master=[] +list_Slave=[] +global keyx +keyx=False +def valueofkey(): + global keyx + return keyx + +def setkeyx(): + global keyx + keyx=True + +def resetkeyx(): + global keyx + keyx=False + +global keyy +keyy=False +def valueofkey1(): + global keyy + return keyy + +def setkeyy(): + global keyy + keyy=True + +def resetkeyy(): + global keyy + keyy=False + +val=[] + +def exit(): + root.destroy() + + +def viewerwin2(): + global Root4 + Root4.quit() + Root4.destroy() + + global Root1 + Root1 = tk.Toplevel(root) + Root1.wm_title("Open Master Image") + Root1.geometry("600x600") + + global keyy + resetkeyy() + + frame=tk.Frame(Root1) + frame1=tk.Frame(frame) + frame2=tk.Frame(frame) + button = tk.Button(frame1, width=5, height=2, text='Open',command=open_rectification_Slave) + button.pack() + frame1.pack(side=tk.LEFT) + frame2.pack(side=tk.LEFT) + frame.pack() + + + +def viewerwin(): + + global Root + Root = tk.Toplevel(root) + Root.wm_title("Open Slave Image") + Root.geometry("600x600") + global keyx + resetkeyx() + + + frame=tk.Frame(Root) + frame1=tk.Frame(frame) + frame2=tk.Frame(frame) + button = tk.Button(frame1, width=5, height=2, text='Open',command=open_rectification_Master) + button.pack() + + button1 = tk.Button(frame2, width=5, height=2, text='Proceed',command=openref) + button1.pack() + + + frame1.pack(side=tk.LEFT) + frame2.pack(side=tk.LEFT) + frame.pack() + + + +def click(): + setkeyx() + + +def mouse_input_event(event): + if valueofkey(): + global mastercount + global slavecount + mastercount=mastercount+1 + print 'input pixel loc is ',event.xdata,' ', event.ydata + a.plot(event.xdata, event.ydata,'b.') + tktable.write_to_table_master(np.round(event.xdata),np.round(event.ydata),mastercount,slavecount) + list_Master.append([np.round(event.xdata), np.round(event.ydata)]) + print list_Master + resetkeyx() + canvas.show() + + + + +def open_rectification_Master(): + + + + fileName=tkFileDialog.askopenfilename(title='select image to be rectified') + + global f + global a + f = Figure(figsize=(5,4), dpi=100) + a = f.add_subplot(111) + img=mpimg.imread(fileName) + a.imshow(img) + +# a tk.DrawingArea + global canvas + canvas = FigureCanvasTkAgg(f, master=Root) + canvas.show() + + canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1) + + toolbar = NavigationToolbar2TkAgg( canvas, Root ) + toolbar.update() + canvas._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=1) + + def on_key_event(event): + print 'event is ', event + key_press_handler(event, canvas, toolbar) + print "Tkable" + + f.canvas.mpl_connect('button_press_event',mouse_input_event) + f.canvas.mpl_connect('key_press_event', on_key_event) + + def _quit(): + Root.quit() # stops mainloop + Root.destroy() # this is necessary on Windows to pprevent + # Fatal Python Error: PyEval_RestoreThread: NULL tstate + button1 = tk.Button(master=Root, text='Quit', command=_quit) + button1.pack(side=tk.BOTTOM) + button = tk.Button(master=Root, text='select', command=click) + button.pack(side=tk.BOTTOM) + tktable.sample_test() +def clickx(): + setkeyy() + +def mouse_input_eventx(event): + if valueofkey1(): + global mastercount + global slavecount + slavecount=slavecount+1 + print 'input pixel loc is ',event.xdata,' ', event.ydata + ax.plot(event.xdata, event.ydata,'b.') + tktable.write_to_table_slave(np.round(event.xdata),np.round(event.ydata),slavecount,mastercount) + list_Slave.append([np.round(event.xdata), np.round(event.ydata)]) + print list_Slave + resetkeyy() + + canvasx.show() + +def key_input_eventx(event): + if valueofkey1(): + global mastercount + global slavecount + slavecount=slavecount+1 + print 'input pixel loc is ',event.xdata,' ', event.ydata + ax.plot(event.xdata, event.ydata,'b.') + tktable.write_to_table_slave(np.round(event.xdata),np.round(event.ydata),slavecount,mastercount) + list_Slave.append([np.round(event.xdata), np.round(event.ydata)]) + print list_Slave + resetkeyy() + + canvasx.show() +def open_rectification_Slave(): + + fileName=tkFileDialog.askopenfilename(title='select slave image to be rectified') + + global fx + global ax + fx = Figure(figsize=(5,4), dpi=100) + ax = fx.add_subplot(111) + img=mpimg.imread(fileName) + ax.imshow(img) + +# a tk.DrawingArea + global canvasx + canvasx = FigureCanvasTkAgg(fx, master=Root1) + canvasx.show() + + canvasx.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1) + + toolbar = NavigationToolbar2TkAgg( canvasx, Root1 ) + toolbar.update() + canvasx._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=1) + + def on_key_event(event): + print('you pressed %s'%event.key) + key_press_handler(event, canvasx, toolbar) + + + fx.canvas.mpl_connect('button_press_event',mouse_input_eventx) + fx.canvas.mpl_connect('key_press_event', on_key_event) + + def _quitx(): + Root1.quit() # stops mainloop + Root1.destroy() # this is necessary on Windows to pprevent + # Fatal Python Error: PyEval_RestoreThread: NULL tstate + button1 = tk.Button(master=Root1, text='Quit', command=_quitx) + button1.pack(side=tk.BOTTOM) + button = tk.Button(master=Root1, text='select', command=clickx) + button.pack(side=tk.BOTTOM) + + +def openref(): + + """selection=" " + #fileName=tkFileDialog.askopenfilename() + if(fileName == ''): + pass + else: + print(fileName) + im=(tifwork.openTIF(fileName)) + def sel(): + selection =str(var.get()) + print selection + + def printEntry(): + print selection """ + + global Root4 + Root4=tk.Tk() + Root4.title('Choose Polynomial order') + Root4.geometry('200x200') + var = IntVar() + r1=Spinbox(Root4,from_=0,to=100) + r1.pack() + buttona = tk.Button(master=Root4, text='GO', command=viewerwin2) + buttona.pack(side=tk.BOTTOM) + """R1 = Radiobutton(a, text="Order 0", variable=var, value=0) + R1.pack( anchor = W ) + + R2 = Radiobutton(a, text="Order 1", variable=var, value=1) + R2.pack( anchor = W ) + + R3 = Radiobutton(a, text="Order 2", variable=var, value=2) + R3.pack( anchor = W) + + label = Label(a) + label.pack() + + + L1 = Label(a, text="other") + L1.pack( side = LEFT) + E1 = Entry(a, bd =5) + + E1.pack(side = RIGHT) + selection=E1.get()""" + + a.mainloop() + + + image=Image.open(im) + image1=ImageTk.PhotoImage(image) + imagesprite=c.create_image(500,500,image=image1) + return im + + + + + + +def rgbselect(): + + fileName=tkFileDialog.askopenfilename() + if(fileName == ''): + pass + else: + print(fileName) + dataset=(tifwork.openTIF(fileName)) + + w=tk.Tk() + + def bandPrint(): + if(not(opt1.get() and opt2.get() and opt3.get())): + showerror("Error", "All bands not selected") + elif(opt1.get()==opt2.get() or opt1.get()==opt3.get() or opt2.get()==opt3.get()): + showerror("Error", "Two same bands selected") + else: + bandArr = tifwork.getBand(dataset,bands,bandArray) + tifwork.selectBand(bandArr,rows,cols,opt1.get(),opt2.get(),opt3.get()) + + frame4 = tk.Frame(w) +# frame4.grid() + frame2=tk.Frame(frame4) +# frame2.grid() + frame3=tk.Frame(frame4) +# frame3.grid() + frame5 = tk.Frame(w) +# frame5.grid() + w.title("Band Selection") + (cols,rows,bands,bandArray) = tifwork.detailsTIF(dataset) + + + optionList=[] + for k in range(1, bands+1): + optionList.append(k) + + x1=tk.Label(frame2, text="Red") + x1.pack(side=tk.TOP, pady = 5 , padx = 5 ) + opt1= ttk.Combobox(frame3,values=optionList, width=5) + opt1.pack(side = tk.TOP , pady = 5,padx = 5 ) + + x2=tk.Label(frame2, text="Blue") + x2.pack(side = tk.TOP , pady = 5 , padx = 5 ) + opt2= ttk.Combobox(frame3 , values=optionList, width=5) + opt2.pack(side = tk.TOP , pady = 5 , padx = 5 ) + + x3=tk.Label(frame2, text="Green") + x3.pack(side = tk.TOP , pady = 5 , padx = 5 ) + opt3= ttk.Combobox(frame3, values=optionList, width=5) + opt3.pack(side = tk.TOP , pady = 5 , padx = 5 ) + + frame2.pack(side=tk.LEFT, pady = 5 , padx = 5 ) + frame3.pack(side=tk.LEFT, pady = 5 , padx = 5 ) + frame4.pack(side= tk.TOP, pady = 5 , padx = 5 ) + + button = tk.Button(frame5, width=10, text="Show", command=bandPrint) + button.pack(side = tk.TOP , pady = 5 , padx = 5 ) + frame5.pack(side=tk.TOP , pady = 5 , padx = 5 ) + +#opens the root window +root=tk.Tk() + +root.title("Image Processing") + +frame1 = tk.Frame(root, width=800) + +#to display the frame +frame1.pack() + +#keeps only the frame +root.overrideredirect(0) +root.resizable(0,0) + +photo3 = tk.PhotoImage(file="2.gif") +button3 = tk.Button(frame1, width=100, height=100, image=photo3) +button3.pack(side=tk.LEFT, padx=2, pady=2) +button3.image = photo3 + + +photo2 = tk.PhotoImage(file="1.gif") +button2 = tk.Button(frame1, width=100, height=100, image=photo2, command=rgbselect) +button2.pack(side=tk.LEFT, padx=2, pady=2) +button2.image = photo2 + +button5 = tk.Button(frame1, width=20, height=6, text='Geometric correction',justify=tk.LEFT,command=viewerwin) +button5.pack(side=tk.LEFT, padx=2, pady=2) + + +photo1 = tk.PhotoImage(file="3.gif") +button1 = tk.Button(frame1, width=100, height=100, image=photo1, command=exit) +button1.pack(side=tk.LEFT, padx=2, pady=2) +button1.image = photo1 + +root.mainloop() + diff --git a/GUI/retable.py b/GUI/retable.py new file mode 100644 index 0000000..9356445 --- /dev/null +++ b/GUI/retable.py @@ -0,0 +1,440 @@ + +import Tkinter as tk +from Tkinter import * +from tkMessageBox import * +import ttk +import tkFileDialog +from PIL import Image +import tifwork +import sys +import matplotlib + + +matplotlib.use('TkAgg') +from Tkinter import * +from tkFileDialog import askopenfilename +from numpy import arange, sin, pi +from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg +# implement the default mpl key bindings +from matplotlib.backend_bases import key_press_handler +import matplotlib.pyplot as plt +import matplotlib.image as mpimg +from matplotlib.figure import Figure +from pylab import * +#import Image, ImageTk +import tktable + + + + + + +global mastercount +global slavecount +mastercount=0 +slavecount=0 + + +global list_Master +global list_Slave +list_Master=[] +list_Slave=[] +global keyx +keyx=False +def valueofkey(): + global keyx + return keyx + +def setkeyx(): + global keyx + keyx=True + +def resetkeyx(): + global keyx + keyx=False + +global keyy +keyy=False +def valueofkey1(): + global keyy + return keyy + +def setkeyy(): + global keyy + keyy=True + +def resetkeyy(): + global keyy + keyy=False + +val=[] + +def exit(): + root.destroy() + + + +def imdisplay(filename): + + filename = '2.gif' + + global Root1 + Root1 = tk.Toplevel(root) + Root1.wm_title("Image Display") + Root1.geometry("600x600") + + global keyy + resetkeyy() + + openImFile(filename) + + +def openImFile(filename): + + + global fx + global ax + fx = Figure(figsize=(5,4), dpi=100) + ax = fx.add_subplot(111) + img=mpimg.imread(filename) + ax.imshow(img) + +# a tk.DrawingArea + global canvasx + canvasx = FigureCanvasTkAgg(fx, master=Root1) + canvasx.show() + + canvasx.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1) + + toolbar = NavigationToolbar2TkAgg( canvasx, Root1 ) + toolbar.update() + canvasx._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=1) + + def on_key_event(event): + print('you pressed %s'%event.key) + key_press_handler(event, canvasx, toolbar) + + + fx.canvas.mpl_connect('button_press_event',mouse_input_eventx) + fx.canvas.mpl_connect('key_press_event', on_key_event) + + def _quitx(): + Root1.quit() # stops mainloop + Root1.destroy() # this is necessary on Windows to pprevent + # Fatal Python Error: PyEval_RestoreThread: NULL tstate + button1 = tk.Button(master=Root1, text='Quit', command=_quitx) + button1.pack(side=tk.BOTTOM) + button = tk.Button(master=Root1, text='select', command=clickx) + button.pack(side=tk.BOTTOM) + + +def viewerwin2(): + global Root4 + Root4.quit() + Root4.destroy() + + global Root1 + Root1 = tk.Toplevel(root) + Root1.wm_title("Open Master Image") + Root1.geometry("600x600") + + global keyy + resetkeyy() + + frame=tk.Frame(Root1) + frame1=tk.Frame(frame) + frame2=tk.Frame(frame) + button = tk.Button(frame1, width=5, height=2, text='Open',command=open_rectification_Slave) + button.pack() + frame1.pack(side=tk.LEFT) + frame2.pack(side=tk.LEFT) + frame.pack() + + + +def viewerwin(): + + global Root + Root = tk.Toplevel(root) + Root.wm_title("Open Slave Image") + Root.geometry("600x600") + global keyx + resetkeyx() + + + frame=tk.Frame(Root) + frame1=tk.Frame(frame) + frame2=tk.Frame(frame) + button = tk.Button(frame1, width=5, height=2, text='Open',command=open_rectification_Master) + button.pack() + + button1 = tk.Button(frame2, width=5, height=2, text='Proceed',command=openref) + button1.pack() + + + frame1.pack(side=tk.LEFT) + frame2.pack(side=tk.LEFT) + frame.pack() + + + +def click(): + setkeyx() + + +def mouse_input_event(event): + if valueofkey(): + global mastercount + global slavecount + mastercount=mastercount+1 + print 'input pixel loc is ',event.xdata,' ', event.ydata + a.plot(event.xdata, event.ydata,'b.') + tktable.write_to_table_master(np.round(event.xdata),np.round(event.ydata),mastercount,slavecount) + list_Master.append([np.round(event.xdata), np.round(event.ydata)]) + print list_Master + resetkeyx() + canvas.show() + + + + +def open_rectification_Master(): + + + + fileName=tkFileDialog.askopenfilename(title='select image to be rectified') + + global f + global a + f = Figure(figsize=(5,4), dpi=100) + a = f.add_subplot(111) + img=mpimg.imread(fileName) + a.imshow(img) + +# a tk.DrawingArea + global canvas + canvas = FigureCanvasTkAgg(f, master=Root) + canvas.show() + + canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1) + + toolbar = NavigationToolbar2TkAgg( canvas, Root ) + toolbar.update() + canvas._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=1) + + def on_key_event(event): + print('you pressed %s'%event.key) + key_press_handler(event, canvas, toolbar) + print "Tkable" + + f.canvas.mpl_connect('button_press_event',mouse_input_event) + f.canvas.mpl_connect('key_press_event', on_key_event) + + def _quit(): + Root.quit() # stops mainloop + Root.destroy() # this is necessary on Windows to pprevent + # Fatal Python Error: PyEval_RestoreThread: NULL tstate + button1 = tk.Button(master=Root, text='Quit', command=_quit) + button1.pack(side=tk.BOTTOM) + button = tk.Button(master=Root, text='select', command=click) + button.pack(side=tk.BOTTOM) + tktable.sample_test() +def clickx(): + setkeyy() + +def mouse_input_eventx(event): + if valueofkey1(): + global mastercount + global slavecount + slavecount=slavecount+1 + print 'input pixel loc is ',event.xdata,' ', event.ydata + ax.plot(event.xdata, event.ydata,'b.') + tktable.write_to_table_slave(np.round(event.xdata),np.round(event.ydata),slavecount,mastercount) + list_Slave.append([np.round(event.xdata), np.round(event.ydata)]) + print list_Slave + resetkeyy() + + canvasx.show() + +def open_rectification_Slave(): + + fileName=tkFileDialog.askopenfilename(title='select slave image to be rectified') + + global fx + global ax + fx = Figure(figsize=(5,4), dpi=100) + ax = fx.add_subplot(111) + img=mpimg.imread(fileName) + ax.imshow(img) + +# a tk.DrawingArea + global canvasx + canvasx = FigureCanvasTkAgg(fx, master=Root1) + canvasx.show() + + canvasx.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1) + + toolbar = NavigationToolbar2TkAgg( canvasx, Root1 ) + toolbar.update() + canvasx._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=1) + + def on_key_event(event): + print('you pressed %s'%event.key) + key_press_handler(event, canvasx, toolbar) + + + fx.canvas.mpl_connect('button_press_event',mouse_input_eventx) + fx.canvas.mpl_connect('key_press_event', on_key_event) + + def _quitx(): + Root1.quit() # stops mainloop + Root1.destroy() # this is necessary on Windows to pprevent + # Fatal Python Error: PyEval_RestoreThread: NULL tstate + button1 = tk.Button(master=Root1, text='Quit', command=_quitx) + button1.pack(side=tk.BOTTOM) + button = tk.Button(master=Root1, text='select', command=clickx) + button.pack(side=tk.BOTTOM) + + +def openref(): + + + global Root4 + Root4=tk.Tk() + Root4.title('Choose Polynomial order') + Root4.geometry('200x200') + var = IntVar() + r1=Spinbox(Root4,from_=0,to=100) + r1.pack() + buttona = tk.Button(master=Root4, text='GO', command=viewerwin2) + buttona.pack(side=tk.BOTTOM) + """R1 = Radiobutton(a, text="Order 0", variable=var, value=0) + R1.pack( anchor = W ) + + R2 = Radiobutton(a, text="Order 1", variable=var, value=1) + R2.pack( anchor = W ) + + R3 = Radiobutton(a, text="Order 2", variable=var, value=2) + R3.pack( anchor = W) + + label = Label(a) + label.pack() + + + L1 = Label(a, text="other") + L1.pack( side = LEFT) + E1 = Entry(a, bd =5) + + E1.pack(side = RIGHT) + selection=E1.get()""" + + a.mainloop() + + + image=Image.open(im) + image1=ImageTk.PhotoImage(image) + imagesprite=c.create_image(500,500,image=image1) + return im + + + + + + +def rgbselect(): + + fileName=tkFileDialog.askopenfilename() + if(fileName == ''): + pass + else: + print(fileName) + dataset=(tifwork.openTIF(fileName)) + + w=tk.Tk() + + def bandPrint(): + if(not(opt1.get() and opt2.get() and opt3.get())): + showerror("Error", "All bands not selected") + elif(opt1.get()==opt2.get() or opt1.get()==opt3.get() or opt2.get()==opt3.get()): + showerror("Error", "Two same bands selected") + else: + bandArr = tifwork.getBand(dataset,bands,bandArray) + tifwork.selectBand(bandArr,rows,cols,opt1.get(),opt2.get(),opt3.get()) + + frame4 = tk.Frame(w) +# frame4.grid() + frame2=tk.Frame(frame4) +# frame2.grid() + frame3=tk.Frame(frame4) +# frame3.grid() + frame5 = tk.Frame(w) +# frame5.grid() + w.title("Band Selection") + (cols,rows,bands,bandArray) = tifwork.detailsTIF(dataset) + + + optionList=[] + for k in range(1, bands+1): + optionList.append(k) + + x1=tk.Label(frame2, text="Red") + x1.pack(side=tk.TOP, pady = 5 , padx = 5 ) + opt1= ttk.Combobox(frame3,values=optionList, width=5) + opt1.pack(side = tk.TOP , pady = 5,padx = 5 ) + + x2=tk.Label(frame2, text="Blue") + x2.pack(side = tk.TOP , pady = 5 , padx = 5 ) + opt2= ttk.Combobox(frame3 , values=optionList, width=5) + opt2.pack(side = tk.TOP , pady = 5 , padx = 5 ) + + x3=tk.Label(frame2, text="Green") + x3.pack(side = tk.TOP , pady = 5 , padx = 5 ) + opt3= ttk.Combobox(frame3, values=optionList, width=5) + opt3.pack(side = tk.TOP , pady = 5 , padx = 5 ) + + frame2.pack(side=tk.LEFT, pady = 5 , padx = 5 ) + frame3.pack(side=tk.LEFT, pady = 5 , padx = 5 ) + frame4.pack(side= tk.TOP, pady = 5 , padx = 5 ) + + button = tk.Button(frame5, width=10, text="Show", command=bandPrint) + button.pack(side = tk.TOP , pady = 5 , padx = 5 ) + frame5.pack(side=tk.TOP , pady = 5 , padx = 5 ) + +#opens the root window +root=tk.Tk() + +root.title("Image Processing") + +frame1 = tk.Frame(root, width=800) + +#to display the frame +frame1.pack() + +#keeps only the frame +root.overrideredirect(0) +root.resizable(0,0) + +photo3 = tk.PhotoImage(file="2.gif") +button3 = tk.Button(frame1, width=100, height=100, image=photo3) +button3.pack(side=tk.LEFT, padx=2, pady=2) +button3.image = photo3 + + +photo2 = tk.PhotoImage(file="1.gif") +button2 = tk.Button(frame1, width=100, height=100, image=photo2, command=rgbselect) +button2.pack(side=tk.LEFT, padx=2, pady=2) +button2.image = photo2 + +button5 = tk.Button(frame1, width=20, height=6, text='Geometric correction',justify=tk.LEFT,command=viewerwin) +button5.pack(side=tk.LEFT, padx=2, pady=2) + + +photo1 = tk.PhotoImage(file="3.gif") +button1 = tk.Button(frame1, width=100, height=100, image=photo1, command=exit) +button1.pack(side=tk.LEFT, padx=2, pady=2) +button1.image = photo1 + +imdisplay('3.jpg') + +root.mainloop() + diff --git a/GUI/tifwork.py b/GUI/tifwork.py new file mode 100644 index 0000000..b6ce1a9 --- /dev/null +++ b/GUI/tifwork.py @@ -0,0 +1,44 @@ +from osgeo import gdal +import PIL.Image as Image +import numpy as np + + +gdal.AllRegister() + +def openTIF(filename): + dataset =gdal.Open(filename,gdal.GA_ReadOnly) + if dataset is None: + print 'Could Not Open' + filename + #Alternatively Raise an Event here + sys.exit(1) + + return dataset + +def detailsTIF(dataset): + cols = dataset.RasterXSize + rows = dataset.RasterYSize + bands = dataset.RasterCount + bandArray = np.zeros((rows,cols,bands),'uint8') + return (cols, rows,bands,bandArray) + +def getBand(dataset,bands,bandArr): + for x in range(1,bands+1): + band=dataset.GetRasterBand(x) + array=band.ReadAsArray() + bandArr[:,:,x-1] = array + return bandArr + + +def selectBand(bandArray,rows,cols,ch1,ch2,ch3): + + ch1 = int(ch1) + ch2 = int(ch2) + ch3 = int(ch3) + combi= np.zeros((rows,cols,3),'uint8') + combi[:,:,0]=bandArray[:,:,ch1-1] + combi[:,:,1]=bandArray[:,:,ch2-1] + combi[:,:,2]=bandArray[:,:,ch3-1] + combImage= Image.fromarray(combi) + combImage.save('guiTry'+'.jpeg') + combImage.show() + diff --git a/GUI/tktable.py b/GUI/tktable.py new file mode 100644 index 0000000..56d0101 --- /dev/null +++ b/GUI/tktable.py @@ -0,0 +1,740 @@ +# Copyright (c) 2008, Guilherme Polo +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +""" +This contains a wrapper class for the tktable widget as well a class for using +tcl arrays that are, in some instances, required by tktable. +""" + +__author__ = "Guilherme Polo " + +__all__ = ["ArrayVar", "Table"] + +import os +import Tkinter + +def _setup_master(master): + if master is None: + if Tkinter._support_default_root: + master = Tkinter._default_root or Tkinter.Tk() + else: + raise RuntimeError("No master specified and Tkinter is " + "configured to not support default master") + return master + +class ArrayVar(Tkinter.Variable): + """Class for handling Tcl arrays. + + An array is actually an associative array in Tcl, so this class supports + some dict operations. + """ + + def __init__(self, master=None, name=None): + # Tkinter.Variable.__init__ is not called on purpose! I don't wanna + # see an ugly _default value in the pretty array. + self._master = _setup_master(master) + self._tk = self._master.tk + if name: + self._name = name + else: + self._name = 'PY_VAR%s' % id(self) + + def __del__(self): + if bool(self._tk.call('info', 'exists', self._name)): + self._tk.globalunsetvar(self._name) + + def __len__(self): + return int(self._tk.call('array', 'size', str(self))) + + def __getitem__(self, key): + return self.get(key) + + def __setitem__(self, key, value): + self.set(**{str(key): value}) + + def names(self): + return self._tk.call('array', 'names', self._name) + + def get(self, key=None): + if key is None: + flatten_pairs = self._tk.call('array', 'get', str(self)) + return dict(zip(flatten_pairs[::2], flatten_pairs[1::2])) + + return self._tk.globalgetvar(str(self), str(key)) + + def set(self, **kw): + self._tk.call('array', 'set', str(self), Tkinter._flatten(kw.items())) + + def unset(self, pattern=None): + """Unsets all of the elements in the array. If pattern is given, only + the elements that match pattern are unset. """ + self._tk.call('array', 'unset', str(self), pattern) + + +_TKTABLE_LOADED = False + +class Table(Tkinter.Widget): + """Create and manipulate tables.""" + + _switches = ('holddimensions', 'holdselection', 'holdtags', 'holdwindows', + 'keeptitles', '-') + _tabsubst_format = ('%c', '%C', '%i', '%r', '%s', '%S', '%W') + _tabsubst_commands = ('browsecommand', 'browsecmd', 'command', + 'selectioncommand', 'selcmd', + 'validatecommand', 'valcmd') + + def __init__(self, master=None, **kw): + master = _setup_master(master) + global _TKTABLE_LOADED + if not _TKTABLE_LOADED: + tktable_lib = os.environ.get('TKTABLE_LIBRARY') + if tktable_lib: + master.tk.eval('global auto_path; ' + 'lappend auto_path {%s}' % tktable_lib) + master.tk.call('package', 'require', 'Tktable') + _TKTABLE_LOADED = True + + Tkinter.Widget.__init__(self, master, 'table', kw) + + + def _options(self, cnf, kw=None): + if kw: + cnf = Tkinter._cnfmerge((cnf, kw)) + else: + cnf = Tkinter._cnfmerge(cnf) + + res = () + for k, v in cnf.iteritems(): + if callable(v): + if k in self._tabsubst_commands: + v = "%s %s" % (self._register(v, self._tabsubst), + ' '.join(self._tabsubst_format)) + else: + v = self._register(v) + res += ('-%s' % k, v) + + return res + + + def _tabsubst(self, *args): + if len(args) != len(self._tabsubst_format): + return args + + tk = self.tk + c, C, i, r, s, S, W = args + e = Tkinter.Event() + + e.widget = self + e.c = tk.getint(c) + e.i = tk.getint(i) + e.r = tk.getint(r) + e.C = "%d,%d" % (e.r, e.c) + e.s = s + e.S = S + try: + e.W = self._nametowidget(W) + except KeyError: + e.W = None + + return (e,) + + + def _handle_switches(self, args): + args = args or () + return tuple(('-%s' % x) for x in args if x in self._switches) + + + def activate(self, index): + """Set the active cell to the one indicated by index.""" + self.tk.call(self._w, 'activate', index) + + + def bbox(self, first, last=None): + """Return the bounding box for the specified cell (range) as a + 4-tuple of x, y, width and height in pixels. It clips the box to + the visible portion, if any, otherwise an empty tuple is returned.""" + return self._getints(self.tk.call(self._w, 'bbox', first, last)) or () + + + def clear(self, option, first=None, last=None): + """This is a convenience routine to clear certain state information + managed by the table. first and last represent valid table indices. + If neither are specified, then the command operates on the whole + table.""" + self.tk.call(self._w, 'clear', option, first, last) + + + def clear_cache(self, first=None, last=None): + """Clear the specified section of the cache, if the table has been + keeping one.""" + self.clear('cache', first, last) + + + def clear_sizes(self, first=None, last=None): + """Clear the specified row and column areas of specific height/width + dimensions. When just one index is specified, for example 2,0, that + is interpreted as row 2 and column 0.""" + self.clear('sizes', first, last) + + + def clear_tags(self, first=None, last=None): + """Clear the specified area of tags (all row, column and cell tags).""" + self.clear('tags', first, last) + + + def clear_all(self, first=None, last=None): + """Perform all of the above clear functions on the specified area.""" + self.clear('all', first, last) + + + def curselection(self, value=None): + """With no arguments, it returns the sorted indices of the currently + selected cells. Otherwise it sets all the selected cells to the given + value if there is an associated ArrayVar and the state is not + disabled.""" + result = self.tk.call(self._w, 'curselection', value) + if value is None: + return result + + + def curvalue(self, value=None): + """If no value is given, the value of the cell being edited (indexed + by active) is returned, else it is set to the given value. """ + return self.tk.call(self._w, 'curvalue', value) + + + def delete_active(self, index1, index2=None): + """Deletes text from the active cell. If only one index is given, + it deletes the character after that index, otherwise it deletes from + the first index to the second. index can be a number, insert or end.""" + self.tk.call(self._w, 'delete', 'active', index1, index2) + + + def delete_cols(self, index, count=None, switches=None): + args = self._handle_switches(switches) + (index, count) + self.tk.call(self._w, 'delete', 'cols', *args) + + + def delete_rows(self, index, count=None, switches=None): + args = self._handle_switches(switches) + (index, count) + self.tk.call(self._w, 'delete', 'rows', *args) + + + def get(self, first, last=None): + """Returns the value of the cells specified by the table indices + first and (optionally) last.""" + return self.tk.call(self._w, 'get', first, last) + + + def height(self, row=None, **kwargs): + """If row and kwargs are not given, a list describing all rows for + which a width has been set is returned. + If row is given, the height of that row is returnd. + If kwargs is given, then it sets the key/value pairs, where key is a + row and value represents the height for the row.""" + if row is None and not kwargs: + pairs = self.tk.splitlist(self.tk.call(self._w, 'height')) + return dict(pair.split() for pair in pairs) + elif row: + return int(self.tk.call(self._w, 'height', str(row))) + + args = Tkinter._flatten(kwargs.items()) + self.tk.call(self._w, 'height', *args) + + + def hidden(self, *args): + """When called without args, it returns all the hidden cells (those + cells covered by a spanning cell). If one index is specified, it + returns the spanning cell covering that index, if any. If multiple + indices are specified, it returns 1 if all indices are hidden cells, + 0 otherwise.""" + return self.tk.call(self._w, 'hidden', *args) + + + def icursor(self, arg=None): + """If arg is not specified, return the location of the insertion + cursor in the active cell. Otherwise, set the cursor to that point in + the string. + + 0 is before the first character, you can also use insert or end for + the current insertion point or the end of the text. If there is no + active cell, or the cell or table is disabled, this will return -1.""" + return self.tk.call(self._w, 'icursor', arg) + + + def index(self, index, rc=None): + """Return the integer cell coordinate that corresponds to index in the + form row, col. If rc is specified, it must be either 'row' or 'col' so + only the row or column index is returned.""" + res = self.tk.call(self._w, 'index', index, rc) + if rc is None: + return res + else: + return int(res) + + + def insert_active(self, index, value): + """The value is a text string which is inserted at the index postion + of the active cell. The cursor is then positioned after the new text. + index can be a number, insert or end. """ + self.tk.call(self._w, 'insert', 'active', index, value) + + + def insert_cols(self, index, count=None, switches=None): + args = self._handle_switches(switches) + (index, count) + self.tk.call(self._w, 'insert', 'cols', *args) + + + def insert_rows(self, index, count=None, switches=None): + args = self._handle_switches(switches) + (index, count) + self.tk.call(self._w, 'insert', 'rows', *args) + + + #def postscript(self, **kwargs): + # """Skip this command if you are under Windows. + # + # Accepted options: + # colormap, colormode, file, channel, first, fontmap, height, + # last, pageanchor, pageheight, pagewidth, pagex, pagey, rotate, + # width, x, y + # """ + # args = () + # for key, val in kwargs.iteritems(): + # args += ('-%s' % key, val) + # + # return self.tk.call(self._w, 'postscript', *args) + + + def reread(self): + """Rereads the old contents of the cell back into the editing buffer. + Useful for a key binding when is pressed to abort the edit + (a default binding).""" + self.tk.call(self._w, 'reread') + + + def scan_mark(self, x, y): + self.tk.call(self._w, 'scan', 'mark', x, y) + + + def scan_dragto(self, x, y): + self.tk.call(self._w, 'scan', 'dragto', x, y) + + + def see(self, index): + self.tk.call(self._w, 'see', index) + + + def selection_anchor(self, index): + self.tk.call(self._w, 'selection', 'anchor', index) + + + def selection_clear(self, first, last=None): + self.tk.call(self._w, 'selection', 'clear', first, last) + + + def selection_includes(self, index): + return self.getboolean(self.tk.call(self._w, 'selection', 'includes', + index)) + + + def selection_set(self, first, last=None): + self.tk.call(self._w, 'selection', 'set', first, last) + + + def set(self, rc=None, index=None, *args, **kwargs): + """If rc is specified (either 'row' or 'col') then it is assumes that + args (if given) represents values which will be set into the + subsequent columns (if row is specified) or rows (for col). + If index is not None and args is not given, then it will return the + value(s) for the cell(s) specified. + + If kwargs is given, assumes that each key in kwargs is a index in this + table and sets the specified index to the associated value. Table + validation will not be triggered via this method. + + Note that the table must have an associated array (defined through the + variable option) in order to this work.""" + if not args and index is not None: + if rc: + args = (rc, index) + else: + args = (index, ) + return self.tk.call(self._w, 'set', *args) + + if rc is None: + args = Tkinter._flatten(kwargs.items()) + self.tk.call(self._w, 'set', *args) + else: + self.tk.call(self._w, 'set', rc, index, args) + + + def spans(self, index=None, **kwargs): + """Manipulate row/col spans. + + When called with no arguments, all known spans are returned as a dict. + When called with only the index, the span for that index only is + returned, if any. Otherwise kwargs is assumed to contain keys/values + pairs used to set spans. A span starts at the row,col defined by a key + and continues for the specified number of rows,cols specified by + its value. A span of 0,0 unsets any span on that cell.""" + if kwargs: + args = Tkinter._flatten(kwargs.items()) + self.tk.call(self._w, 'spans', *args) + else: + return self.tk.call(self._w, 'spans', index) + + + def tag_cell(self, tagname, *args): + return self.tk.call(self._w, 'tag', 'cell', tagname, *args) + + + def tag_cget(self, tagname, option): + return self.tk.call(self._w, 'tag', 'cget', tagname, '-%s' % option) + + + def tag_col(self, tagname, *args): + return self.tk.call(self._w, 'tag', 'col', tagname, *args) + + + def tag_configure(self, tagname, option=None, **kwargs): + """Query or modify options associated with the tag given by tagname. + + If no option is specified, a dict describing all of the available + options for tagname is returned. If option is specified, then the + command returns a list describing the one named option. Lastly, if + kwargs is given then it corresponds to option-value pairs that should + be modified.""" + if option is None and not kwargs: + split1 = self.tk.splitlist( + self.tk.call(self._w, 'tag', 'configure', tagname)) + + result = {} + for item in split1: + res = self.tk.splitlist(item) + result[res[0]] = res[1:] + + return result + + elif option: + return self.tk.call(self._w, 'tag', 'configure', tagname, + '-%s' % option) + + else: + args = () + for key, val in kwargs.iteritems(): + args += ('-%s' % key, val) + + self.tk.call(self._w, 'tag', 'configure', tagname, *args) + + + def tag_delete(self, tagname): + self.tk.call(self._w, 'tag', 'delete', tagname) + + + def tag_exists(self, tagname): + return self.getboolean(self.tk.call(self._w, 'tag', 'exists', tagname)) + + + def tag_includes(self, tagname, index): + return self.getboolean(self.tk.call(self._w, 'tag', 'includes', + tagname, index)) + + + def tag_lower(self, tagname, belowthis=None): + self.tk.call(self._w, 'tag', 'lower', belowthis) + + + def tag_names(self, pattern=None): + return self.tk.call(self._w, 'tag', 'names', pattern) + + + def tag_raise(self, tagname, abovethis=None): + self.tk.call(self._w, 'tag', 'raise', tagname, abovethis) + + + def tag_row(self, tagname, *args): + return self.tk.call(self._w, 'tag', 'row', tagname, *args) + + + def validate(self, index): + """Explicitly validates the specified index based on the current + callback set for the validatecommand option. Return 0 or 1 based on + whether the cell was validated.""" + return self.tk.call(self._w, 'validate', index) + + + @property + def version(self): + """Return tktable's package version.""" + return self.tk.call(self._w, 'version') + + + def width(self, column=None, **kwargs): + """If column and kwargs are not given, a dict describing all columns + for which a width has been set is returned. + If column is given, the width of that column is returnd. + If kwargs is given, then it sets the key/value pairs, where key is a + column and value represents the width for the column.""" + if column is None and not kwargs: + pairs = self.tk.splitlist(self.tk.call(self._w, 'width')) + return dict(pair.split() for pair in pairs) + elif column is not None: + return int(self.tk.call(self._w, 'width', str(column))) + + args = Tkinter._flatten(kwargs.items()) + self.tk.call(self._w, 'width', *args) + + + def window_cget(self, index, option): + return self.tk.call(self._w, 'window', 'cget', index, option) + + + def window_configure(self, index, option=None, **kwargs): + """Query or modify options associated with the embedded window given + by index. This should also be used to add a new embedded window into + the table. + + If no option is specified, a dict describing all of the available + options for index is returned. If option is specified, then the + command returns a list describing the one named option. Lastly, if + kwargs is given then it corresponds to option-value pairs that should + be modified.""" + if option is None and not kwargs: + return self.tk.call(self._w, 'window', 'configure', index) + elif option: + return self.tk.call(self._w, 'window', 'configure', index, + '-%s' % option) + else: + args = () + for key, val in kwargs.iteritems(): + args += ('-%s' % key, val) + + self.tk.call(self._w, 'window', 'configure', index, *args) + + + def window_delete(self, *indexes): + self.tk.call(self._w, 'window', 'delete', *indexes) + + + def window_move(self, index_from, index_to): + self.tk.call(self._w, 'window', 'move', index_from, index_to) + + + def window_names(self, pattern=None): + return self.tk.call(self._w, 'window', 'names', pattern) + + + def xview(self, index=None): + """If index is not given a tuple containing two fractions is returned, + each fraction is between 0 and 1. Together they describe the + horizontal span that is visible in the window. + + If index is given the view in the window is adjusted so that the + column given by index is displayed at the left edge of the window.""" + res = self.tk.call(self._w, 'xview', index) + if index is None: + return self._getdoubles(res) + + + def xview_moveto(self, fraction): + """Adjusts the view in the window so that fraction of the total width + of the table text is off-screen to the left. The fraction parameter + must be a fraction between 0 and 1.""" + self.tk.call(self._w, 'xview', 'moveto', fraction) + + + def xview_scroll(self, *L): + #change by frank gao for attach scrollbar 11/11/2010 + """Shift the view in the window left or right according to number and + what. The 'number' parameter must be an integer. The 'what' parameter + must be either units or pages or an abbreviation of one of these. + + If 'what' is units, the view adjusts left or right by number cells on + the display; if it is pages then the view adjusts by number screenfuls. + If 'number' is negative then cells farther to the left become visible; + if it is positive then cells farther to the right become visible. """ + #self.tk.call(self._w, 'xview', 'scroll', number, what) + if op=='scroll': + units=L[2] + self.tk.call(self._w, 'xview', 'scroll',howMany,units) + elif op=='moveto': + self.tk.call(self._w, 'xview', 'moveto',howMany) + + + def yview(self, index=None): + """If index is not given a tuple containing two fractions is returned, + each fraction is between 0 and 1. The first element gives the position + of the table element at the top of the window, relative to the table + as a whole. The second element gives the position of the table element + just after the last one in the window, relative to the table as a + whole. + + If index is given the view in the window is adjusted so that the + row given by index is displayed at the top of the window.""" + res = self.tk.call(self._w, 'yview', index) + if index is None: + return self._getdoubles(res) + + + def yview_moveto(self, fraction): + """Adjusts the view in the window so that the element given by + fraction appears at the top of the window. The fraction parameter + must be a fraction between 0 and 1.""" + self.tk.call(self._w, 'yview', 'moveto', fraction) + + + def yview_scroll(self, *L): + #change by frank gao for attach scrollbar 11/11/2010 + """Adjust the view in the window up or down according to number and + what. The 'number' parameter must be an integer. The 'what' parameter + must be either units or pages or an abbreviation of one of these. + + If 'what' is units, the view adjusts up or down by number cells; if it + is pages then the view adjusts by number screenfuls. + If 'number' is negative then earlier elements become visible; if it + is positive then later elements become visible. """ + #self.tk.call(self._w, 'yview', 'scroll', number, what) + op,howMany=L[0],L[1] + if op=='scroll': + units=L[2] + self.tk.call(self._w, 'yview', 'scroll',howMany,units) + elif op=='moveto': + self.tk.call(self._w, 'yview', 'moveto',howMany) + + +# Sample test taken from tktable cvs, original tktable python wrapper +def sample_test(): + global Root1 + from Tkinter import Tk, Label, Button + + def test_cmd(event): + if event.i == 0: + return '%i, %i' % (event.r, event.c) + else: + return 'set' + + def browsecmd(event): + + print "event:", event.__dict__ + print "curselection:", test.curselection() + print "active cell index:", test.index('active') + print "active:", test.index('active', 'row') + print "anchor:", test.index('anchor', 'row') + print event.key + root3 = Tkinter.Tk() + global var + var = ArrayVar(root3) + '''for y in range(-1, 4): + for x in range(-1, 5): + index = "%i,%i" % (y, x) + var[index] = index + ''' + index = "%i,%i" % (-1, -1) + var[index]="Serial no" + index = "%i,%i" % (-1, 0) + var[index]="MasterX" + index = "%i,%i" % (-1, 1) + var[index]="MasterY" + index = "%i,%i" % (-1, 2) + var[index]="SlaveX" + index = "%i,%i" % (-1, 3) + var[index]="SlaveY" + index = "%i,%i" % (-1, 4) + var[index]="RMS_X" + index = "%i,%i" % (-1, 5) + var[index]="RMS_Y" + for y in range (0,5): + index = "%i,%i" % (y, -1) + var[index]=y+1 + + label = Label(root3, text="Rectification") + label.pack(side = 'top', fill = 'x') + + quit = Button(root3, text="QUIT", command=root3.destroy) + quit.pack(side = 'bottom', fill = 'x') + global test + test = Table(root3, + rows=10, + cols=7, + state='disabled', + width=12, + height=12, + titlerows=1, + titlecols=1, + roworigin=-1, + colorigin=-1, + selectmode='browse', + selecttype='row', + rowstretch='unset', + colstretch='last', + browsecmd=browsecmd, + flashmode='on', + variable=var, + usecommand=0, + command=test_cmd) + test.pack(expand=1, fill='both') + test.tag_configure('sel', background = 'yellow') + test.tag_configure('active', background = 'blue') + test.tag_configure('title', anchor='w', bg='blue', relief='sunken') + root3.mainloop() +def write_to_table_master(x,y,count,count1): + global var,test + index = "%i,%i" % (count-1, 2) + var[index]=x + index = "%i,%i" % (count-1, 3) + var[index]=y + test.pack(expand=1, fill='both') + if (count1==count): + RMS_clac() +def write_to_table_slave(x,y,count,count1): + global var,test + index = "%i,%i" % (count-1, 0) + var[index]=x + index = "%i,%i" % (count-1, 1) + var[index]=y + test.pack(expand=1, fill='both') + if (count1==count): + RMS_clac(count) +def RMS_clac(count): + global var,test + index1 = "%i,%i" % (count-1, 0) + index2 = "%i,%i" % (count-1, 1) + index3 = "%i,%i" % (count-1, 2) + index4= "%i,%i" % (count-1, 3) + x1=var[index1] + x2=var[index3] + y1=var[index2] + y2=var[index4] + xrms=(x1**2+x2**2)/2 + xrms=xrms**0.5 + yrms=(y1**2+y2**2)/2 + yrms=yrms**0.5 + index1 = "%i,%i" % (count-1, 4) + index2 = "%i,%i" % (count-1, 5) + var[index1]=xrms + var[index2]=yrms + test.pack(expand=1, fill='both') + + + diff --git a/ISODATA/isodata-working.py b/ISODATA/isodata-working.py new file mode 100644 index 0000000..ece4a15 --- /dev/null +++ b/ISODATA/isodata-working.py @@ -0,0 +1,463 @@ +import numpy as np +from scipy.cluster import vq +import scipy.misc +from PIL import Image +import tifwork + +def initialize_parameters(parameters=None): + """Auxiliar function to set default values to all the parameters not + given a value by the user. + + """ + parameters = {} if not parameters else parameters + + def safe_pull_value(parameters, key, default): + return parameters.get(key, default) + + # number of clusters desired + K = safe_pull_value(parameters, 'K', 5) + + # maximum number of iterations + I = safe_pull_value(parameters, 'I', 100) + + # maximum of number of pairs of clusters which can be merged + P = safe_pull_value(parameters, 'P', 4) + + # threshold value for minimum number of samples in each cluster + # (discarding clusters) + THETA_M = safe_pull_value(parameters, 'THETA_M', 10) + + # threshold value for standard deviation (for split) + THETA_S = safe_pull_value(parameters, 'THETA_S', 1) + # threshold value for pairwise distances (for merge) + THETA_C = safe_pull_value(parameters, 'THETA_C', 20) + + # percentage of change in clusters between each iteration + #(to stop algorithm) + THETA_O = 0.05 + + #can use any of both fixed or random + # number of starting clusters + #k = np.random.randint(1, K) + k = safe_pull_value(parameters, 'k', K) + + ret = locals() + ret.pop('safe_pull_value') + ret.pop('parameters') + globals().update(ret) + + +def quit_low_change_in_clusters(centers, last_centers, iter): + """Stop algorithm by low change in the clusters values between each + iteration. + + :returns: True if should stop, otherwise False. + + """ + quit = False + + if centers.shape == last_centers.shape: + thresholds = np.abs((centers - last_centers) / (last_centers + 1)) + + if np.all(thresholds <= THETA_O): # percent of change in [0:1] + quit = True +# print "Isodata(info): Stopped by low threshold at the centers." +# print "Iteration step: %s" % iter + + return quit + + + + +def merge_clusters(img_class_flat, centers, clusters_list): + """ + Merge by pair of clusters in 'below_threshold' to form new clusters. + """ + pair_dists = compute_pairwise_distances(centers) + + first_p_elements = pair_dists[:P] + + below_threshold = [(c1, c2) for d, (c1, c2) in first_p_elements + if d < THETA_C] + + if below_threshold: + k, bands = centers.shape + count_per_cluster = np.zeros(k) + to_add = np.array([[]]).reshape(0,bands) # new clusters to add + to_delete = np.array([[]]).reshape(0,bands) # clusters to delete + + for cluster in xrange(0, k): + result = np.where(img_class_flat == clusters_list[cluster]) + indices = result[0] + count_per_cluster[cluster] = indices.size + + for c1, c2 in below_threshold: + c1_count = float(count_per_cluster[c1]) + 1 + c2_count = float(count_per_cluster[c2]) + factor = 1.0 / (c1_count + c2_count) + weight_c1 = c1_count * centers[c1] #weight_c1 = [x,y,z] + weight_c2 = c2_count * centers[c2] #weight_c1 = [x,y,z] + + value = round(factor * (weight_c1 + weight_c2)) #value = [x,y,z] + + to_add = np.vstack([to_add, value]) + to_delete = np.vstack([to_delete, [c1, c2]]) + + #delete old clusters and their indices from the availables array + centers = np.delete(centers, to_delete,axis =0) + clusters_list = np.delete(clusters_list, to_delete) + + #generate new indices for the new clusters + #starting from the max index 'to_add.size' times + start = int(clusters_list.max()) + end = to_add.size + start + + centers = np.append(centers, to_add) + clusters_list = np.append(clusters_list, xrange(start, end)) + + #centers, clusters_list = sort_arrays_by_first(centers, clusters_list) + + return centers, clusters_list + + +def compute_pairwise_distances(centers): + """ + Compute the pairwise distances 'pair_dists', between every two clusters + centers and returns them sorted. + Returns: + - a list with tuples, where every tuple has in it's first coord the + distance between to clusters, and in the second coord has a tuple, + with the numbers of the clusters measured. + Output example: + [(d1,(cluster_1,cluster_2)), + (d2,(cluster_3,cluster_4)), + ... + (dn, (cluster_n,cluster_n+1))] + """ + pair_dists = [] + size = centers.shape[0] + + for i in xrange(0, size): + for j in xrange(0, size): + if i > j: + di = np.abs(centers[i] - centers[j]) + di = di**2 + d = np.sum(di) + d = d**0.5 + pair_dists.append((d, (i, j))) + + #return it sorted on the first elem + return sorted(pair_dists ) + + +def split_clusters(img_flat, img_class_flat, centers, clusters_list): + """ + Split clusters to form new clusters. + """ + assert centers.shape[0] == clusters_list.size, \ + "ERROR: split() centers and clusters_list size are different" + + delta = 10 + (k,bands) = centers.shape + count_per_cluster = np.zeros(k) + stddev = np.array([]).reshape(0,bands) + + avg_dists_to_clusters = compute_avg_distance(img_flat, img_class_flat, + centers, clusters_list) + d = compute_overall_distance(img_class_flat, avg_dists_to_clusters, + clusters_list) + + # compute all the standard deviation of the clusters + for cluster in xrange(0, k): + indices = np.where(img_class_flat == clusters_list[cluster])[0] + count_per_cluster[cluster] = indices.size + value = ((img_flat[indices] - centers[cluster]) ** 2).sum(axis = 0) + value /= count_per_cluster[cluster] + value = np.sqrt(value) + stddev = np.vstack([stddev, value]) + + meanstd = np.mean(stddev,axis= 1) + cluster = meanstd.argmax() + max_stddev = meanstd[cluster] + max_clusters_list = int(clusters_list.max()) + + if max_stddev > THETA_S: + if avg_dists_to_clusters[cluster] >= d: + if count_per_cluster[cluster] > (2.0 * THETA_M): + old_cluster = centers[cluster] + new_cluster_1 = old_cluster + delta + new_cluster_2 = old_cluster - delta + + centers = np.delete(centers, cluster, axis = 0) + clusters_list = np.delete(clusters_list, cluster) + + centers = np.vstack([centers, new_cluster_1, new_cluster_2]) + clusters_list = np.append(clusters_list, [max_clusters_list, + (max_clusters_list + 1)]) + + centers, clusters_list = sort_arrays_by_first(centers, + clusters_list) + + assert centers.shape[0] == clusters_list.size, \ + "ERROR: split() centers and clusters_list size are different" + + return centers, clusters_list + +def compute_overall_distance(img_class_flat, avg_dists_to_clusters, + clusters_list): + """ + Computes the overall distance of the samples from their respective cluster + centers. + """ + k = avg_dists_to_clusters.size + total = img_class_flat.size + count_per_cluster = np.zeros(k) + + for cluster in xrange(0, k): + indices = np.where(img_class_flat == clusters_list[cluster])[0] + count_per_cluster[cluster] = indices.size + + d = ((count_per_cluster / total) * avg_dists_to_clusters).sum() + + return d + +def compute_avg_distance(img_flat, img_class_flat, centers, clusters_list): + """ + Computes all the average distances to the center in each cluster. + """ + (k,bands) = centers.shape + avg_dists_to_clusters = np.array([]) + + for cluster in xrange(0, k): + indices = np.where(img_class_flat == clusters_list[cluster])[0] + + total_per_cluster = indices.size + 1 + cen = centers[cluster].reshape(1,bands) + + x , dist = vq.vq(img_flat[indices],cen) + + sum_per_cluster = dist.sum() + #sum_per_cluster = (np.abs(img_flat[indices] - centers[cluster])).sum() + + dj = (sum_per_cluster / float(total_per_cluster)) + + avg_dists_to_clusters = np.append(avg_dists_to_clusters, dj) + + return avg_dists_to_clusters + +def discard_clusters(img_class_flat, centers, clusters_list): + """ + Discard clusters with fewer than THETA_M. + """ + (k,bands) = centers.shape + to_delete = np.array([]) + + assert centers.shape[0] == clusters_list.size, \ + "ERROR: discard_cluster() centers and clusters_list size are different" + + for cluster in xrange(0, k): + indices = np.where(img_class_flat == clusters_list[cluster])[0] + total_per_cluster = indices.size + if total_per_cluster <= THETA_M: + to_delete = np.append(to_delete, cluster) + + if to_delete.size: + new_centers = np.delete(centers, to_delete,axis= 0) + new_clusters_list = np.delete(clusters_list, to_delete) + else: + new_centers = centers + new_clusters_list = clusters_list + + #new_centers, new_clusters_list = sort_arrays_by_first(new_centers, new_clusters_list) + +# shape_bef = centers.shape[0] +# shape_aft = new_centers.shape[0] +# print "Isodata(info): Discarded %s clusters." % (shape_bef - shape_aft) + +# if to_delete.size: +# print "Clusters discarded %s" % to_delete + + assert new_centers.shape[0] == new_clusters_list.size, \ + "ERROR: discard_cluster() centers and clusters_list size are different" + + return new_centers, new_clusters_list + +def update_clusters(img_flat, img_class_flat, centers, clusters_list): + + """ Update clusters. """ + (k,bands) = centers.shape + new_centers = np.array([]).reshape(0,bands) + + new_clusters_list = np.array([]) + + assert centers.shape[0] == clusters_list.size, \ + "ERROR: update_clusters() centers and clusters_list size are different" + + for cluster in xrange(0, k): + indices = np.where(img_class_flat == clusters_list[cluster])[0] + #get whole cluster + cluster_values = img_flat[indices] + #sum and count the values + sum_per_cluster = cluster_values.sum(axis = 0) + total_per_cluster = (cluster_values.shape[0]) + 1 + #compute the new center of the cluster + new_cluster = sum_per_cluster / total_per_cluster + + new_centers = np.vstack([new_centers, new_cluster]) + new_clusters_list = np.append(new_clusters_list, cluster) + + #new_centers, new_clusters_list = sort_arrays_by_first(new_centers, new_clusters_list) + + assert new_centers.shape[0] == new_clusters_list.size, \ + "ERROR: update_clusters() centers and clusters_list size are different" + + return new_centers, new_clusters_list + +def initial_clusters(img_flat, k, method="linspace"): + """ + Define initial clusters centers as startup. + By default, the method is "linspace". Other method available is "random". + """ + methods_availables = ["linspace", "random"] + + assert method in methods_availables, "ERROR: method %s is no valid." \ + "Methods availables %s" \ + % (method, methods_availables) + if method == "linspace": + start, end = 0, img_flat.shape[0] + indices = np.random.randint(start, end, k) + centers = np.array([]) + for x in indices: + centers = np.append(centers,img_flat[x]) + + centers = centers.reshape(k,img_flat.shape[1]) + if method == "random": + start, end = 0, img_flat.shape[0] + indices = np.random.randint(start, end, k) + centers = np.array([]) + for x in indices: + centers = np.append(centers,img_flat[x]) + + centers = centers.reshape(k,img_flat.shape[1]) + return centers + +def sort_arrays_by_first(centers, clusters_list): + """ + Sort the array 'centers' and the with indices of the sorted centers + order the array 'clusters_list'. + Example: centers=[22, 33, 0, 11] and cluster_list=[7,6,5,4] + returns (array([ 0, 11, 22, 33]), array([5, 4, 7, 6])) + """ + assert centers.shape[0] == clusters_list.size, \ + "ERROR: sort_arrays_by_first centers and clusters_list size are not equal" + + indices = np.argsort(centers,axis=1) #sorted indic + + sorted_centers = centers[indices[:,0]] + sorted_clusters_list = clusters_list[indices[:,0]] + + return sorted_centers, sorted_clusters_list + + + + + +def isodata_classification(img, parameters=None): + """ + Classify a numpy 'img' using Isodata algorithm. + Parameters: a dictionary with the following keys. + - img: an input numpy array that contains the image to classify. + - parameters: a dictionary with the initial values. + If 'parameters' are not specified, the algorithm uses the default + ones. + + number of clusters desired. + K = 15 + + max number of iterations. + I = 100 + + max number of pairs of clusters which can be ,erged. + P = 2 + + threshold value for min number in each cluster. + THETA_M = 10 + + threshold value for standard deviation (for split). + THETA_S = 0.1 + + threshold value for pairwise distances (for merge). + THETA_C = 2 + + threshold change in the clusters between each iter. + THETA_O = 0.01 + Note: if some(or all) parameters are nos providen, default values + will be used. + Returns: + - img_class: a numpy array with the classification. + """ + global K, I, P, THETA_M, THETA_S, THEHTA_C, THETA_O, k + initialize_parameters(parameters) + + N, M,bands = img.shape # for reshaping at the end + img_flat = img.reshape((N*M),bands) + clusters_list = np.arange(k) # number of clusters availables + + print "Isodata(info): Starting algorithm with %s classes" % k + centers = initial_clusters(img_flat, k, "linspace") + + for iter in xrange(0, I): + # print "Isodata(info): Iteration:%s Num Clusters:%s" % (iter, k) + last_centers = centers.copy() + # assing each of the samples to the closest cluster center + img_class_flat, dists = vq.vq(img_flat, centers) + + centers, clusters_list = discard_clusters(img_class_flat, + centers, clusters_list) + centers, clusters_list = update_clusters(img_flat, + img_class_flat, + centers, clusters_list) + k = centers.shape[0] + + if k <= (K / 2.0): # too few clusters => split clusters + centers, clusters_list = split_clusters(img_flat, img_class_flat, + centers, clusters_list) + + elif k > (K * 2.0): # too many clusters => merge clusters + centers, clusters_list = merge_clusters(img_class_flat, centers, + clusters_list) + else: # nor split or merge are needed + pass + + k , bands = centers.shape +############################################################################### + if quit_low_change_in_clusters(centers, last_centers, iter): + break + +# take_snapshot(img_class_flat.reshape(N, M), iteration_step=iter) +############################################################################### + print "Isodata(info): Finished with %s classes" % k + print "Isodata(info): Number of Iterations: %s" % (iter + 1) + + return img_class_flat + + + +filename = 'liss2.tif' +dataset = tifwork.openTIF(filename) + +(cols,rows,bands,bandArr) = tifwork.detailsTIF(dataset) + +bandArr = tifwork.getBand(dataset,bands,bandArr) + + +imageArray = np.array(bandArr,dtype =float) +x = {'K':5 , 'I':200} +isoarr = isodata_classification(imageArray,x) +#print rows +colorArray=np.array([[0,0,100],[100,0,0],[0,100,0],[100,100,0],[75,75,75],[0,100,100],[100,0,100],[50,25,25],[25,50,25],[25,25,50]]) +clusteredArray = np.zeros((rows*cols,3)) + +clusters = isoarr.max() +#print clusters +for i in xrange(clusters+1): + indices = np.where(isoarr == i)[0] + if indices.size: + clusteredArray[indices] = colorArray[i] + +clusteredArray = clusteredArray.reshape(rows,cols,3) +#print clusteredArray +scipy.misc.imsave('iso.jpg',clusteredArray) diff --git a/ISODATA/isodata.py b/ISODATA/isodata.py new file mode 100644 index 0000000..a715976 --- /dev/null +++ b/ISODATA/isodata.py @@ -0,0 +1,469 @@ +import numpy as np +from scipy.cluster import vq +import scipy.misc +from PIL import Image +import tifwork +import sys +sys.path.append('../GUI/') +import imageGUI +def initialize_parameters(parameters=None): + """Auxiliar function to set default values to all the parameters not + given a value by the user. + + """ + parameters = {} if not parameters else parameters + + def safe_pull_value(parameters, key, default): + return parameters.get(key, default) + + # number of clusters desired + K = safe_pull_value(parameters, 'K', 5) + + # maximum number of iterations + I = safe_pull_value(parameters, 'I', 100) + + # maximum of number of pairs of clusters which can be merged + P = safe_pull_value(parameters, 'P', 4) + + # threshold value for minimum number of samples in each cluster + # (discarding clusters) + THETA_M = safe_pull_value(parameters, 'THETA_M', 10) + + # threshold value for standard deviation (for split) + THETA_S = safe_pull_value(parameters, 'THETA_S', 1) + # threshold value for pairwise distances (for merge) + THETA_C = safe_pull_value(parameters, 'THETA_C', 20) + + # percentage of change in clusters between each iteration + #(to stop algorithm) + THETA_O = 0.01 + + #can use any of both fixed or random + # number of starting clusters + #k = np.random.randint(1, K) + k = safe_pull_value(parameters, 'k', K) + + ret = locals() + ret.pop('safe_pull_value') + ret.pop('parameters') + globals().update(ret) + + +def quit_low_change_in_clusters(centers, last_centers, iter): + """Stop algorithm by low change in the clusters values between each + iteration. + + :returns: True if should stop, otherwise False. + + """ + quit = False + + if centers.shape == last_centers.shape: + thresholds = np.abs((centers - last_centers) / (last_centers + 1)) + + if np.all(thresholds <= THETA_O): # percent of change in [0:1] + quit = True +# print "Isodata(info): Stopped by low threshold at the centers." +# print "Iteration step: %s" % iter + + return quit + + + + +def merge_clusters(img_class_flat, centers, clusters_list): + """ + Merge by pair of clusters in 'below_threshold' to form new clusters. + """ + pair_dists = compute_pairwise_distances(centers) + + first_p_elements = pair_dists[:P] + + below_threshold = [(c1, c2) for d, (c1, c2) in first_p_elements + if d < THETA_C] + + if below_threshold: + k, bands = centers.shape + count_per_cluster = np.zeros(k) + to_add = np.array([[]]).reshape(0,bands) # new clusters to add + to_delete = np.array([[]]).reshape(0,bands) # clusters to delete + + for cluster in xrange(0, k): + result = np.where(img_class_flat == clusters_list[cluster]) + indices = result[0] + count_per_cluster[cluster] = indices.size + + for c1, c2 in below_threshold: + c1_count = float(count_per_cluster[c1]) + 1 + c2_count = float(count_per_cluster[c2]) + factor = 1.0 / (c1_count + c2_count) + weight_c1 = c1_count * centers[c1] #weight_c1 = [x,y,z] + weight_c2 = c2_count * centers[c2] #weight_c1 = [x,y,z] + + value = round(factor * (weight_c1 + weight_c2)) #value = [x,y,z] + + to_add = np.vstack([to_add, value]) + to_delete = np.vstack([to_delete, [c1, c2]]) + + #delete old clusters and their indices from the availables array + centers = np.delete(centers, to_delete,axis =0) + clusters_list = np.delete(clusters_list, to_delete) + + #generate new indices for the new clusters + #starting from the max index 'to_add.size' times + start = int(clusters_list.max()) + end = to_add.size + start + + centers = np.append(centers, to_add) + clusters_list = np.append(clusters_list, xrange(start, end)) + + #centers, clusters_list = sort_arrays_by_first(centers, clusters_list) + + return centers, clusters_list + + +def compute_pairwise_distances(centers): + """ + Compute the pairwise distances 'pair_dists', between every two clusters + centers and returns them sorted. + Returns: + - a list with tuples, where every tuple has in it's first coord the + distance between to clusters, and in the second coord has a tuple, + with the numbers of the clusters measured. + Output example: + [(d1,(cluster_1,cluster_2)), + (d2,(cluster_3,cluster_4)), + ... + (dn, (cluster_n,cluster_n+1))] + """ + pair_dists = [] + size = centers.shape[0] + + for i in xrange(0, size): + for j in xrange(0, size): + if i > j: + di = np.abs(centers[i] - centers[j]) + di = di**2 + d = np.sum(di) + d = d**0.5 + pair_dists.append((d, (i, j))) + + #return it sorted on the first elem + return sorted(pair_dists ) + + +def split_clusters(img_flat, img_class_flat, centers, clusters_list): + """ + Split clusters to form new clusters. + """ + assert centers.shape[0] == clusters_list.size, \ + "ERROR: split() centers and clusters_list size are different" + + delta = 10 + (k,bands) = centers.shape + count_per_cluster = np.zeros(k) + stddev = np.array([]).reshape(0,bands) + + avg_dists_to_clusters = compute_avg_distance(img_flat, img_class_flat, + centers, clusters_list) + d = compute_overall_distance(img_class_flat, avg_dists_to_clusters, + clusters_list) + + # compute all the standard deviation of the clusters + for cluster in xrange(0, k): + indices = np.where(img_class_flat == clusters_list[cluster])[0] + count_per_cluster[cluster] = indices.size + value = ((img_flat[indices] - centers[cluster]) ** 2).sum(axis = 0) + value /= count_per_cluster[cluster] + value = np.sqrt(value) + stddev = np.vstack([stddev, value]) + + meanstd = np.mean(stddev,axis= 1) + cluster = meanstd.argmax() + max_stddev = meanstd[cluster] + max_clusters_list = int(clusters_list.max()) + + if max_stddev > THETA_S: + if avg_dists_to_clusters[cluster] >= d: + if count_per_cluster[cluster] > (2.0 * THETA_M): + old_cluster = centers[cluster] + new_cluster_1 = old_cluster + delta + new_cluster_2 = old_cluster - delta + + centers = np.delete(centers, cluster, axis = 0) + clusters_list = np.delete(clusters_list, cluster) + + centers = np.vstack([centers, new_cluster_1, new_cluster_2]) + clusters_list = np.append(clusters_list, [max_clusters_list, + (max_clusters_list + 1)]) + + centers, clusters_list = sort_arrays_by_first(centers, + clusters_list) + + assert centers.shape[0] == clusters_list.size, \ + "ERROR: split() centers and clusters_list size are different" + + return centers, clusters_list + +def compute_overall_distance(img_class_flat, avg_dists_to_clusters, + clusters_list): + """ + Computes the overall distance of the samples from their respective cluster + centers. + """ + k = avg_dists_to_clusters.size + total = img_class_flat.size + count_per_cluster = np.zeros(k) + + for cluster in xrange(0, k): + indices = np.where(img_class_flat == clusters_list[cluster])[0] + count_per_cluster[cluster] = indices.size + + d = ((count_per_cluster / total) * avg_dists_to_clusters).sum() + + return d + +def compute_avg_distance(img_flat, img_class_flat, centers, clusters_list): + """ + Computes all the average distances to the center in each cluster. + """ + (k,bands) = centers.shape + avg_dists_to_clusters = np.array([]) + + for cluster in xrange(0, k): + indices = np.where(img_class_flat == clusters_list[cluster])[0] + + total_per_cluster = indices.size + 1 + cen = centers[cluster].reshape(1,bands) + + x , dist = vq.vq(img_flat[indices],cen) + + sum_per_cluster = dist.sum() + #sum_per_cluster = (np.abs(img_flat[indices] - centers[cluster])).sum() + + dj = (sum_per_cluster / float(total_per_cluster)) + + avg_dists_to_clusters = np.append(avg_dists_to_clusters, dj) + + return avg_dists_to_clusters + +def discard_clusters(img_class_flat, centers, clusters_list): + """ + Discard clusters with fewer than THETA_M. + """ + (k,bands) = centers.shape + to_delete = np.array([]) + + assert centers.shape[0] == clusters_list.size, \ + "ERROR: discard_cluster() centers and clusters_list size are different" + + for cluster in xrange(0, k): + indices = np.where(img_class_flat == clusters_list[cluster])[0] + total_per_cluster = indices.size + if total_per_cluster <= THETA_M: + to_delete = np.append(to_delete, cluster) + + if to_delete.size: + new_centers = np.delete(centers, to_delete,axis= 0) + new_clusters_list = np.delete(clusters_list, to_delete) + else: + new_centers = centers + new_clusters_list = clusters_list + + #new_centers, new_clusters_list = sort_arrays_by_first(new_centers, new_clusters_list) + +# shape_bef = centers.shape[0] +# shape_aft = new_centers.shape[0] +# print "Isodata(info): Discarded %s clusters." % (shape_bef - shape_aft) + +# if to_delete.size: +# print "Clusters discarded %s" % to_delete + + assert new_centers.shape[0] == new_clusters_list.size, \ + "ERROR: discard_cluster() centers and clusters_list size are different" + + return new_centers, new_clusters_list + +def update_clusters(img_flat, img_class_flat, centers, clusters_list): + + """ Update clusters. """ + (k,bands) = centers.shape + new_centers = np.array([]).reshape(0,bands) + + new_clusters_list = np.array([]) + + assert centers.shape[0] == clusters_list.size, \ + "ERROR: update_clusters() centers and clusters_list size are different" + + for cluster in xrange(0, k): + indices = np.where(img_class_flat == clusters_list[cluster])[0] + #get whole cluster + cluster_values = img_flat[indices] + #sum and count the values + sum_per_cluster = cluster_values.sum(axis = 0) + total_per_cluster = (cluster_values.shape[0]) + 1 + #compute the new center of the cluster + new_cluster = sum_per_cluster / total_per_cluster + + new_centers = np.vstack([new_centers, new_cluster]) + new_clusters_list = np.append(new_clusters_list, cluster) + + #new_centers, new_clusters_list = sort_arrays_by_first(new_centers, new_clusters_list) + + assert new_centers.shape[0] == new_clusters_list.size, \ + "ERROR: update_clusters() centers and clusters_list size are different" + + return new_centers, new_clusters_list + +def initial_clusters(img_flat, k, method="linspace"): + """ + Define initial clusters centers as startup. + By default, the method is "linspace". Other method available is "random". + """ + methods_availables = ["linspace", "random"] + + assert method in methods_availables, "ERROR: method %s is no valid." \ + "Methods availables %s" \ + % (method, methods_availables) + if method == "linspace": + start, end = 0, img_flat.shape[0] + indices = np.random.randint(start, end, k) + centers = np.array([]) + for x in indices: + centers = np.append(centers,img_flat[x]) + + centers = centers.reshape(k,img_flat.shape[1]) + if method == "random": + start, end = 0, img_flat.shape[0] + indices = np.random.randint(start, end, k) + centers = np.array([]) + for x in indices: + centers = np.append(centers,img_flat[x]) + + centers = centers.reshape(k,img_flat.shape[1]) + return centers + +def sort_arrays_by_first(centers, clusters_list): + """ + Sort the array 'centers' and the with indices of the sorted centers + order the array 'clusters_list'. + Example: centers=[22, 33, 0, 11] and cluster_list=[7,6,5,4] + returns (array([ 0, 11, 22, 33]), array([5, 4, 7, 6])) + """ + assert centers.shape[0] == clusters_list.size, \ + "ERROR: sort_arrays_by_first centers and clusters_list size are not equal" + + indices = np.argsort(centers,axis=1) #sorted indic + + sorted_centers = centers[indices[:,0]] + sorted_clusters_list = clusters_list[indices[:,0]] + + return sorted_centers, sorted_clusters_list + + + + + +def isodata_classification(img, parameters=None): + """ + Classify a numpy 'img' using Isodata algorithm. + Parameters: a dictionary with the following keys. + - img: an input numpy array that contains the image to classify. + - parameters: a dictionary with the initial values. + If 'parameters' are not specified, the algorithm uses the default + ones. + + number of clusters desired. + K = 15 + + max number of iterations. + I = 100 + + max number of pairs of clusters which can be ,erged. + P = 2 + + threshold value for min number in each cluster. + THETA_M = 10 + + threshold value for standard deviation (for split). + THETA_S = 0.1 + + threshold value for pairwise distances (for merge). + THETA_C = 2 + + threshold change in the clusters between each iter. + THETA_O = 0.01 + Note: if some(or all) parameters are nos providen, default values + will be used. + Returns: + - img_class: a numpy array with the classification. + """ + global K, I, P, THETA_M, THETA_S, THEHTA_C, THETA_O, k + initialize_parameters(parameters) + + N, M,bands = img.shape # for reshaping at the end + img_flat = img.reshape((N*M),bands) + clusters_list = np.arange(k) # number of clusters availables + + print "Isodata(info): Starting algorithm with %s classes" % k + centers = initial_clusters(img_flat, k, "linspace") + + for iter in xrange(0, I): + # print "Isodata(info): Iteration:%s Num Clusters:%s" % (iter, k) + last_centers = centers.copy() + # assing each of the samples to the closest cluster center + img_class_flat, dists = vq.vq(img_flat, centers) + + centers, clusters_list = discard_clusters(img_class_flat, + centers, clusters_list) + centers, clusters_list = update_clusters(img_flat, + img_class_flat, + centers, clusters_list) + k = centers.shape[0] + + if k <= (K / 2.0): # too few clusters => split clusters + centers, clusters_list = split_clusters(img_flat, img_class_flat, + centers, clusters_list) + + elif k > (K * 2.0): # too many clusters => merge clusters + centers, clusters_list = merge_clusters(img_class_flat, centers, + clusters_list) + else: # nor split or merge are needed + pass + + k , bands = centers.shape +############################################################################### + if quit_low_change_in_clusters(centers, last_centers, iter): + break + +# take_snapshot(img_class_flat.reshape(N, M), iteration_step=iter) +############################################################################### + print "Isodata(info): Finished with %s classes" % k + print "Isodata(info): Number of Iterations: %s" % (iter + 1) + + return img_class_flat + + + +def isoclass (filename , colorArray,x): + dataset = tifwork.openTIF(filename) + + (cols,rows,bands,bandArr) = tifwork.detailsTIF(dataset) + + bandArr = tifwork.getBand(dataset,bands,bandArr) + + + + imageArray = np.array(bandArr,dtype =float) + + isoarr = isodata_classification(imageArray,x) + print isoarr.shape + #print rows + #colorArray=np.array([[0,0,100],[100,0,0],[0,100,0],[100,100,0],[75,75,75],[0,100,100],[100,0,100],[50,25,25],[25,50,25],[25,25,50]]) + clusteredArray = np.zeros((rows*cols,3)) + print clusteredArray.shape + clusters = isoarr.max() + #print clusters + for i in xrange(clusters+1): + indices = np.where(isoarr == i)[0] + if indices.size: + clusteredArray[indices] = colorArray[i] + + clusteredArray = clusteredArray.reshape(rows,cols,3) + #print clusteredArray + scipy.misc.imsave('iso.jpg',clusteredArray) + imageGUI.imdisplay('iso.jpg','ISODATA-Image') + print 'iso done' diff --git a/ISODATA/tifwork.py b/ISODATA/tifwork.py new file mode 100644 index 0000000..d414845 --- /dev/null +++ b/ISODATA/tifwork.py @@ -0,0 +1,45 @@ +from osgeo import gdal +import PIL.Image as Image +import numpy as np + + + +gdal.AllRegister() + +def openTIF(filename): + dataset =gdal.Open(filename,gdal.GA_ReadOnly) + if dataset is None: + print 'Could Not Open' + filename + #Alternatively Raise an Event here + sys.exit(1) + + return dataset + +def detailsTIF(dataset): + cols = dataset.RasterXSize + rows = dataset.RasterYSize + bands = dataset.RasterCount + bandArray = np.zeros((rows,cols,bands),dtype = float) + return (cols, rows,bands,bandArray) + +def getBand(dataset,bands,bandArr): + for x in range(1,bands+1): + band=dataset.GetRasterBand(x) + array=band.ReadAsArray() + bandArr[:,:,x-1] = array + return bandArr + + +def selectBand(bandArray,rows,cols,ch1,ch2,ch3): + + ch1 = int(ch1) + ch2 = int(ch2) + ch3 = int(ch3) + combi= np.zeros((rows,cols,3),'uint8') + combi[:,:,0]=bandArray[:,:,ch1-1] + combi[:,:,1]=bandArray[:,:,ch2-1] + combi[:,:,2]=bandArray[:,:,ch3-1] + combImage= Image.fromarray(combi) + combImage.save('guiTry'+'.jpeg') + combImage.show() + diff --git a/K-means/kmeans.py b/K-means/kmeans.py new file mode 100644 index 0000000..6412711 --- /dev/null +++ b/K-means/kmeans.py @@ -0,0 +1,89 @@ +from PIL import Image +import numpy as np +import pylab +#from PIL import Image +import random +import tifwork as tw +import scipy.misc + + + +def initCentroids(Dataset,K,z): + init_centroid = np.zeros((K,z)) + for i in range(0,K): + j = random.choice(Dataset) + init_centroid[i,:] = j + return init_centroid + +def kmeans(Dataset,K,initial_centroid): + (nos,z) = Dataset.shape + + idx = np.zeros((row*col),float) + dis = np.zeros(z,float) + for i in range(0,nos): + for j in range(0,K): + dis = (initial_centroid[j,:] - Dataset[i,:])**2 + dist = 0 + for k in range(0,z): + dist += dis[k] + if( j == 0): + minimum = dist + idx[i] = j + elif (dist < minimum): + minimum = dist + idx[i] = j + + centroid = newclus(K,nos,Dataset,idx) + return (idx,centroid) + +def newclus(K,nos,Dataset,idx): + centroid = np.zeros((K,z)) + for i in range(0,K): + mean = [0,0,0] + count = 0 + for j in range(0,nos): + if(idx[j] == i): + mean = mean+Dataset[j] + count+=1 + + mean = mean/count + centroid[i,:] = mean + return centroid + +Dataset = np.array(Image.open('good.jpg'),float) +(row,col,z) = Dataset.shape + +arr2 = np.zeros(Dataset.shape,float) + +Dataset = Dataset/255 + +# no of clusters +K = 4 + +#no of iters +iters = 3 + +Data_orig = Dataset +Dataset=Dataset.reshape(((row*col),z)) +#print Dataset.shape + + +initial_centroid = initCentroids(Dataset,K,z) +#print initial_centroid + +for q in range(0,iters): + + (idx,centroid)=kmeans(Dataset,K,initial_centroid) + +print idx.max() + +color = [(10,0,0),(0,25,0),(0,0,55),(10,10,10),(12,0,45),(34,65,0),(0,45,87),(100,100,100),(50,50,50),(12,54,77),(43,65,99)] +for i in range(0,(row*col)): + + Dataset[i] = color[int(idx[i])] + +Dataset=Dataset.reshape(row,col,z) + +print Dataset.shape +scipy.misc.imsave('kmeans.jpeg',Dataset) + diff --git a/K-means/kmeanswork.py b/K-means/kmeanswork.py new file mode 100644 index 0000000..95cdfe7 --- /dev/null +++ b/K-means/kmeanswork.py @@ -0,0 +1,44 @@ +from spectral import kmeans +from PIL import Image +import scipy.misc +import tifwork +import numpy as np +import sys +sys.path.append('../GUI/') +import imageGUI + +def kmea(colorArray,iterations,fileName): + print 'Kmeans' + + print colorArray + print iterations + print fileName + dataset = tifwork.openTIF(fileName) + + (cols,rows,bands,bandArr) = tifwork.detailsTIF(dataset) + + bandArr = tifwork.getBand(dataset,bands,bandArr) + + + imageArray = np.array(bandArr,dtype =float) + + clusters = len(colorArray) + print 'clusters = ' , clusters + #iterations = 3 + + (clusterNumber, colorArr) = kmeans(imageArray,clusters,iterations) + + #print colorArray.shape + #print clusterNumber + + clusteredArray = np.zeros((rows,cols,3)) + + for i in range(clusters): + index = clusterNumber == i + clusteredArray[index] = colorArray[i] + + + scipy.misc.imsave('kMeans.jpg',clusteredArray) + + imageGUI.imdisplay('kMeans.jpg','Kmeans-Image') + print 'kmeans done' diff --git a/K-means/tifwork.py b/K-means/tifwork.py new file mode 100644 index 0000000..29faa8a --- /dev/null +++ b/K-means/tifwork.py @@ -0,0 +1,46 @@ +from osgeo import gdal +import PIL.Image as Image +import numpy as np + + +#Register hardware drivers with the GDAL library +gdal.AllRegister() + + +def openTIF(filename): + dataset =gdal.Open(filename,gdal.GA_ReadOnly) + if dataset is None: + print 'Could Not Open' + filename + #Alternatively Raise an Event here + sys.exit(1) + + return dataset + +def detailsTIF(dataset): + cols = dataset.RasterXSize + rows = dataset.RasterYSize + bands = dataset.RasterCount + bandArray = np.zeros((rows,cols,bands),dtype = float) + return (cols, rows,bands,bandArray) + +def getBand(dataset,bands,bandArr): + for x in range(1,bands+1): + band=dataset.GetRasterBand(x) + array=band.ReadAsArray() + bandArr[:,:,x-1] = array + return bandArr + + +def selectBand(bandArray,rows,cols,ch1,ch2,ch3): + + ch1 = int(ch1) + ch2 = int(ch2) + ch3 = int(ch3) + combi= np.zeros((rows,cols,3),'uint8') + combi[:,:,0]=bandArray[:,:,ch1-1] + combi[:,:,1]=bandArray[:,:,ch2-1] + combi[:,:,2]=bandArray[:,:,ch3-1] + combImage= Image.fromarray(combi) + combImage.save('guiTry'+'.jpeg') + combImage.show() + diff --git a/LUT2label.py b/LUT2label.py new file mode 100644 index 0000000..01aafe2 --- /dev/null +++ b/LUT2label.py @@ -0,0 +1,46 @@ +import numpy as np + +def LUT2label(im,LUT): + #Create a label image using LUT obtained from a clustering operation of grayscale data + + # Intensity range + + Imin = float(np.min(im[:])) + Imax = float(np.max(im[:])) + I = np.transpose(np.array(np.arange(Imin,Imax+1))) + I = I[:, np.newaxis] + + #print I.shape + #Create a Label Image + + L = np.zeros(im.shape,int) + + #print L.shape + + for k in range(0, np.max(LUT)+1): + + + #intensity range for k-th class + i = np.nonzero(LUT==k) + + (arr ,)= i + arr = np.copy(arr[:,np.newaxis]) + #print 'arr shape is ', arr.shape + #print arr[1] + + i1 = arr[1] + + sz = np.size(arr) + #print arr[sz-1] + if sz > 1: + i2 = arr[sz-1] + else: + i2 = i1 + + #map the intensities in the range [I(i1),I(i2)] to class k] + bw = np.logical_and(im >= I[i1], im <= I[i2]) + + L[bw] = k + + + return L diff --git a/Licenses.txt b/Licenses.txt new file mode 100644 index 0000000..8a7f70f --- /dev/null +++ b/Licenses.txt @@ -0,0 +1,42 @@ +''' +The software aims to be an open-source package with basic, and advanced Image Processing features. +Copyright (C) 2014 Indian Institute of Remote Sensing, Dehradun + +The original authors of this program (in alphabetical order) are: + +--------------------------------------------------------------------------------------------------------------------------------------- +Sno. NAME Email( AT gmail DOT com) Role(s) +--------------------------------------------------------------------------------------------------------------------------------------- + +1. Abhishek Kaushik akaushik079 Rectification +2. Abhishek Kumar Roushan abhishek.roushan12 Histogram, Contrast +3. Abhishek Mohta mohta.abhishek GUI, Spectral +4. Girish Rathi girishrathi347 Contrast/ Spectral, Rectification GUI +5. Pragun Vinayak pragunvinayak GUI, Contrast, Histogram +6. Saloni Chandak saloni20121907 GUI, Documentation +7. Shalaka Somani shalaka195 GUI, Spectral +8. Siddhant Shrivastava sidhu94 Classification, Spatial, Polygons +9. Siddharth Dalmia sonudalmia Classification, Spatial, PCA, libraries +---------------------------------------------------------------------------------------------------------------------------------------- + + + Compatible with Python 2.7 ( NOT COMPATIBLE with Python(>3)) + + Dependencies: GDAL, NumPy, SciPy, OpenCV, Spectral Python, Tkinter, scikit-learn, scikit-fuzz + + + +This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +''' diff --git a/PCA.py b/PCA.py new file mode 100644 index 0000000..444c81f --- /dev/null +++ b/PCA.py @@ -0,0 +1,83 @@ +from PIL import Image +import numpy +import pylab +#from PIL import Image +from numpy import * +import tifwork as tw +import scipy.misc +import sys +sys.path.append('../GUI/') +import imageGUI +def pca(fileName): + dataset = tw.openTIF(fileName) + cols, rows,bands,bandArray = tw.detailsTIF(dataset) + bandArray = tw.getBand(dataset,bands,bandArray) + print bands + for i in range(0,bands): + + array = bandArray[:,:,i] + #print array + scipy.misc.imsave('./temp/PCA/test'+str(i)+'.png',array) + + imlist = [] + for i in range(0,bands): + imlist.append('./temp/PCA/test'+str(i)+'.png') + print imlist + + def pca(X): + # Principal Component Analysis + # input: X, matrix with training data as flattened arrays in rows + # return: projection matrix (with important dimensions first), + # variance and mean + + #get dimensions + num_data,dim = X.shape + + #center data + mean_X = X.mean(axis=0) + for i in range(num_data): + X[i] -= mean_X + + if dim>100: + print 'PCA - compact trick used' + M = dot(X,X.T) #covariance matrix + print M + e,EV = linalg.eigh(M) #eigenvalues and eigenvectors + print e + print EV + tmp = dot(X.T,EV).T #this is the compact trick + V = tmp[::-1] #reverse since last eigenvectors are the ones we want + S = sqrt(e)[::-1] #reverse since eigenvalues are in increasing order + else: + print 'PCA - SVD used' + U,S,V = linalg.svd(X) + V = V[:num_data] #only makes sense to return the first num_data + + #return the projection matrix, the variance and the mean + return V,S,mean_X + + + + im = numpy.array(Image.open(imlist[0])) #open one image to get the size + m,n = im.shape[0:2] #get the size of the images + imnbr = len(imlist) #get the number of images + + #create matrix to store all flattened images + immatrix = numpy.array([numpy.array(Image.open(imlist[i])).flatten() for i in range(imnbr)],'f') + + #perform PCA + V,S,immean = pca(immatrix) + + #mean image and first mode of variation + immean = immean.reshape(m,n) + + for i in range (0,bands): + mode = V[i].reshape(m,n) + scipy.misc.imsave('./temp/PCA/pca'+str(i+1)+'.png',mode) + x = imageGUI.imdisplay('./temp/PCA/pca'+str(i+1)+'.png','PCA '+str(i),1) + + #show the images + + scipy.misc.imsave('./temp/PCA/meanimage.png',immean) + imageGUI.imdisplay('./temp/PCA/meanimage.png','Mean Image',1) + diff --git a/PCA/Classif-test.py b/PCA/Classif-test.py new file mode 100644 index 0000000..ea2519f --- /dev/null +++ b/PCA/Classif-test.py @@ -0,0 +1,49 @@ +from PIL import Image +import numpy +import pylab +#from PIL import Image +from numpy import * +import tifwork as tw +import scipy.misc + + +arr=array(Image.open('guiTry.jpeg')) +(row,col,z) = arr.shape +arr2 = numpy.zeros(arr.shape,int) +print arr.shape + +print arr[:,:,0].min(),arr[:,:,0].mean(),arr[:,:,0].max() +print arr[:,:,1].min(),arr[:,:,1].mean(),arr[:,:,1].max() +print arr[:,:,2].min(),arr[:,:,2].mean(),arr[:,:,2].max() +# standard deviation from each band for each class will be required +# the deviation will be about the mean of the brightness value of all the bands +# 12 , 54, 67 +# mean = 44 + + +classes = [[(0,17),(0,65),(0,57)], [(17,47),(0,65),(0,57)]] +print classes[0][0][1] +print arr[0,0,0] in range(classes[0][0][0],classes[0][0][1]) +x = 0 +y = 0 + +for x in range (0,row): + for y in range (0,col): + if ((arr[x,y,0] in range(classes[0][0][0],classes[0][0][1])) and (arr[x,y,1] in range(classes[0][1][0],classes[0][1][1])) and(arr[x,y,2] in range(classes[0][2][0],classes[0][2][1]))): + arr[x,y,:] = (255,0,0) + if ((arr[x,y,0] in range(classes[1][0][0],classes[1][0][1])) and (arr[x,y,1] in range(classes[1][1][0],classes[1][1][1])) and(arr[x,y,2] in range(classes[1][2][0],classes[1][2][1]))): + arr[x,y,:] = (0,255,0) + else: + arr[x,y,:] = (255,255,255) + +scipy.misc.imsave('haha.jpg',arr) +''' +[12 , 13 +87, 23] +[32 , 13 +84, 23] +[62 , 13 +87, 23] + +''' + diff --git a/PCA/PCA.py b/PCA/PCA.py new file mode 100644 index 0000000..444c81f --- /dev/null +++ b/PCA/PCA.py @@ -0,0 +1,83 @@ +from PIL import Image +import numpy +import pylab +#from PIL import Image +from numpy import * +import tifwork as tw +import scipy.misc +import sys +sys.path.append('../GUI/') +import imageGUI +def pca(fileName): + dataset = tw.openTIF(fileName) + cols, rows,bands,bandArray = tw.detailsTIF(dataset) + bandArray = tw.getBand(dataset,bands,bandArray) + print bands + for i in range(0,bands): + + array = bandArray[:,:,i] + #print array + scipy.misc.imsave('./temp/PCA/test'+str(i)+'.png',array) + + imlist = [] + for i in range(0,bands): + imlist.append('./temp/PCA/test'+str(i)+'.png') + print imlist + + def pca(X): + # Principal Component Analysis + # input: X, matrix with training data as flattened arrays in rows + # return: projection matrix (with important dimensions first), + # variance and mean + + #get dimensions + num_data,dim = X.shape + + #center data + mean_X = X.mean(axis=0) + for i in range(num_data): + X[i] -= mean_X + + if dim>100: + print 'PCA - compact trick used' + M = dot(X,X.T) #covariance matrix + print M + e,EV = linalg.eigh(M) #eigenvalues and eigenvectors + print e + print EV + tmp = dot(X.T,EV).T #this is the compact trick + V = tmp[::-1] #reverse since last eigenvectors are the ones we want + S = sqrt(e)[::-1] #reverse since eigenvalues are in increasing order + else: + print 'PCA - SVD used' + U,S,V = linalg.svd(X) + V = V[:num_data] #only makes sense to return the first num_data + + #return the projection matrix, the variance and the mean + return V,S,mean_X + + + + im = numpy.array(Image.open(imlist[0])) #open one image to get the size + m,n = im.shape[0:2] #get the size of the images + imnbr = len(imlist) #get the number of images + + #create matrix to store all flattened images + immatrix = numpy.array([numpy.array(Image.open(imlist[i])).flatten() for i in range(imnbr)],'f') + + #perform PCA + V,S,immean = pca(immatrix) + + #mean image and first mode of variation + immean = immean.reshape(m,n) + + for i in range (0,bands): + mode = V[i].reshape(m,n) + scipy.misc.imsave('./temp/PCA/pca'+str(i+1)+'.png',mode) + x = imageGUI.imdisplay('./temp/PCA/pca'+str(i+1)+'.png','PCA '+str(i),1) + + #show the images + + scipy.misc.imsave('./temp/PCA/meanimage.png',immean) + imageGUI.imdisplay('./temp/PCA/meanimage.png','Mean Image',1) + diff --git a/PCA/tifwork.py b/PCA/tifwork.py new file mode 100644 index 0000000..d414845 --- /dev/null +++ b/PCA/tifwork.py @@ -0,0 +1,45 @@ +from osgeo import gdal +import PIL.Image as Image +import numpy as np + + + +gdal.AllRegister() + +def openTIF(filename): + dataset =gdal.Open(filename,gdal.GA_ReadOnly) + if dataset is None: + print 'Could Not Open' + filename + #Alternatively Raise an Event here + sys.exit(1) + + return dataset + +def detailsTIF(dataset): + cols = dataset.RasterXSize + rows = dataset.RasterYSize + bands = dataset.RasterCount + bandArray = np.zeros((rows,cols,bands),dtype = float) + return (cols, rows,bands,bandArray) + +def getBand(dataset,bands,bandArr): + for x in range(1,bands+1): + band=dataset.GetRasterBand(x) + array=band.ReadAsArray() + bandArr[:,:,x-1] = array + return bandArr + + +def selectBand(bandArray,rows,cols,ch1,ch2,ch3): + + ch1 = int(ch1) + ch2 = int(ch2) + ch3 = int(ch3) + combi= np.zeros((rows,cols,3),'uint8') + combi[:,:,0]=bandArray[:,:,ch1-1] + combi[:,:,1]=bandArray[:,:,ch2-1] + combi[:,:,2]=bandArray[:,:,ch3-1] + combImage= Image.fromarray(combi) + combImage.save('guiTry'+'.jpeg') + combImage.show() + diff --git a/SVM/getData.py b/SVM/getData.py new file mode 100644 index 0000000..e01ba56 --- /dev/null +++ b/SVM/getData.py @@ -0,0 +1,24 @@ +import PIL.Image as Image +import tifwork + +def getData(fileName, num): + #get dataset + dataset = tifwork.openTIF(fileName) + + #get details of dataset + (cols,rows,bands,bandArray) = tifwork.detailsTIF(dataset) + + #get all bands + bandArray = tifwork.getBand(dataset,bands,bandArray) + + #input a band + + workData = bandArray[:,:,num-1] + + #show original image and plot it + imdata = Image.fromarray(workData) + imdata = imdata.convert('L') + imdata.save('original.jpg') + #plot(workData,'Original') + filename = 'original.jpg' + return filename diff --git a/SVM/gui.py b/SVM/gui.py new file mode 100644 index 0000000..e61aa3d --- /dev/null +++ b/SVM/gui.py @@ -0,0 +1,120 @@ +import Tkinter as tk +from Tkinter import * +from tkMessageBox import * +import ttk +from PIL import Image +import tifwork +from tkFileDialog import askopenfilename +import sys +import matplotlib +matplotlib.use('TkAgg') +from numpy import arange, sin, pi +from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg +# implement the default mpl key bindings +from matplotlib.backend_bases import key_press_handler +import matplotlib.pyplot as plt +import matplotlib.image as mpimg +from matplotlib.figure import Figure +#from pylab import * +import cv,cv2 +import scipy.misc +import numpy as np + +def getData(fileName, num): + #get dataset + dataset = tifwork.openTIF(fileName) + + #get details of dataset + (cols,rows,bands,bandArray) = tifwork.detailsTIF(dataset) + + #get all bands + bandArray = tifwork.getBand(dataset,bands,bandArray) + + #input a band + + workData = bandArray[:,:,num-1] + + #show original image and plot it + imdata = Image.fromarray(workData) + imdata = imdata.convert('L') + imdata.save('original.jpg') + #plot(workData,'Original') + filename = 'original.jpg' + return filename + +global index +index = [] +val=[] +def exit(): + root.destroy() + +def index_return(): + global index + return index[:,0] + +def viewerwin(fileName): + global index + Root = tk.Tk() + Root.wm_title("Rectifiction") + Root.geometry("1080x720") + frame8=tk.Frame(Root) + frame8.pack() + f = Figure(figsize=(5,4), dpi=100) + a = f.add_subplot(111) + filename= 'sja.jpg' + img=mpimg.imread(filename) + #grayScaleImage = cv2.cvtColor(img,cv.CV_BGR2GRAY) + #print grayScaleImage + a.axis('off') + a.imshow(img) + overlayImage = np.ones_like(img) + overlayImage +=254 + #over = np.copy(overlayImage) + #print overlayImage + opacity = 1 + # a tk.DrawingArea + canvas = FigureCanvasTkAgg(f, master=Root) + canvas.show() + canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1) + toolbar = NavigationToolbar2TkAgg( canvas, Root ) + toolbar.update() + canvas._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=1) + global polygon + polygon = [] + closeFlag = False + def mouse_input_event(event): + global polygon + global index + #print 'Event is ', event + print 'input pixel loc is ',event.xdata,' ', event.ydata + polygon.append([np.int(event.xdata),np.int(event.ydata)]) + a.plot(event.xdata,event.ydata,'b.') + poly = plt.Polygon(polygon,closed = event.dblclick, fill = None, edgecolor ='b') + f.gca().add_patch(poly) + if (event.dblclick == True): + poly = plt.Polygon(polygon,closed = event.dblclick, fill = None, edgecolor ='b') + f.gca().add_patch(poly) + canvas.show() + polygon.pop() + polygon = [polygon] + print polygon + cv2.drawContours(overlayImage,np.array(polygon),0,255) + maskImage = np.zeros_like(img) + cv2.drawContours(maskImage,np.array(polygon),0,255,-1) + extractedImage = np.bitwise_and(over,maskImage) + #print extractedImage.shape + rows,cols,bands = extractedImage.shape + #print extractedImage + index = extractedImage > 0 + #extract = extractedImage.reshape((rows*cols),bands) + print index[:,0] + scipy.misc.imsave("poly1.jpg",extractedImage) + polygon = [] + canvas.show() + f.canvas.mpl_connect('button_press_event',mouse_input_event) + def _quit(): + Root.destroy() # this is necessary on Windows to pprevent + button = tk.Button(master=Root, text='Quit', command=_quit) + button.pack(side=tk.BOTTOM) + button = tk.Button(master=Root, text='Done', command=index_return) + button.pack(side=tk.BOTTOM) diff --git a/SVM/gui_backup.py b/SVM/gui_backup.py new file mode 100644 index 0000000..15912a9 --- /dev/null +++ b/SVM/gui_backup.py @@ -0,0 +1,313 @@ +import Tkinter as tk +from Tkinter import * +from tkMessageBox import * +import ttk +import tkFileDialog +from PIL import Image +import tifwork +import sys +import matplotlib +matplotlib.use('TkAgg') +from Tkinter import * +from tkFileDialog import askopenfilename +from numpy import arange, sin, pi +from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg +# implement the default mpl key bindings +from matplotlib.backend_bases import key_press_handler +import matplotlib.pyplot as plt +import matplotlib.image as mpimg +from matplotlib.figure import Figure +from pylab import * +import cv,cv2 +import scipy.misc + +val=[] +def exit(): + root.destroy() + +def viewerwin(): + Root = tk.Tk() + Root.wm_title("Rectifiction") + + Root.geometry("1080x720") + + + frame8=tk.Frame(Root) + frame9=tk.Frame(frame8) + frame10=tk.Frame(frame8) + button6 = tk.Button(frame9, width=5, height=2, text='Open',command=rgbselect2) + button6.pack() + + button7 = tk.Button(frame10, width=5, height=2, text='Proceed',command=openref) + button7.pack() + + + frame9.pack(side=tk.LEFT) + frame10.pack(side=tk.LEFT) + frame8.pack() + + + + f = Figure(figsize=(5,4), dpi=100) + a = f.add_subplot(111) + filename="liss3.tif" + + img=mpimg.imread(filename) + #grayScaleImage = cv2.cvtColor(img,cv.CV_BGR2GRAY) + #print grayScaleImage + + a.axis('off') + a.imshow(img) + + overlayImage = np.ones_like(img) + overlayImage +=254 + + + over = np.copy(overlayImage) + + print overlayImage + + opacity = 1 + + + + +# a tk.DrawingArea + canvas = FigureCanvasTkAgg(f, master=Root) + canvas.show() + + canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1) + + toolbar = NavigationToolbar2TkAgg( canvas, Root ) + toolbar.update() + canvas._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=1) + + + + global polygon + polygon = [] + closeFlag = False + + def on_key_event(event): + print('you pressed %s'%event.key) + key_press_handler(event, canvas, toolbar) + + + + def mouse_input_event(event): + global polygon + #print 'Event is ', event + print 'input pixel loc is ',event.xdata,' ', event.ydata + polygon.append([np.int(event.xdata),np.int(event.ydata)]) + a.plot(event.xdata,event.ydata,'b.') + + + + poly = plt.Polygon(polygon,closed = event.dblclick, fill = None, edgecolor ='b') + f.gca().add_patch(poly) + + if (event.dblclick == True): + polygon.pop() + polygon = [polygon] + print polygon + + cv2.drawContours(overlayImage,np.array(polygon),0,255) + maskImage = np.zeros_like(img) + cv2.drawContours(maskImage,np.array(polygon),0,255,-1) + extractedImage = np.bitwise_and(over,maskImage) + print extractedImage.shape + + rows,cols,bands = extractedImage.shape + + #print extractedImage + + index = extractedImage > 0 + + #extract = extractedImage.reshape((rows*cols),bands) + + print index[:,0] + scipy.misc.imsave("poly1.jpg",extractedImage) + + + + polygon = [] + + + + canvas.show() + + + + + f.canvas.mpl_connect('button_press_event',mouse_input_event) + f.canvas.mpl_connect('key_press_event', on_key_event) + + + def _quit(): + Root.quit() # stops mainloop + Root.destroy() # this is necessary on Windows to pprevent + # Fatal Python Error: PyEval_RestoreThread: NULL tstate + + button = tk.Button(master=Root, text='Quit', command=_quit) + button.pack(side=tk.BOTTOM) + + + +def rgbselect2(): + + + fileName=tkFileDialog.askopenfilename(title='select image to be rectified') + if(fileName == ''): + pass + else: + print(fileName) + im=(tifwork.openTIF(fileName)) + + +def openref(): + + selection=" " + fileName=tkFileDialog.askopenfilename(title='select reference image') + if(fileName == ''): + pass + else: + print(fileName) + im=(tifwork.openTIF(fileName)) + def sel(): + selection =str(var.get()) + print selection + + def printEntry(): + print selection + + a=tk.Tk() + a.title('Choose Polynomial order') + a.geometry('500x500') + var = IntVar() + R1 = Radiobutton(a, text="Order 0", variable=var, value=0,command=sel) + R1.pack( anchor = W ) + + R2 = Radiobutton(a, text="Order 1", variable=var, value=1,command=sel) + R2.pack( anchor = W ) + + R3 = Radiobutton(a, text="Order 2", variable=var, value=2,command=sel) + R3.pack( anchor = W) + + label = Label(a) + label.pack() + + + L1 = Label(a, text="other") + L1.pack( side = LEFT) + E1 = Entry(a, bd =5, command=printEntry) + + E1.pack(side = RIGHT) + selection=E1.get() + a.mainloop() + + + image=Image.open(im) + image1=ImageTk.PhotoImage(image) + imagesprite=c.create_image(500,500,image=image1) + return im + + + + + + +def rgbselect(): + + fileName=tkFileDialog.askopenfilename() + if(fileName == ''): + pass + else: + print(fileName) + dataset=(tifwork.openTIF(fileName)) + + w=tk.Tk() + + def bandPrint(): + if(not(opt1.get() and opt2.get() and opt3.get())): + showerror("Error", "All bands not selected") + elif(opt1.get()==opt2.get() or opt1.get()==opt3.get() or opt2.get()==opt3.get()): + showerror("Error", "Two same bands selected") + else: + bandArr = tifwork.getBand(dataset,bands,bandArray) + tifwork.selectBand(bandArr,rows,cols,opt1.get(),opt2.get(),opt3.get()) + + frame4 = tk.Frame(w) +# frame4.grid() + frame2=tk.Frame(frame4) +# frame2.grid() + frame3=tk.Frame(frame4) +# frame3.grid() + frame5 = tk.Frame(w) +# frame5.grid() + w.title("Band Selection") + (cols,rows,bands,bandArray) = tifwork.detailsTIF(dataset) + + + optionList=[] + for k in range(1, bands+1): + optionList.append(k) + + x1=tk.Label(frame2, text="Red") + x1.pack(side=tk.TOP, pady = 5 , padx = 5 ) + opt1= ttk.Combobox(frame3,values=optionList, width=5) + opt1.pack(side = tk.TOP , pady = 5,padx = 5 ) + + x2=tk.Label(frame2, text="Blue") + x2.pack(side = tk.TOP , pady = 5 , padx = 5 ) + opt2= ttk.Combobox(frame3 , values=optionList, width=5) + opt2.pack(side = tk.TOP , pady = 5 , padx = 5 ) + + x3=tk.Label(frame2, text="Green") + x3.pack(side = tk.TOP , pady = 5 , padx = 5 ) + opt3= ttk.Combobox(frame3, values=optionList, width=5) + opt3.pack(side = tk.TOP , pady = 5 , padx = 5 ) + + frame2.pack(side=tk.LEFT, pady = 5 , padx = 5 ) + frame3.pack(side=tk.LEFT, pady = 5 , padx = 5 ) + frame4.pack(side= tk.TOP, pady = 5 , padx = 5 ) + + button = tk.Button(frame5, width=10, text="Show", command=bandPrint) + button.pack(side = tk.TOP , pady = 5 , padx = 5 ) + frame5.pack(side=tk.TOP , pady = 5 , padx = 5 ) + +#opens the root window +root=tk.Tk() + +root.title("Image Processing") + +frame1 = tk.Frame(root, width=800) + +#to display the frame +frame1.pack() + +#keeps only the frame +root.overrideredirect(0) +root.resizable(0,0) + +photo3 = tk.PhotoImage(file="2.gif") +button3 = tk.Button(frame1, width=100, height=100, image=photo3) +button3.pack(side=tk.LEFT, padx=2, pady=2) +button3.image = photo3 + + +photo2 = tk.PhotoImage(file="1.gif") +button2 = tk.Button(frame1, width=100, height=100, image=photo2, command=rgbselect) +button2.pack(side=tk.LEFT, padx=2, pady=2) +button2.image = photo2 + +button5 = tk.Button(frame1, width=20, height=6, text='Geometric correction',justify=tk.LEFT,command=viewerwin) +button5.pack(side=tk.LEFT, padx=2, pady=2) + + +photo1 = tk.PhotoImage(file="3.gif") +button1 = tk.Button(frame1, width=100, height=100, image=photo1, command=exit) +button1.pack(side=tk.LEFT, padx=2, pady=2) +button1.image = photo1 + +root.mainloop() + diff --git a/SVM/menu_super.py b/SVM/menu_super.py new file mode 100644 index 0000000..423376c --- /dev/null +++ b/SVM/menu_super.py @@ -0,0 +1,304 @@ +from Tkinter import * +import tkMessageBox +import tkFileDialog +import math +import numpy +import tkColorChooser +import sys +import tifwork +import numpy as np +import PIL.Image as Image +import matplotlib +matplotlib.use('TkAgg') +from numpy import arange, sin, pi +from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg +# implement the default mpl key bindings +from matplotlib.backend_bases import key_press_handler +import matplotlib.pyplot as plt +import matplotlib.image as mpimg +from matplotlib.figure import Figure +import cv,cv2 +import scipy.misc +import svms +import matplotlib.cm as cm +global bandArray +global bands +global target +global data +global count_target +count_target = 0 +global prev +prev = 0 + +data = None +def getData(fileName, num): + #get dataset + global bandArray + global bands + global target + global data + dataset = tifwork.openTIF(fileName) + + #get details of dataset + (cols,rows,bands,bandArray) = tifwork.detailsTIF(dataset) + + #get all bands + bandArray = tifwork.getBand(dataset,bands,bandArray) + + #input a band + print rows, cols + workData = bandArray[:,:,num-1] + if (data == None): + data = np.array([]).reshape(0,bands) + target = np.array([]) + #show original image and plot it + imdata = Image.fromarray(workData) + imdata = imdata.convert('L') + imdata.save('original.jpg') + #plot(workData,'Original') + filename = 'original.jpg' + return filename + +global index +index = [] +val=[] +def exit(): + root.destroy() + + + +def viewerwin(fileName): + global bandArray + global index + + def index_return(): + global data + global target + global count_target + global prev + if (count_target == 0): + target = np.append(target, np.zeros(data.shape[0])) + prev = data.shape[0] + else: + next = data.shape[0] - prev + target = np.append(target, (np.ones(next)*count_target)) + prev = data.shape[0] + count_target += 1 + print 'index_return data ' ,data.shape + print 'index_return target' ,target.shape + _quit() + Root = Tk() + Root.wm_title("Training Data") + Root.geometry("800x600") + frame8=Frame(Root) + frame8.pack() + f = Figure(figsize=(5,4), dpi=100) + a = f.add_subplot(111) + filename= getData(fileName, 1) + img=mpimg.imread(filename) + print img.shape + #grayScaleImage = cv2.cvtColor(img,cv.CV_BGR2GRAY) + #print grayScaleImage + a.axis('off') + a.imshow(img,cmap = cm.Greys_r) + overlayImage = np.ones_like(img) + overlayImage +=254 + over = np.copy(overlayImage) + #print overlayImage + opacity = 1 + # a tk.DrawingArea + canvas = FigureCanvasTkAgg(f, master=Root) + canvas.show() + canvas.get_tk_widget().pack(side=TOP, fill=BOTH, expand=1) + toolbar = NavigationToolbar2TkAgg( canvas, Root ) + toolbar.update() + canvas._tkcanvas.pack(side=TOP, fill=BOTH, expand=1) + global polygon + polygon = [] + closeFlag = False + def mouse_input_event(event): + global polygon + global index + global bandArray + global data + #print 'Event is ', event + print 'input pixel loc is ',event.xdata,' ', event.ydata + polygon.append([np.int(event.xdata),np.int(event.ydata)]) + a.plot(event.xdata,event.ydata,'r.') + poly = plt.Polygon(polygon,closed = event.dblclick, fill = None, edgecolor ='r') + f.gca().add_patch(poly) + if (event.dblclick == True): + poly = plt.Polygon(polygon,closed = event.dblclick, fill = None, edgecolor ='r') + f.gca().add_patch(poly) + canvas.show() + polygon.pop() + polygon = [polygon] + print polygon + cv2.drawContours(overlayImage,np.array(polygon),0,255) + maskImage = np.zeros_like(img) + cv2.drawContours(maskImage,np.array(polygon),0,255,-1) + extractedImage = np.bitwise_and(over,maskImage) + + rows,cols = extractedImage.shape + #print extractedImage + index = extractedImage > 0 + + #print workData[index] + extract = bandArray.reshape((rows*cols),bands) + index = index.reshape((rows*cols)) + print extract + print index + data = np.vstack([data,extract[index]]) + print 'data shape' , data.shape + scipy.misc.imsave("poly1.jpg",extractedImage) + polygon = [] + canvas.show() + f.canvas.mpl_connect('button_press_event',mouse_input_event) + def _quit(): + Root.destroy() # this is necessary on Windows to pprevent + + button = Button(master=Root, text='Done', command=index_return) + button.pack(side=BOTTOM) + + +filename='' +#iteration=0 +index='' + +def supervi(typ): + global filename + #global iteration + global box1 + global root + root=Tk() + root.geometry('350x350') + root.title('Supervised Classification') + count=0 + + global i + i=0 + + def end(): + global root + root.destroy() + + def showfilename(filen): + tkMessageBox.showinfo('File Chosen',filen) + + def help_tab(): + tkMessageBox.showinfo("Help","You are too dumb") + + def browse(): + global filename + filename=tkFileDialog.askopenfilename(filetypes=[("TIF File","*.tif")]) + showfilename(filename) + print filename + + def changecolor(): + if ( filename == ''): + browse() + viewerwin(filename) + + + def endfield(): + global add + add.destroy() + stopaddition.destroy() + global add2 + add2=Button(framebutton,text='Add More',command=addfield ) + add2.pack() + + + def createfield(name,framename): + + name=Entry(framename,width=5) + name.pack() + + def addfield(): + global i + global l2 + global box1 + i=i+1 + + def changecolor2(): + if ( filename == ''): + browse() + viewerwin(filename) + outerframe=Frame(frame2) + l1=Label(outerframe,text=str(i+1),width=10) + l1.pack(side=LEFT) + + l2=Entry(outerframe,width=5) + l2.pack(side=LEFT) + l3=Button(outerframe,text='Area',command=changecolor2,width=10) + l3.pack(side=LEFT) + outerframe.pack(side=TOP) + + + def supervised(): + global filename + global target + global data + global count_target + print 'data' , data.shape + print 'target' , target.shape + svms.svmwork(filename,data,target,typ) + + # create a toplevel menu + menubar = Menu(root) + filemenu2=Menu(menubar,tearoff='0') + + filemenu3=Menu(menubar,tearoff='0') + filemenu3.add_command(label='Open',command=browse) + filemenu3.add_command(label='Close',command=end) + menubar.add_cascade(label='Import File',menu=filemenu3) + + + # create a pulldown menu, and add it to the menu bar + + menubar.add_cascade(label="Help", menu=filemenu2) + + filemenu2.add_command(label="About Software", command=help_tab) + + root.config(menu=menubar) + + #display buttons + showimg=Button(root,text='Display Image',command= supervised) + showimg.pack() + + #creating labels + frame1=Frame(root) + lu=Label(frame1,text='Cluster No.',width=10) + lu.pack(side=LEFT) + lu1=Label(frame1,text='Name',width=10) + lu1.pack(side=LEFT) + + lu2=Label(frame1,text='Cluster Area',width=10) + lu2.pack(side=LEFT) + + frame1.pack(side=TOP) + + global frame2 + frame2=Frame(root) + #print text + + outerframe=Frame(frame2) + l1=Label(outerframe,text=str(i+1),width=10) + l1.pack(side=LEFT) + + l2=Entry(outerframe,width=5) + l2.pack(side=LEFT) + l3=Button(outerframe,text='Area',command=changecolor,width=10) + l3.pack(side=LEFT) + outerframe.pack(side=TOP) + + frame2.pack(side=TOP) + #submit value + framebutton=Frame(root,pady=30) + global add + add=Button(framebutton,text='Add',command=addfield) + add.pack(side=LEFT) + framebutton.pack(side=TOP) + root.mainloop() + +#supervi('linear') diff --git a/SVM/svm.py b/SVM/svm.py new file mode 100644 index 0000000..f0611ca --- /dev/null +++ b/SVM/svm.py @@ -0,0 +1,81 @@ +from PIL import Image +import scipy.misc +import tifwork +import numpy as np +from sklearn import svm +import sys +sys.path.append('../GUI/') +import imageGUI + +def svmwork(fileName,data,target,typ): + print 'SVM' + dataset = tifwork.openTIF(fileName) + + (cols,rows,bands,bandArr) = tifwork.detailsTIF(dataset) + + bandArr = tifwork.getBand(dataset,bands,bandArr) + + + imageArray = np.array(bandArr,dtype =float) + + print imageArray.shape + + array = imageArray.copy() + + array = array.reshape((cols*rows),bands) + + #print array.shape + + + # training data extract + + # classifying training data + + + + #print target.shape + #print data.shape + #print array.shape + + # SVM + if (typ == 'poly'): + clf = svm.SVC(kernel=typ,degree=3) + else: + clf = svm.SVC(kernel=typ) + + clf.fit(data, target) + + isoarr = clf.predict(array) + + isoarr = np.array(isoarr,dtype =int) + #print isoarr + + #print isoarr.max() + + + #print z.shape + #print z + + + colorArray=np.array([[0,0,100],[100,0,0],[0,100,0],[100,100,0],[75,75,75],[0,100,100],[100,0,100],[50,25,25],[25,50,25],[25,25,50]]) + clusteredArray = np.zeros((rows*cols,3)) + #print clusteredArray.shape + clusters = isoarr.max() + + #print clusters + for i in xrange(clusters+1): + indices = np.where(isoarr == i)[0] + print i ,indices.size + if indices.size: + clusteredArray[indices] = colorArray[i] + + + print clusteredArray + clusteredArray = clusteredArray.reshape(rows,cols,3) + + #print clusteredArray + + scipy.misc.imsave('svm'+typ+'.jpg',clusteredArray) + imageGUI.imdisplay('svm'+typ+'.jpg','SVM-'+typ+'-Image') + print 'SVM Done' + diff --git a/SVM/svms.py b/SVM/svms.py new file mode 100644 index 0000000..f0611ca --- /dev/null +++ b/SVM/svms.py @@ -0,0 +1,81 @@ +from PIL import Image +import scipy.misc +import tifwork +import numpy as np +from sklearn import svm +import sys +sys.path.append('../GUI/') +import imageGUI + +def svmwork(fileName,data,target,typ): + print 'SVM' + dataset = tifwork.openTIF(fileName) + + (cols,rows,bands,bandArr) = tifwork.detailsTIF(dataset) + + bandArr = tifwork.getBand(dataset,bands,bandArr) + + + imageArray = np.array(bandArr,dtype =float) + + print imageArray.shape + + array = imageArray.copy() + + array = array.reshape((cols*rows),bands) + + #print array.shape + + + # training data extract + + # classifying training data + + + + #print target.shape + #print data.shape + #print array.shape + + # SVM + if (typ == 'poly'): + clf = svm.SVC(kernel=typ,degree=3) + else: + clf = svm.SVC(kernel=typ) + + clf.fit(data, target) + + isoarr = clf.predict(array) + + isoarr = np.array(isoarr,dtype =int) + #print isoarr + + #print isoarr.max() + + + #print z.shape + #print z + + + colorArray=np.array([[0,0,100],[100,0,0],[0,100,0],[100,100,0],[75,75,75],[0,100,100],[100,0,100],[50,25,25],[25,50,25],[25,25,50]]) + clusteredArray = np.zeros((rows*cols,3)) + #print clusteredArray.shape + clusters = isoarr.max() + + #print clusters + for i in xrange(clusters+1): + indices = np.where(isoarr == i)[0] + print i ,indices.size + if indices.size: + clusteredArray[indices] = colorArray[i] + + + print clusteredArray + clusteredArray = clusteredArray.reshape(rows,cols,3) + + #print clusteredArray + + scipy.misc.imsave('svm'+typ+'.jpg',clusteredArray) + imageGUI.imdisplay('svm'+typ+'.jpg','SVM-'+typ+'-Image') + print 'SVM Done' + diff --git a/SVM/tifwork.py b/SVM/tifwork.py new file mode 100644 index 0000000..d414845 --- /dev/null +++ b/SVM/tifwork.py @@ -0,0 +1,45 @@ +from osgeo import gdal +import PIL.Image as Image +import numpy as np + + + +gdal.AllRegister() + +def openTIF(filename): + dataset =gdal.Open(filename,gdal.GA_ReadOnly) + if dataset is None: + print 'Could Not Open' + filename + #Alternatively Raise an Event here + sys.exit(1) + + return dataset + +def detailsTIF(dataset): + cols = dataset.RasterXSize + rows = dataset.RasterYSize + bands = dataset.RasterCount + bandArray = np.zeros((rows,cols,bands),dtype = float) + return (cols, rows,bands,bandArray) + +def getBand(dataset,bands,bandArr): + for x in range(1,bands+1): + band=dataset.GetRasterBand(x) + array=band.ReadAsArray() + bandArr[:,:,x-1] = array + return bandArr + + +def selectBand(bandArray,rows,cols,ch1,ch2,ch3): + + ch1 = int(ch1) + ch2 = int(ch2) + ch3 = int(ch3) + combi= np.zeros((rows,cols,3),'uint8') + combi[:,:,0]=bandArray[:,:,ch1-1] + combi[:,:,1]=bandArray[:,:,ch2-1] + combi[:,:,2]=bandArray[:,:,ch3-1] + combImage= Image.fromarray(combi) + combImage.save('guiTry'+'.jpeg') + combImage.show() + diff --git a/Spectral.py b/Spectral.py new file mode 100644 index 0000000..f1dee3b --- /dev/null +++ b/Spectral.py @@ -0,0 +1,119 @@ +import math +from osgeo import gdal +import PIL.Image as Image +import numpy as np +import math +import sys +import scipy.misc +sys.path.append('./GUI/') +import imageGUI + +#linearly enhances an array from its minimum to maximum value. +def linearx(array): + array1=np.array(array,'uint16') + min=np.amin(array1) + max=np.amax(array1) + array1=((array1-min)*255)/((max-min)) + return array1 + +#creates and displays the NDVI image for the two bands entered +def goNDVI(array1,array2): + print 'NDVI' + array1=np.array(array1,'float32') + array2=np.array(array2,'float32') + num=array1-array2 + den=array1+array2 + index = (den>0) + index1 = (den==0) + num1=num[index] + den1=den[index] + output=num1/den1 + final=array1 + final[index]=output + final[index1]=0 + #print index + final=linearx(final) + #print final.shape + + scipy.misc.imsave('temp/Spectral/ndvi.png',final) + imageGUI.imdisplay('temp/Spectral/ndvi.png','NDVI-Image',1) + ''' + im=Image.fromarray(final) + im = im.convert('L') + im.save('ndvi'+str(count1)+'.png') + #count1=count1+1 + #return final + ''' + +#creates and displays the TVI image for the two bands entered +def goTVI(array,arrayz): + print 'TVI' + array1=np.array(array,'float32') + array2=np.array(arrayz,'float32') + num=array1-array2 + den=array1+array2 + index=(den >0) + index1=(den ==0) + num1=num[index] + den1=den[index] + output=(((num1/den1) + 0.5)**0.5)*100 + final=array1 + final[index]=output + final[index1]=0 + final=linearx(final) + scipy.misc.imsave('temp/Spectral/tvi.png',final) + imageGUI.imdisplay('temp/Spectral/tvi.png','TVI-Image',1) + ''' + im=Image.fromarray(final) + im = im.convert('L') + im.save('tvi'+str(count1)+'.png') + #count1=count1+1 + #return final + ''' + +def goRVI(array,arrayz): + print 'RVI' + array1=np.array(array,'float32') + array2=np.array(arrayz,'float32') + num=array1 + den=array2 + index=den >0 + index1=den ==0 + num1=num[index] + den1=den[index] + output=num1/den1 + final=array1 + final[index]=output + final[index1]=0 + scipy.misc.imsave('temp/Spectral/ri.png',final) + imageGUI.imdisplay('temp/Spectral/ri.png','RI-Image',1) + ''' + final=linearx(final) + im=Image.fromarray(final) + im = im.convert('L') + im.save('rvi'+str(count1)+'.png') + #count1=count1+1 + #return final + ''' + +#gets details about the number of rows ,columns ,bands and the array of bands for the file opened +#calls the function accordingly +def spec(fileName,num,no1,no2): + + gdal.AllRegister() + dataset =gdal.Open(fileName,gdal.GA_ReadOnly) + if dataset is None: + print 'Could Not Open' + fileName + #Alternatively Raise an Event here + sys.exit(1) + cols = dataset.RasterXSize + rows = dataset.RasterYSize + bands = dataset.RasterCount + dic = {1:goNDVI , 2 : goTVI , 3:goRVI} + band1=dataset.GetRasterBand(no1) + band2=dataset.GetRasterBand(no2) + array1=band1.ReadAsArray() + array2=band2.ReadAsArray() + dic[num](array1,array2) + + diff --git a/Untitled.gif b/Untitled.gif new file mode 100644 index 0000000..fc63860 Binary files /dev/null and b/Untitled.gif differ diff --git a/back_imageGUI.py b/back_imageGUI.py new file mode 100644 index 0000000..7450526 --- /dev/null +++ b/back_imageGUI.py @@ -0,0 +1,58 @@ + +import Tkinter as tk +from Tkinter import * +from tkMessageBox import * +import ttk +import tkFileDialog +from PIL import Image +import tifwork +import sys +import matplotlib +matplotlib.use('TkAgg') + +from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg +from matplotlib.backend_bases import key_press_handler +import matplotlib.pyplot as plt +import matplotlib.image as mpimg +from matplotlib.figure import Figure + +#from tkFileDialog import askopenfilename + +# implement the default mpl key bindings +#import Image, ImageTk + + +def imdisplay(filename,title): + openImFile(filename,title) + +def openImFile(filename,title): + Root1 = tk.Tk() + Root1.wm_title(title) + Root1.geometry("600x600") + fx = Figure(figsize=(5,4), dpi=100) + ax = fx.add_subplot(111) + img=mpimg.imread(filename) + plt.gray() + ax.imshow(img) + + canvasx = FigureCanvasTkAgg(fx, master=Root1) + canvasx.show() + canvasx.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1) + toolbar = NavigationToolbar2TkAgg( canvasx, Root1 ) + toolbar.update() + canvasx._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=1) + + def on_key_event(event): + print('you pressed %s'%event.key) + key_press_handler(event, canvasx, toolbar) + + def _quitx(): + Root1.quit() # stops mainloop + Root1.destroy() + button1 = tk.Button(master=Root1, text='Quit', command=_quitx) + button1.pack(side=tk.BOTTOM) + + fx.canvas.mpl_connect('key_press_event', on_key_event) + Root1.mainloop() + +# a tk.DrawingArea diff --git a/classification.gif b/classification.gif new file mode 100644 index 0000000..aa24814 Binary files /dev/null and b/classification.gif differ diff --git a/close.gif b/close.gif new file mode 100644 index 0000000..fbae985 Binary files /dev/null and b/close.gif differ diff --git a/contrast.py b/contrast.py new file mode 100644 index 0000000..c13f63f --- /dev/null +++ b/contrast.py @@ -0,0 +1,127 @@ +''' +The software aims to be an open-source package with basic, and advanced Image Processing features. +Copyright (C) 2014 Indian Institute of Remote Sensing, Dehradun + +The original authors of this program (in alphabetical order) are: + +--------------------------------------------------------------------------------------------------------------------------------------- +Sno. NAME Email( AT gmail DOT com) Role(s) +--------------------------------------------------------------------------------------------------------------------------------------- +1. Pragun Vinayak pragunvinayak GUI, Contrast, Histogram +---------------------------------------------------------------------------------------------------------------------------------------- + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +''' +from osgeo import gdal +import PIL.Image as Image +import numpy as np +import math +import sys +import math +sys.path.append('./GUI/') +import imageGUI +def linearx(array): + array1=np.array(array,'uint16') + min=np.amin(array1) + max=np.amax(array1) + array1=((array1-min)*255)/(max-min) + return array1 + + +def log(array): + array1=np.array(array,'uint64') + array1=(array1+1) + array1=np.log(array1) + lmin=np.amin(array1) + lmax=np.amax(array1) + array1=((array1-lmin)*255)/(lmax-lmin) + return array1 + +def exp(array): + array1=np.array(array,'uint64') + array1=np.exp(array1) + lmin=np.amin(array1) + lmax=np.amax(array1) + array1=((array1-lmin)*255)/(lmax-lmin) + return array1 + + +def linearp(array1,slope,c): + array1=np.array(array1,'uint64') + array1=(slope*array1)+c + return array1 + +def piecewise(array): + (x1 , x2 , x3 ,x4) = (1,2,3,4) + array_pw=np.array(array,'uint64') + index=array_pw >=x1 + index1=array_pw <= x2 + c_index=index & index1 + newarray=array_pw[c_index] + slope=(float)(y2-y1)/(x2-x1) + c=(float)(x2*y1-x1*y2)/(x2-x1) + array_op=linearp(newarray,slope,c) + array_pw[c_index]=array_op + return array_pw + +def cont(fileName,num): + + + gdal.AllRegister() + + + + dataset =gdal.Open(fileName,gdal.GA_ReadOnly) + + if dataset is None: + print 'Could Not Open' + fileName + #Alternatively Raise an Event here + sys.exit(1) + + cols = dataset.RasterXSize + rows = dataset.RasterYSize + bands = dataset.RasterCount + rgbArray = np.zeros((rows,cols,bands),'uint8') + print cols + print rows + print bands + dic = {1:linearx , 2 : log , 3:exp , 4:piecewise} + dic1 = {1:'linear' , 2 : 'log' , 3:'exp' , 4:'piecewise'} + for x in range(1,bands+1): + band=dataset.GetRasterBand(x) + array=band.ReadAsArray() + rgbArray[:,:,x-1] = dic[num](array) + + combi= np.zeros((rows,cols,3),'uint8') + count=1 + + for i in range(0,bands): + for j in range(0,bands): + for k in range(0,bands): + if( (not i == j) and (not j ==k) and (not k == i) ): + combi[:,:,0]=rgbArray[:,:,i] + combi[:,:,1]=rgbArray[:,:,j] + combi[:,:,2]=rgbArray[:,:,k] + combImage= Image.fromarray(combi) + combImage.save('temp/Contrast/'+dic1[num]+str(count)+'.jpeg') + imageGUI.imdisplay('temp/Contrast/'+dic1[num]+str(count)+'.jpeg','Contrast'+str(count),1) + count=count+1 + + +#img = Image.fromarray(rgbArray) +#img.save('jpegTry.jpeg') +#img.show() + +#I=plt.imread('liss4.tif') diff --git a/data.py b/data.py new file mode 100644 index 0000000..71f56c3 --- /dev/null +++ b/data.py @@ -0,0 +1,55 @@ +''' +The software aims to be an open-source package with basic, and advanced Image Processing features. +Copyright (C) 2014 Indian Institute of Remote Sensing, Dehradun + +The original authors of this program (in alphabetical order) are: + +--------------------------------------------------------------------------------------------------------------------------------------- +Sno. NAME Email( AT gmail DOT com) Role(s) +--------------------------------------------------------------------------------------------------------------------------------------- +1. Abhishek Mohta mohta.abhishek GUI, Spectral +---------------------------------------------------------------------------------------------------------------------------------------- + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +''' +import numpy as np +from osgeo import gdal +import tifwork + +dataset=tifwork.openTIF(filename) +cols, rows,bands,bandArray=tifwork.detailsTIF(dataset) +bandArray=tifwork.getBand(dataset,bands,bandArray) + +mean=np.mean(bandArray, axis=0) +median=np.median(bandArray, axis=0) +stddev=np.std(bandArray,axis=0) +max=np.max(bandArray,axis=0) +min=np.min(bandArray,axis=0) + +f=open("abc.txt",'w') +f.write("Mean = "+str(mean)+"\n") +f.write("Median = "+str(median)+"\n") +f.write("Standard Deviation = "+str(stddev)+"\n") +f.write("Max = "+str(max)+"\n") +f.write("Min = "+str(min)+"\n") +f.close() + +#f=open("abc.txt",'r') +lines=[line.strip() for line in open('abc.txt')] +print lines + +f.close() + + diff --git a/display.gif b/display.gif new file mode 100644 index 0000000..459f296 Binary files /dev/null and b/display.gif differ diff --git a/enhancement.gif b/enhancement.gif new file mode 100644 index 0000000..b483482 Binary files /dev/null and b/enhancement.gif differ diff --git a/fuzzy.py b/fuzzy.py new file mode 100644 index 0000000..203c700 --- /dev/null +++ b/fuzzy.py @@ -0,0 +1,99 @@ +''' +The software aims to be an open-source package with basic, and advanced Image Processing features. +Copyright (C) 2014 Indian Institute of Remote Sensing, Dehradun + +The original authors of this program (in alphabetical order) are: + +--------------------------------------------------------------------------------------------------------------------------------------- +Sno. NAME Email( AT gmail DOT com) Role(s) +--------------------------------------------------------------------------------------------------------------------------------------- +1. Siddhant Shrivastava sidhu94 Classification, Spatial, Polygons +---------------------------------------------------------------------------------------------------------------------------------------- + + + Compatible with Python 2.7 ( NOT COMPATIBLE with Python(>3)) + + Dependencies: GDAL, NumPy, SciPy, OpenCV, Spectral Python, Tkinter, scikit-learn, scikit-fuzz + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +''' + +import numpy as np +import matplotlib.pyplot as plt +import tifwork as tw +import scipy.misc +from PIL import Image +import FastFCMeans as ffc +import FastCMeans as fc + +def fuzz(color,filename): + #filename = 'liss4.tif' + dataset = tw.openTIF(filename) + cols, rows,bands,bandArray = tw.detailsTIF(dataset) + bandArray = tw.getBand(dataset,bands,bandArray) + + intBandArray = np.array(bandArray,dtype = float) + + c = len(color) + + #print bands + #print intBandArray.shape + + scipy.misc.imsave('hello.jpg',intBandArray) + + #(L, C, U, LUT, H) = FastFCMeans(intBandArray,c,q) + (L,C,U,LUT,H) = ffc.FastFCMeans(intBandArray[:,:,0],c,2) + + im = intBandArray[:,:,0] + + #Visualize the fuzzy membership functions + + plt.figure('Fig 1') + #plt.subplot(2,1,1) + + #Visualize the segmentation + + Lrgb = np.zeros((np.size(L),3),'uint8') + + Lflat = L.ravel() + + Lflat = Lflat[:,np.newaxis] + + + + #correct things from here + + #color = [(0,255,0),(0,0,255),(255,0,0),(0,0,0),(255,255,255),(34,65,0),(0,45,87),(100,100,100),(50,50,50),(12,54,77),(43,65,99)] + + for i in range(0,c): + (temp,b) =np.nonzero(Lflat == i) + Lrgb[temp] = color[i] + + + + #print im.shape + + Lrgb = np.reshape(Lrgb,(im.shape)+(3,)) + + imArray = np.copy(Lrgb.astype('uint8')) + print imArray.shape + scipy.misc.imsave('1.jpg',imArray) + plt.imshow(imArray) + plt.show() + + #If necessary, unpack the membership functions to produce membership maps + + + diff --git a/fuzzy/FastCMeans.py b/fuzzy/FastCMeans.py new file mode 100644 index 0000000..fe5d7d3 --- /dev/null +++ b/fuzzy/FastCMeans.py @@ -0,0 +1,90 @@ +# Segment N-dimensional grayscale image into c classes using a memory +# efficient implementation of the c-means (aka k-means) clustering +# algorithm. The computational efficiency is achieved by using the +# histogram of the image intensities during the clustering process instead +# of the raw image data. +# +# INPUT ARGUMENTS: +# - im : N-dimensional grayscale image in integer format. +# - c : positive interger greater than 1 specifying the number of +# clusters. c=2 is the default setting. Alternatively, c can be +# specified as a k-by-1 array of initial cluster (aka prototype) +# centroids. +# +# OUTPUT : +# - L : label image of the same size as the input image. For example, +# L==i represents the region associated with prototype C(i), +# where i=[1,k] (k = number of clusters). +# - C : 1-by-k array of cluster centroids. +# - LUT : L-by-1 array that specifies the intensity-class relations, +# where L is the dynamic intensity range of the input image. +# Specifically, LUT(1) corresponds to class assigned to +# min(im(:)) and LUT(L) corresponds to the class assigned to +# max(im(:)). See 'apply_LUT' function for more info. +# + +import numpy as np +import LUT2label as label + + + +def FastCMeans(im, c): + + # Intensity range + + Imin = float(np.min(im[:])) + Imax = float(np.max(im[:])) + I = np.transpose(np.array(np.arange(Imin,Imax+1))) + + I = I[:, np.newaxis] + + # Compute intensity histogram + + H = np.histogram(im.flatten(),I.flatten()) + (H1, H2) = H + #H1 = H1.flatten() + #H2 = H2.flatten() + H1 = H1[:, np.newaxis] + #H2 = H2[:, np.newaxis] + #print 'H1 and H2 Size: ', H1.shape, H2.shape + #print H1.shape + H = np.copy(np.append(H1,[1])) + H = H[:, np.newaxis] + + + # Initialize cluster centroids + + if np.size(c) > 1: + C = c + c = np.size(c) + else: + dl = (Imax - Imin)/c + C = np.arange(Imin + dl/2, Imax+1, dl) + + # Update cluster centroids + + IH = I * H + dC = float(np.inf) + + while (dC > 1.0E-6): + + C0 = np.copy(C) + + # Distance to the centroids + D = np.abs(I - C) + + # Classify by proximity + Dmin = np.min(D,1) + LUT = np.argmin(D,1) + + for j in range(0,c): + index = LUT==j + C[j] = np.sum(IH[index]) / np.sum(H[index]) + + # Change in centroids + #print (C-C0) + dC = np.max(np.abs(C-C0)) + + L = label.LUT2label(im,LUT) + return (L,C,LUT) + diff --git a/fuzzy/FastFCMeans.py b/fuzzy/FastFCMeans.py new file mode 100644 index 0000000..3139387 --- /dev/null +++ b/fuzzy/FastFCMeans.py @@ -0,0 +1,153 @@ +# Segment N-dimensional grayscale image into c classes using a memory +# efficient implementation of the fuzzy c-means (FCM) clustering algorithm. +# The computational efficiency is achieved by using the histogram of the +# image intensities during the clustering process instead of the raw image +# data. +# +# INPUT ARGUMENTS: +# - im : N-dimensional grayscale image in integer format. +# - c : positive interger greater than 1 specifying the number of +# clusters. c=2 is the default setting. Alternatively, c can be +# specified as a k-by-1 array of initial cluster (aka prototype) +# centroids. +# - q : fuzzy weighting exponent. q must be a real number greater than +# 1.1. q=2 is the default setting. Increasing q leads to an +# increased amount of fuzzification, while reducing q leads to +# crispier class memberships. +# +# OUTPUT : +# - L : label image of the same size as the input image. For example, +# L==i represents the region associated with prototype C(i), +# where i=[1,k] (k = number of clusters). +# - C : 1-by-k array of cluster centroids. +# - U : L-by-k array of fuzzy class memberships, where k is the number +# of classes and L is the intensity range of the input image, +# such that L=numel(min(im(:)):max(im(:))). +# - LUT : L-by-1 array that specifies the defuzzified intensity-class +# relations, where L is the dynamic intensity range of the input +# image. Specifically, LUT(1) corresponds to class assigned to +# min(im(:)) and LUT(L) corresponds to the class assigned to +# max(im(:)). See 'apply_LUT' function for more info. +# - H : image histogram. If I=min(im(:)):max(im(:)) are the intensities +# present in the input image, then H(i) is the number of image +# pixels/voxels that have intensity I(i). +# + + +import numpy as np +import matplotlib.pyplot as plt +import tifwork as tw +import scipy.misc +import LUT2label as label +import FastCMeans as fc + +def FastFCMeans(im, c, q): + + #intensity range + + Imin = float(np.min(im[:])) + Imax = float(np.max(im[:])) + I = np.transpose(np.array(np.arange(Imin,Imax+1))) + + I = I[:, np.newaxis] + + #print 'I size ', I.shape + + #print Imin, Imax + + # Compute intensity histogram + + H = np.histogram(im.flatten(),I.flatten()) + + (H1, H2) = H + + #H1 = H1.flatten() + #H2 = H2.flatten() + + H1 = H1[:, np.newaxis] + H2 = H2[:, np.newaxis] + + #print 'H1 and H2 Size: ', H1.shape, H2.shape + + + + H = np.copy(np.append(H1,[1])) + H = H[:, np.newaxis] + + + + #print H.shape + + #plt.show() + #print H + + #Initialize Cluster Centroids + + if np.size(c) > 1: + C = c + c = np.size(c) + else: + + (l,C,lut) = fc.FastCMeans(im,c) + + #Update Fuzzy Memberships and cluster centroids + + #I = repmat(I,[1 c]) + I = np.tile(I,np.array([1,c])) + + #print ' I shape ', I.shape + + dC = np.inf + + eps = np.finfo(float).eps + + #print 'Epsilon is ', eps + + while (dC > 1E-6): + + C0 = np.copy(C) + #Distance to the centroids + D = np.abs(I-C) + D = D**(2/(q-1)) + eps + + #compute fuzzy memberships + + recipSum = np.sum(1/D,1) + recipSum = recipSum[:, np.newaxis] + + + U = D * recipSum + + U = 1/(U+ eps) + + #update the centroids + + UH = (U**q) * H + + s1 = np.sum(UH * I,0) + s1 = s1[:,np.newaxis] + s2 = np.sum(UH,0).astype(float) + s2 = s2[:, np.newaxis] + + s1 = np.transpose(s1) + s2 = np.transpose(s2) + C = s1 /s2 + + + C = np.sort(C) + #Change in centroids + dC = np.max(np.abs(C-C0)) + + #Defuzzify and create a label image + + Umax = np.max(U,1) + #Umax = Umax[:,np.newaxis] + #print Umax + LUT = np.argmax(U,1) + #print LUT2label + + L = label.LUT2label(im,LUT) + + return (L,C,U,LUT,H) + + diff --git a/fuzzy/LUT2label.py b/fuzzy/LUT2label.py new file mode 100644 index 0000000..01aafe2 --- /dev/null +++ b/fuzzy/LUT2label.py @@ -0,0 +1,46 @@ +import numpy as np + +def LUT2label(im,LUT): + #Create a label image using LUT obtained from a clustering operation of grayscale data + + # Intensity range + + Imin = float(np.min(im[:])) + Imax = float(np.max(im[:])) + I = np.transpose(np.array(np.arange(Imin,Imax+1))) + I = I[:, np.newaxis] + + #print I.shape + #Create a Label Image + + L = np.zeros(im.shape,int) + + #print L.shape + + for k in range(0, np.max(LUT)+1): + + + #intensity range for k-th class + i = np.nonzero(LUT==k) + + (arr ,)= i + arr = np.copy(arr[:,np.newaxis]) + #print 'arr shape is ', arr.shape + #print arr[1] + + i1 = arr[1] + + sz = np.size(arr) + #print arr[sz-1] + if sz > 1: + i2 = arr[sz-1] + else: + i2 = i1 + + #map the intensities in the range [I(i1),I(i2)] to class k] + bw = np.logical_and(im >= I[i1], im <= I[i2]) + + L[bw] = k + + + return L diff --git a/fuzzy/fuzzy.py b/fuzzy/fuzzy.py new file mode 100644 index 0000000..203c700 --- /dev/null +++ b/fuzzy/fuzzy.py @@ -0,0 +1,99 @@ +''' +The software aims to be an open-source package with basic, and advanced Image Processing features. +Copyright (C) 2014 Indian Institute of Remote Sensing, Dehradun + +The original authors of this program (in alphabetical order) are: + +--------------------------------------------------------------------------------------------------------------------------------------- +Sno. NAME Email( AT gmail DOT com) Role(s) +--------------------------------------------------------------------------------------------------------------------------------------- +1. Siddhant Shrivastava sidhu94 Classification, Spatial, Polygons +---------------------------------------------------------------------------------------------------------------------------------------- + + + Compatible with Python 2.7 ( NOT COMPATIBLE with Python(>3)) + + Dependencies: GDAL, NumPy, SciPy, OpenCV, Spectral Python, Tkinter, scikit-learn, scikit-fuzz + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +''' + +import numpy as np +import matplotlib.pyplot as plt +import tifwork as tw +import scipy.misc +from PIL import Image +import FastFCMeans as ffc +import FastCMeans as fc + +def fuzz(color,filename): + #filename = 'liss4.tif' + dataset = tw.openTIF(filename) + cols, rows,bands,bandArray = tw.detailsTIF(dataset) + bandArray = tw.getBand(dataset,bands,bandArray) + + intBandArray = np.array(bandArray,dtype = float) + + c = len(color) + + #print bands + #print intBandArray.shape + + scipy.misc.imsave('hello.jpg',intBandArray) + + #(L, C, U, LUT, H) = FastFCMeans(intBandArray,c,q) + (L,C,U,LUT,H) = ffc.FastFCMeans(intBandArray[:,:,0],c,2) + + im = intBandArray[:,:,0] + + #Visualize the fuzzy membership functions + + plt.figure('Fig 1') + #plt.subplot(2,1,1) + + #Visualize the segmentation + + Lrgb = np.zeros((np.size(L),3),'uint8') + + Lflat = L.ravel() + + Lflat = Lflat[:,np.newaxis] + + + + #correct things from here + + #color = [(0,255,0),(0,0,255),(255,0,0),(0,0,0),(255,255,255),(34,65,0),(0,45,87),(100,100,100),(50,50,50),(12,54,77),(43,65,99)] + + for i in range(0,c): + (temp,b) =np.nonzero(Lflat == i) + Lrgb[temp] = color[i] + + + + #print im.shape + + Lrgb = np.reshape(Lrgb,(im.shape)+(3,)) + + imArray = np.copy(Lrgb.astype('uint8')) + print imArray.shape + scipy.misc.imsave('1.jpg',imArray) + plt.imshow(imArray) + plt.show() + + #If necessary, unpack the membership functions to produce membership maps + + + diff --git a/fuzzy/tifwork.py b/fuzzy/tifwork.py new file mode 100644 index 0000000..d414845 --- /dev/null +++ b/fuzzy/tifwork.py @@ -0,0 +1,45 @@ +from osgeo import gdal +import PIL.Image as Image +import numpy as np + + + +gdal.AllRegister() + +def openTIF(filename): + dataset =gdal.Open(filename,gdal.GA_ReadOnly) + if dataset is None: + print 'Could Not Open' + filename + #Alternatively Raise an Event here + sys.exit(1) + + return dataset + +def detailsTIF(dataset): + cols = dataset.RasterXSize + rows = dataset.RasterYSize + bands = dataset.RasterCount + bandArray = np.zeros((rows,cols,bands),dtype = float) + return (cols, rows,bands,bandArray) + +def getBand(dataset,bands,bandArr): + for x in range(1,bands+1): + band=dataset.GetRasterBand(x) + array=band.ReadAsArray() + bandArr[:,:,x-1] = array + return bandArr + + +def selectBand(bandArray,rows,cols,ch1,ch2,ch3): + + ch1 = int(ch1) + ch2 = int(ch2) + ch3 = int(ch3) + combi= np.zeros((rows,cols,3),'uint8') + combi[:,:,0]=bandArray[:,:,ch1-1] + combi[:,:,1]=bandArray[:,:,ch2-1] + combi[:,:,2]=bandArray[:,:,ch3-1] + combImage= Image.fromarray(combi) + combImage.save('guiTry'+'.jpeg') + combImage.show() + diff --git a/getData.py b/getData.py new file mode 100644 index 0000000..e01ba56 --- /dev/null +++ b/getData.py @@ -0,0 +1,24 @@ +import PIL.Image as Image +import tifwork + +def getData(fileName, num): + #get dataset + dataset = tifwork.openTIF(fileName) + + #get details of dataset + (cols,rows,bands,bandArray) = tifwork.detailsTIF(dataset) + + #get all bands + bandArray = tifwork.getBand(dataset,bands,bandArray) + + #input a band + + workData = bandArray[:,:,num-1] + + #show original image and plot it + imdata = Image.fromarray(workData) + imdata = imdata.convert('L') + imdata.save('original.jpg') + #plot(workData,'Original') + filename = 'original.jpg' + return filename diff --git a/gui.py b/gui.py new file mode 100644 index 0000000..e61aa3d --- /dev/null +++ b/gui.py @@ -0,0 +1,120 @@ +import Tkinter as tk +from Tkinter import * +from tkMessageBox import * +import ttk +from PIL import Image +import tifwork +from tkFileDialog import askopenfilename +import sys +import matplotlib +matplotlib.use('TkAgg') +from numpy import arange, sin, pi +from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg +# implement the default mpl key bindings +from matplotlib.backend_bases import key_press_handler +import matplotlib.pyplot as plt +import matplotlib.image as mpimg +from matplotlib.figure import Figure +#from pylab import * +import cv,cv2 +import scipy.misc +import numpy as np + +def getData(fileName, num): + #get dataset + dataset = tifwork.openTIF(fileName) + + #get details of dataset + (cols,rows,bands,bandArray) = tifwork.detailsTIF(dataset) + + #get all bands + bandArray = tifwork.getBand(dataset,bands,bandArray) + + #input a band + + workData = bandArray[:,:,num-1] + + #show original image and plot it + imdata = Image.fromarray(workData) + imdata = imdata.convert('L') + imdata.save('original.jpg') + #plot(workData,'Original') + filename = 'original.jpg' + return filename + +global index +index = [] +val=[] +def exit(): + root.destroy() + +def index_return(): + global index + return index[:,0] + +def viewerwin(fileName): + global index + Root = tk.Tk() + Root.wm_title("Rectifiction") + Root.geometry("1080x720") + frame8=tk.Frame(Root) + frame8.pack() + f = Figure(figsize=(5,4), dpi=100) + a = f.add_subplot(111) + filename= 'sja.jpg' + img=mpimg.imread(filename) + #grayScaleImage = cv2.cvtColor(img,cv.CV_BGR2GRAY) + #print grayScaleImage + a.axis('off') + a.imshow(img) + overlayImage = np.ones_like(img) + overlayImage +=254 + #over = np.copy(overlayImage) + #print overlayImage + opacity = 1 + # a tk.DrawingArea + canvas = FigureCanvasTkAgg(f, master=Root) + canvas.show() + canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1) + toolbar = NavigationToolbar2TkAgg( canvas, Root ) + toolbar.update() + canvas._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=1) + global polygon + polygon = [] + closeFlag = False + def mouse_input_event(event): + global polygon + global index + #print 'Event is ', event + print 'input pixel loc is ',event.xdata,' ', event.ydata + polygon.append([np.int(event.xdata),np.int(event.ydata)]) + a.plot(event.xdata,event.ydata,'b.') + poly = plt.Polygon(polygon,closed = event.dblclick, fill = None, edgecolor ='b') + f.gca().add_patch(poly) + if (event.dblclick == True): + poly = plt.Polygon(polygon,closed = event.dblclick, fill = None, edgecolor ='b') + f.gca().add_patch(poly) + canvas.show() + polygon.pop() + polygon = [polygon] + print polygon + cv2.drawContours(overlayImage,np.array(polygon),0,255) + maskImage = np.zeros_like(img) + cv2.drawContours(maskImage,np.array(polygon),0,255,-1) + extractedImage = np.bitwise_and(over,maskImage) + #print extractedImage.shape + rows,cols,bands = extractedImage.shape + #print extractedImage + index = extractedImage > 0 + #extract = extractedImage.reshape((rows*cols),bands) + print index[:,0] + scipy.misc.imsave("poly1.jpg",extractedImage) + polygon = [] + canvas.show() + f.canvas.mpl_connect('button_press_event',mouse_input_event) + def _quit(): + Root.destroy() # this is necessary on Windows to pprevent + button = tk.Button(master=Root, text='Quit', command=_quit) + button.pack(side=tk.BOTTOM) + button = tk.Button(master=Root, text='Done', command=index_return) + button.pack(side=tk.BOTTOM) diff --git a/guiClass.py b/guiClass.py new file mode 100644 index 0000000..a9edde5 --- /dev/null +++ b/guiClass.py @@ -0,0 +1,81 @@ +''' +The software aims to be an open-source package with basic, and advanced Image Processing features. +Copyright (C) 2014 Indian Institute of Remote Sensing, Dehradun + +The original authors of this program (in alphabetical order) are: + +--------------------------------------------------------------------------------------------------------------------------------------- +Sno. NAME Email( AT gmail DOT com) Role(s) +--------------------------------------------------------------------------------------------------------------------------------------- + +1. Shalaka Somani shalaka195 GUI +---------------------------------------------------------------------------------------------------------------------------------------- + +Compatible with Python 2.7 ( NOT COMPATIBLE with Python(>3)) + +Dependencies: GDAL, NumPy, SciPy, OpenCV, Spectral Python, Tkinter, scikit-learn, scikit-fuzz + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +''' + +import Tkinter as tk +import ttk +import matrix +import tkFileDialog +from PIL import Image +import tkMessageBox +import menu_unsuper +import sys +sys.path.append('./SVM') +import menu_super as men + +def classgui(): + frame=tk.Tk() + frame.title("Image Classification") + + frame1=tk.Frame(frame) + frame2=tk.Frame(frame) + + x1=tk.Label(frame, text="Image Classification") + x1.pack(side=tk.TOP, pady = 5 , padx = 5 ) + + + x2=tk.Label(frame1, text="Supervised") + x2.pack(side=tk.TOP, pady = 5 , padx = 5 ) + + button1=tk.Button(frame1, text="SVM Linear",command = lambda:men.supervi('linear')) + button1.pack(side=tk.TOP, padx=2, pady=2) + + button1=tk.Button(frame1, text="SVM Poly" , command = lambda:men.supervi('poly')) + button1.pack(side=tk.TOP, padx=2, pady=2) + + button1=tk.Button(frame1, text="SVM RBF" , command = lambda:men.supervi('rbf')) + button1.pack(side=tk.TOP, padx=2, pady=2) + + + x3=tk.Label(frame2, text="Unsupervised") + x3.pack(side=tk.TOP, pady = 5 , padx = 5 ) + + button2=tk.Button(frame2, text="IsoData", command=lambda:menu_unsuper.unsuper(2)) + button2.pack(side=tk.TOP, padx=2, pady=2) + button3=tk.Button(frame2, text="K-Means", command=lambda:menu_unsuper.unsuper(1)) + button3.pack(side=tk.TOP, padx=2, pady=2) + button3=tk.Button(frame2, text="Fuzzy", command=lambda:menu_unsuper.unsuper(3)) + button3.pack(side=tk.TOP, padx=2, pady=2) + + + frame1.pack(side=tk.LEFT, padx=20, pady=20) + frame2.pack(side=tk.LEFT, padx=20, pady=20) + frame.mainloop() diff --git a/guiEnhance.py b/guiEnhance.py new file mode 100644 index 0000000..f212786 --- /dev/null +++ b/guiEnhance.py @@ -0,0 +1,368 @@ +''' +The software aims to be an open-source package with basic, and advanced Image Processing features. +Copyright (C) 2014 Indian Institute of Remote Sensing, Dehradun + +The original authors of this program (in alphabetical order) are: + +--------------------------------------------------------------------------------------------------------------------------------------- +Sno. NAME Email( AT gmail DOT com) Role(s) +--------------------------------------------------------------------------------------------------------------------------------------- +1. Shalaka Somani shalaka195 GUI, Spectral +---------------------------------------------------------------------------------------------------------------------------------------- + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +''' +import Tkinter as tk +import ttk +import matrix +import tkFileDialog +from PIL import Image +import tkMessageBox +#import spatial as sp +import sys +sys.path.append('./PCA') +import PCA +import contrast +import Spectral as spec +import tifwork +import spatial as spat +global box +global guiSpat4 +global guiSpat3 + +#defines the main GUI for image enhancement + +def guiEn(): + global fileName + fileName = '' + + frame=tk.Tk() + + frame1=tk.Frame(frame) + frame.title("Image Enhancement") + + def open(): + + global fileName + fileName=tkFileDialog.askopenfilename(filetypes=[('tiff file','*.tif')]) + + if(fileName == ''): + tkMessageBox.showerror("Error", "Please select an image.") + return + else: + print(fileName) + + +#GUI for Spectral Analysis + + def guiSpectral(): + frame.destroy() + guiSpec=tk.Tk() + guiSpec.title("Spectral Analysis") + + menuBar = tk.Menu(guiSpec) + guiSpec['menu'] = menuBar + subMenu1 = tk.Menu(menuBar) + + menuBar.add_command(label='Open', command=open) + menuBar.add_command(label='Close', command=guiSpec.destroy) + + frameSpec=tk.Frame(guiSpec, width=200, height=200) + + x1=tk.Label(frameSpec, text="Spectral Analysis") + x1.pack(side=tk.TOP, pady = 5 , padx = 5 ) + + def goSpectral(x): + + global fileName + if(fileName == ''): + tkMessageBox.showerror("Error", "Please select an image.") + open() + return + else: + dic = { 1: PCA.pca , 2: spec.spec , 3: spec.spec , 4: spec.spec} + if (x == 1): + dic[x](fileName) + else: + + + + def indices(): + i = opt1.get() + j = int(i) + i = opt2.get() + k = int(i) + frameSpec1.destroy() + frameSpec2.destroy() + frameSpec3.destroy() + dic[x](fileName,x-1,j,k) + + frameSpec1=tk.Frame(frameSpec) + frameSpec2=tk.Frame(frameSpec) + frameSpec1.pack() + frameSpec2.pack() + frameSpec3= tk.Frame(guiSpec) + frameSpec3.pack() + dataset = tifwork.openTIF(fileName) + (cols,rows,bands,bandArray) = tifwork.detailsTIF(dataset) + + optionList=[] + for k in range(1, bands+1): + optionList.append(k) + + lab1=tk.Label(frameSpec1, text="Band Number 1: ") + lab1.pack(side=tk.LEFT, padx=2, pady=2) + opt1= ttk.Combobox(frameSpec1,values=optionList, width=5) + opt1.pack(side = tk.LEFT , pady = 5,padx = 5 ) + + + lab2=tk.Label(frameSpec2, text="Band Number 2: ") + lab2.pack(side=tk.LEFT, padx=2, pady=2) + + opt2= ttk.Combobox(frameSpec2,values=optionList, width=5) + opt2.pack(side = tk.LEFT , pady = 5,padx = 5 ) + + button=tk.Button(frameSpec3, text="Go", command=indices) + button.pack(side=tk.BOTTOM, padx=2, pady=2) + + + button1=tk.Button(frameSpec, text="PCA", command=lambda : goSpectral(1)) + button1.pack(side=tk.TOP, padx=2, pady=2) + button2=tk.Button(frameSpec, text="NDVI", command=lambda:goSpectral(2)) + button2.pack(side=tk.TOP, padx=2, pady=2) + button3=tk.Button(frameSpec, text="TVI", command=lambda:goSpectral(3)) + button3.pack(side=tk.TOP, padx=2, pady=2 ) + button4=tk.Button(frameSpec, text="RI", command=lambda:goSpectral(4)) + button4.pack(side=tk.TOP, padx=2, pady=2 ) + frameSpec.pack() + +#GUI for Spatial Analysis + + def guiSpatial(): + frame.destroy() + guiSpat=tk.Tk() + guiSpat.title("Spatial Analysis") + + menuBar = tk.Menu(guiSpat) + guiSpat['menu'] = menuBar + subMenu1 = tk.Menu(menuBar) + + menuBar.add_command(label='Open', command=open) + menuBar.add_command(label='Close', command=guiSpat.destroy) + + x1=tk.Label(guiSpat, text="Spatial Analysis") + x1.pack(side=tk.TOP, pady = 5 , padx = 5 ) + + guiSpat1=tk.Frame(guiSpat) + guiSpat2=tk.Frame(guiSpat) + frameSpat1=tk.Frame(guiSpat1, width=200, height=200) + frameSpat2=tk.Frame(guiSpat1, width=200, height=200) + frameSpat3=tk.Frame(guiSpat, width=200, height=200) + + def dest(): + global guiSpat3 + global guiSpat4 + guiSpat3.destroy() + guiSpat4.destroy() + def destr(): + global guiSpat3 + guiSpat3.destroy() + +#get the bands for enhancement + def bandChoose(): + + global guiSpat3 + guiSpat3=tk.Frame(guiSpat) + if(fileName == ''): + tkMessageBox.showerror("Error", "Please select an image.") + open() + return + else: + if(opt1.get()=='' and opt2.get()==''): + tkMessageBox.showerror("Error", "Please select an option.") + return + elif(opt1.get()!='' and opt2.get()!=''): + tkMessageBox.showerror("Error", "Please select only one option.") + return + else: + + global box + dataset = tifwork.openTIF(fileName) + (cols,rows,bands,bandArray) = tifwork.detailsTIF(dataset) + + optionList=[] + for k in range(1, bands+1): + optionList.append(k) + + lab=tk.Label(guiSpat3, text="Band Number : ") + lab.pack(side=tk.LEFT, padx=2, pady=2) + box= ttk.Combobox(guiSpat3,values=optionList, width=5) + box.pack(side = tk.LEFT , pady = 5,padx = 5 ) + button=tk.Button(guiSpat3, text="Go", command=goSpatial) + button.pack(side=tk.RIGHT, padx=2, pady=2) + guiSpat3.pack(side=tk.TOP) + + def enterVariable(x,option,bandNum): + global guiSpat4 + global fileName + def spati(option): + + size = boxVar.get() + size = int(size) + #print option + #print size + dic = {'Mean Filter':spat.meanFilter, 'Median Filter':spat.medianFilter, 'Fourier Filter':spat.fourierFilter, 'Gaussian Filter':spat.gaussFilter} + #print dic[option] + dic[option](fileName,size,bandNum) + dest() + + guiSpat4=tk.Frame(guiSpat) + + var=tk.Label(guiSpat4, text="Enter "+str(x)) + var.pack(side=tk.LEFT, padx=2, pady=2) + boxVar=tk.Entry(guiSpat4) + boxVar.pack(side=tk.LEFT, padx=2, pady=2) + button=tk.Button(guiSpat4, text="Goooo",command= lambda : spati(option)) + button.pack(side=tk.LEFT, padx=2, pady=2) + + + guiSpat4.pack(side=tk.TOP) + + def goSpatial(): + global fileName + + + print(fileName) + + + bandNum = box.get() + bandNum = int(bandNum) + dic1 = { 'User Defined Kernel':matrix.test, 'Laplace Filter':spat.laplaceFilter} + dic2 = {'Emboss East':spat.hpfEmbossE,'Sobel Filter':spat.sobelFilter, 'Emboss West':spat.hpfEmbossW, 'Edge Detect':spat.hpfEdgeDetect, 'Prewitt':spat.hpfPrewitt, 'High Pass North':spat.hpfN, 'High Pass Northeast':spat.hpfNE, 'High Pass East':spat.hpfE, 'High Pass Southeast':spat.hpfSE, 'High Pass South':spat.hpfS, 'High Pass Southwest':spat.hpfSW, 'High Pass West':spat.hpfW, 'High Pass Northwest':spat.hpfNW} + + option1 = opt1.get() + option2 = opt2.get() + + if (option1 == ''): + if (option2 != ''): + + print option2 + dic2[option2](fileName,bandNum) + destr() + else: + if(option1== 'Mean Filter' or option1== 'Median Filter'): + enterVariable('Filter Size',option1,bandNum) + + + elif(option1== 'Fourier Filter' or option1== 'Gaussian Filter'): + enterVariable('Sigma',option1,bandNum) + + else: + if (option1 == 'User Defined Kernel'): + dic1[option1]() + else: + dic1[option1](fileName,bandNum) + destr() + + + optionList1=['','User Defined Kernel', 'Mean Filter', 'Median Filter', 'Gaussian Filter', 'Laplace Filter', 'Fourier Filter'] + + x1=tk.Label(frameSpat1, text="Low Pass Filter") + x1.pack(side=tk.TOP, pady = 5 , padx = 5 ) + opt1= ttk.Combobox(frameSpat1,values=optionList1, width=20) + opt1.pack(side = tk.TOP , pady = 5,padx = 5 ) + + optionList2=['','Emboss East', 'Emboss West', 'Edge Detect', 'Prewitt', 'High Pass North','Sobel Filter', 'High Pass Northeast', 'High Pass East', 'High Pass Southeast', 'High Pass South', 'High Pass Southwest', 'High Pass West', 'High Pass Northwest'] + + x2=tk.Label(frameSpat2, text="High Pass Filter") + x2.pack(side=tk.TOP, pady = 5 , padx = 5 ) + opt2= ttk.Combobox(frameSpat2,values=optionList2, width=20) + opt2.pack(side = tk.TOP , pady = 5,padx = 5 ) + + + button1=tk.Button(guiSpat1, text="Choose Band", command=bandChoose) + button1.pack(side=tk.BOTTOM, padx=2, pady=2) + + frameSpat1.pack(side=tk.LEFT, padx=2, pady=2) + frameSpat2.pack(side=tk.LEFT, padx=2, pady=2) + guiSpat1.pack(side=tk.TOP) + frameSpat3.pack(side=tk.TOP, padx=2, pady=2) + guiSpat2.pack(side = tk.BOTTOM) + + + def guiContrast(): + frame.destroy() + guiCont=tk.Tk() + guiCont.title("Contrast Analysis") + + menuBar = tk.Menu(guiCont) + guiCont['menu'] = menuBar + subMenu1 = tk.Menu(menuBar) + + menuBar.add_command(label='Open', command=open) + menuBar.add_command(label='Close', command=guiCont.destroy) + + + frameCont=tk.Frame(guiCont, width=200, height=200) + + x1=tk.Label(frameCont, text="Contrast Analysis") + x1.pack(side=tk.TOP, pady = 5 , padx = 5 ) + def pwrun(): + import piecewise_guiFinal + + def herun(): + import histequalfinal + + def goContrast(x): + + global fileName + if(fileName == ''): + tkMessageBox.showerror("Error", "Please select an image.") + open() + return + else: + print(fileName) + contrast.cont(fileName,x) + + button3=tk.Button(frameCont, text="Linear", command=lambda:goContrast(1)) + button3.pack(side=tk.TOP, padx=2, pady=2 ) + button1=tk.Button(frameCont, text="Logarithmic", command=lambda:goContrast(2)) + button1.pack(side=tk.TOP, padx=2, pady=2) + button2=tk.Button(frameCont, text="Exponential", command=lambda:goContrast(3)) + button2.pack(side=tk.TOP, padx=2, pady=2) + button4=tk.Button(frameCont, text="Piece Wise", command=pwrun) + button4.pack(side=tk.TOP, padx=2, pady=2 ) + button5=tk.Button(frameCont, text="Histogram Equilization", command=herun) + button5.pack(side=tk.TOP, padx=2, pady=2 ) + + frameCont.pack() + + + + + + x1=tk.Label(frame1, text="Image Enhancement") + x1.pack(side=tk.TOP, pady = 5 , padx = 5 ) + + button1=tk.Button(frame1, text="Spatial", command=guiSpatial) + button1.pack(side=tk.TOP, padx=2, pady=2) + button2=tk.Button(frame1, text="Spectral", command=guiSpectral) + button2.pack(side=tk.TOP, padx=2, pady=2) + button3=tk.Button(frame1, text="Contrast", command=guiContrast) + button3.pack(side=tk.TOP, padx=2, pady=2 ) + + frame1.pack(padx=20, pady=20) + + frame.mainloop() diff --git a/gui_backup.py b/gui_backup.py new file mode 100644 index 0000000..15912a9 --- /dev/null +++ b/gui_backup.py @@ -0,0 +1,313 @@ +import Tkinter as tk +from Tkinter import * +from tkMessageBox import * +import ttk +import tkFileDialog +from PIL import Image +import tifwork +import sys +import matplotlib +matplotlib.use('TkAgg') +from Tkinter import * +from tkFileDialog import askopenfilename +from numpy import arange, sin, pi +from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg +# implement the default mpl key bindings +from matplotlib.backend_bases import key_press_handler +import matplotlib.pyplot as plt +import matplotlib.image as mpimg +from matplotlib.figure import Figure +from pylab import * +import cv,cv2 +import scipy.misc + +val=[] +def exit(): + root.destroy() + +def viewerwin(): + Root = tk.Tk() + Root.wm_title("Rectifiction") + + Root.geometry("1080x720") + + + frame8=tk.Frame(Root) + frame9=tk.Frame(frame8) + frame10=tk.Frame(frame8) + button6 = tk.Button(frame9, width=5, height=2, text='Open',command=rgbselect2) + button6.pack() + + button7 = tk.Button(frame10, width=5, height=2, text='Proceed',command=openref) + button7.pack() + + + frame9.pack(side=tk.LEFT) + frame10.pack(side=tk.LEFT) + frame8.pack() + + + + f = Figure(figsize=(5,4), dpi=100) + a = f.add_subplot(111) + filename="liss3.tif" + + img=mpimg.imread(filename) + #grayScaleImage = cv2.cvtColor(img,cv.CV_BGR2GRAY) + #print grayScaleImage + + a.axis('off') + a.imshow(img) + + overlayImage = np.ones_like(img) + overlayImage +=254 + + + over = np.copy(overlayImage) + + print overlayImage + + opacity = 1 + + + + +# a tk.DrawingArea + canvas = FigureCanvasTkAgg(f, master=Root) + canvas.show() + + canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1) + + toolbar = NavigationToolbar2TkAgg( canvas, Root ) + toolbar.update() + canvas._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=1) + + + + global polygon + polygon = [] + closeFlag = False + + def on_key_event(event): + print('you pressed %s'%event.key) + key_press_handler(event, canvas, toolbar) + + + + def mouse_input_event(event): + global polygon + #print 'Event is ', event + print 'input pixel loc is ',event.xdata,' ', event.ydata + polygon.append([np.int(event.xdata),np.int(event.ydata)]) + a.plot(event.xdata,event.ydata,'b.') + + + + poly = plt.Polygon(polygon,closed = event.dblclick, fill = None, edgecolor ='b') + f.gca().add_patch(poly) + + if (event.dblclick == True): + polygon.pop() + polygon = [polygon] + print polygon + + cv2.drawContours(overlayImage,np.array(polygon),0,255) + maskImage = np.zeros_like(img) + cv2.drawContours(maskImage,np.array(polygon),0,255,-1) + extractedImage = np.bitwise_and(over,maskImage) + print extractedImage.shape + + rows,cols,bands = extractedImage.shape + + #print extractedImage + + index = extractedImage > 0 + + #extract = extractedImage.reshape((rows*cols),bands) + + print index[:,0] + scipy.misc.imsave("poly1.jpg",extractedImage) + + + + polygon = [] + + + + canvas.show() + + + + + f.canvas.mpl_connect('button_press_event',mouse_input_event) + f.canvas.mpl_connect('key_press_event', on_key_event) + + + def _quit(): + Root.quit() # stops mainloop + Root.destroy() # this is necessary on Windows to pprevent + # Fatal Python Error: PyEval_RestoreThread: NULL tstate + + button = tk.Button(master=Root, text='Quit', command=_quit) + button.pack(side=tk.BOTTOM) + + + +def rgbselect2(): + + + fileName=tkFileDialog.askopenfilename(title='select image to be rectified') + if(fileName == ''): + pass + else: + print(fileName) + im=(tifwork.openTIF(fileName)) + + +def openref(): + + selection=" " + fileName=tkFileDialog.askopenfilename(title='select reference image') + if(fileName == ''): + pass + else: + print(fileName) + im=(tifwork.openTIF(fileName)) + def sel(): + selection =str(var.get()) + print selection + + def printEntry(): + print selection + + a=tk.Tk() + a.title('Choose Polynomial order') + a.geometry('500x500') + var = IntVar() + R1 = Radiobutton(a, text="Order 0", variable=var, value=0,command=sel) + R1.pack( anchor = W ) + + R2 = Radiobutton(a, text="Order 1", variable=var, value=1,command=sel) + R2.pack( anchor = W ) + + R3 = Radiobutton(a, text="Order 2", variable=var, value=2,command=sel) + R3.pack( anchor = W) + + label = Label(a) + label.pack() + + + L1 = Label(a, text="other") + L1.pack( side = LEFT) + E1 = Entry(a, bd =5, command=printEntry) + + E1.pack(side = RIGHT) + selection=E1.get() + a.mainloop() + + + image=Image.open(im) + image1=ImageTk.PhotoImage(image) + imagesprite=c.create_image(500,500,image=image1) + return im + + + + + + +def rgbselect(): + + fileName=tkFileDialog.askopenfilename() + if(fileName == ''): + pass + else: + print(fileName) + dataset=(tifwork.openTIF(fileName)) + + w=tk.Tk() + + def bandPrint(): + if(not(opt1.get() and opt2.get() and opt3.get())): + showerror("Error", "All bands not selected") + elif(opt1.get()==opt2.get() or opt1.get()==opt3.get() or opt2.get()==opt3.get()): + showerror("Error", "Two same bands selected") + else: + bandArr = tifwork.getBand(dataset,bands,bandArray) + tifwork.selectBand(bandArr,rows,cols,opt1.get(),opt2.get(),opt3.get()) + + frame4 = tk.Frame(w) +# frame4.grid() + frame2=tk.Frame(frame4) +# frame2.grid() + frame3=tk.Frame(frame4) +# frame3.grid() + frame5 = tk.Frame(w) +# frame5.grid() + w.title("Band Selection") + (cols,rows,bands,bandArray) = tifwork.detailsTIF(dataset) + + + optionList=[] + for k in range(1, bands+1): + optionList.append(k) + + x1=tk.Label(frame2, text="Red") + x1.pack(side=tk.TOP, pady = 5 , padx = 5 ) + opt1= ttk.Combobox(frame3,values=optionList, width=5) + opt1.pack(side = tk.TOP , pady = 5,padx = 5 ) + + x2=tk.Label(frame2, text="Blue") + x2.pack(side = tk.TOP , pady = 5 , padx = 5 ) + opt2= ttk.Combobox(frame3 , values=optionList, width=5) + opt2.pack(side = tk.TOP , pady = 5 , padx = 5 ) + + x3=tk.Label(frame2, text="Green") + x3.pack(side = tk.TOP , pady = 5 , padx = 5 ) + opt3= ttk.Combobox(frame3, values=optionList, width=5) + opt3.pack(side = tk.TOP , pady = 5 , padx = 5 ) + + frame2.pack(side=tk.LEFT, pady = 5 , padx = 5 ) + frame3.pack(side=tk.LEFT, pady = 5 , padx = 5 ) + frame4.pack(side= tk.TOP, pady = 5 , padx = 5 ) + + button = tk.Button(frame5, width=10, text="Show", command=bandPrint) + button.pack(side = tk.TOP , pady = 5 , padx = 5 ) + frame5.pack(side=tk.TOP , pady = 5 , padx = 5 ) + +#opens the root window +root=tk.Tk() + +root.title("Image Processing") + +frame1 = tk.Frame(root, width=800) + +#to display the frame +frame1.pack() + +#keeps only the frame +root.overrideredirect(0) +root.resizable(0,0) + +photo3 = tk.PhotoImage(file="2.gif") +button3 = tk.Button(frame1, width=100, height=100, image=photo3) +button3.pack(side=tk.LEFT, padx=2, pady=2) +button3.image = photo3 + + +photo2 = tk.PhotoImage(file="1.gif") +button2 = tk.Button(frame1, width=100, height=100, image=photo2, command=rgbselect) +button2.pack(side=tk.LEFT, padx=2, pady=2) +button2.image = photo2 + +button5 = tk.Button(frame1, width=20, height=6, text='Geometric correction',justify=tk.LEFT,command=viewerwin) +button5.pack(side=tk.LEFT, padx=2, pady=2) + + +photo1 = tk.PhotoImage(file="3.gif") +button1 = tk.Button(frame1, width=100, height=100, image=photo1, command=exit) +button1.pack(side=tk.LEFT, padx=2, pady=2) +button1.image = photo1 + +root.mainloop() + diff --git a/hist.py b/hist.py new file mode 100644 index 0000000..024d590 --- /dev/null +++ b/hist.py @@ -0,0 +1,582 @@ +''' +The software aims to be an open-source package with basic, and advanced Image Processing features. +Copyright (C) 2014 Indian Institute of Remote Sensing, Dehradun + +The original authors of this program (in alphabetical order) are: + +--------------------------------------------------------------------------------------------------------------------------------------- +Sno. NAME Email( AT gmail DOT com) Role(s) +--------------------------------------------------------------------------------------------------------------------------------------- +1. Pragun Vinayak pragunvinayak GUI, Contrast, Histogram +2. Abhishek Kumar Roushan abhishek.roushan12 Histogram, Contrast +---------------------------------------------------------------------------------------------------------------------------------------- + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +''' + +from PIL import Image +from pylab import * +from Tkinter import * +import Tkinter as tk +from tkMessageBox import * +import ttk +import tkFileDialog +from PIL import Image +import tifwork +import sys +import matplotlib +import math +from osgeo import gdal +#import piecewise + +matplotlib.use('TkAgg') +global fx,ax +from numpy import arange, sin, pi +from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg +# implement the default mpl key bindings +from matplotlib.backend_bases import key_press_handler +import matplotlib.pyplot as plt +import matplotlib.image as mpimg +from matplotlib.figure import Figure +import pylab +#import Image, ImageTk +import tktable + +# read image to array + +# create a new figure +#figure() +# don't use colors +#gray() +# show contours with origin upper left corner +#contour(im, origin='image') +#axis('equal') +#axis('off') + +gdal.AllRegister() + +global counter +counter=0 + +global num,den +num=1 +den=1 + +global click2 +click2=[] + +global click3 +click3=[] + +global keyx +keyx=False +def valueofkey(): + global keyx + return keyx + +def setkeyx(): + global keyx + keyx=True + +def resetkeyx(): + global keyx + keyx=False + +global keyy,bandF +global status,lcom,a,frame4 +status='Status :'+'Pending' +keyy=False +def valueofkey1(): + global keyy + return keyy + +def setkeyy(): + global keyy + keyy=True + +def resetkeyy(): + global keyy + keyy=False +# defining functions for showing image and its enhacement + +def linearp(array1,slope,c): + array1=np.array(array1,'uint64') + array1=(slope*array1)+c + print array1 + return array1 + +def logp(array1,slope,c): + array1=np.array(array1,'uint64') + array1=(array1 + 1) + array1=(slope*array1)+c + print array1 + return array1 + +def expp(array1,slope,c): + array1=np.array(array1,'uint64') + array1=(slope*array1)+c + print array1 + return array1 + +def piecewise(x1,x2,y1,y2,array): + array_pw=np.array(array,'uint64') + global opt1 + listvalue=opt1.get() + print listvalue + + index=array_pw >=x1 + print "index" + print index + index1=array_pw <= x2 + print "index1" + print index1 + c_index=index & index1 + print "newarray" + newarray=array_pw[c_index] + print newarray + + if(listvalue == 'Linear'): + slope=(float)(y2-y1)/(x2-x1) + print slope + + c=(float)(x2*y1-x1*y2)/(x2-x1) + print c + array_op=linearp(newarray,slope,c) + print "array_op" + print array_op + array_pw[c_index]=array_op + print "arra_pw" + print array_pw + print "printed" + return array_pw + + elif(listvalue=='Logarithmic'): + y2=np.log(y2) + y1=np.log(y1) + x1=np.log(x1) + x2=np.log(x2) + + slope=(float)(y2-y1)/(x2-x1) + print slope + + c=(float)(x2*y1-x1*y2)/(x2-x1) + print c + array_op=logp(newarray,slope,c) + print "array_op" + print array_op + array_pw[c_index]=array_op + print "arra_pw" + print array_pw + print "printed" + return array_pw + + elif(listvalue=='Exponential'): + y2=np.exp(y2) + y1=np.exp(y1) + x1=np.exp(x1) + x2=np.exp(x2) + + slope=(float)(y2-y1)/(x2-x1) + print slope + + c=(float)(x2*y1-x1*y2)/(x2-x1) + print c + array_op=expp(newarray,slope,c) + print "array_op" + print array_op + array_pw[c_index]=array_op + print "arra_pw" + print array_pw + print "printed" + return array_pw + + else: + global num,den + print num,den + power_n=float(num)/den + y2=np.power(y2,power_n) + y1=np.power(y1,power_n) + x1=np.power(x1,power_n) + x2=np.power(x2,power_n) + + slope=(float)(y2-y1)/(x2-x1) + print slope + + c=(float)(x2*y1-x1*y2)/(x2-x1) + print c + array_op=linearp(newarray,slope,c) + print "array_op" + print array_op + array_pw[c_index]=array_op + print "arra_pw" + print array_pw + print "printed" + return array_pw + +def numbands(filename_extract): + dataset =gdal.Open(filename_extract,gdal.GA_ReadOnly) + if dataset is None: + print 'Could Not Open' + filename + #Alternatively Raise an Event here + sys.exit(1) + bands = dataset.RasterCount + return bands + + + +def finaloutcome(filename2,x1,x2,y1,y2,filesavedas): + dataset =gdal.Open(filename2,gdal.GA_ReadOnly) + if dataset is None: + print 'Could Not Open' + filename + #Alternatively Raise an Event here + sys.exit(1) + + cols = dataset.RasterXSize + rows = dataset.RasterYSize + bands = dataset.RasterCount + print 'Number of bands :' + print bands + rgbArray = np.zeros((rows,cols,bands),'uint16') + + + for x in range(1,bands+1): + band=dataset.GetRasterBand(x) + array=band.ReadAsArray() + +#R-G-B + rgbArray[:,:,x-1] = piecewise(x1,x2,y1,y2,array) + combi= np.zeros((rows,cols,3),'uint8') + count=1 + + for i in range(0,bands): + for j in range(0,bands): + for k in range(0,bands): + if( (not i == j) and (not j ==k) and (not k == i) ): + combi[:,:,0]=rgbArray[:,:,i] + combi[:,:,1]=rgbArray[:,:,j] + combi[:,:,2]=rgbArray[:,:,k] + combImage= Image.fromarray(combi) + combImage.save(filesavedas+str(count)+'.jpeg') + count=count+1 + + +#end + +def finaloutcome2(filename2,x1,x2,y1,y2,filesavedas,band3): + dataset =gdal.Open(filename2,gdal.GA_ReadOnly) + if dataset is None: + print 'Could Not Open' + filename + #Alternatively Raise an Event here + sys.exit(1) + + cols = dataset.RasterXSize + rows = dataset.RasterYSize + bands = dataset.RasterCount + + rgbArray = np.zeros((rows,cols,bands),'uint16') + + + + band=dataset.GetRasterBand(band3) + array=band.ReadAsArray() + print band3 + print 'hello' + y=band3 -1 + print y +#R-G-B + rgbArray[:,:,y] = piecewise(x1,x2,y1,y2,array) + combi= np.zeros((rows,cols,3),'uint8') + + combi[:,:,y]=rgbArray[:,:,y] + combImage= Image.fromarray(combi) + combImage.save(filesavedas+'.jpeg') + filesaveNAME=filesavedas+'.jpeg' + import imageGUI + imageGUI.imdisplay(filesaveNAME,filesaveNAME) +''' for i in range(0,bands): + for j in range(0,bands): + for k in range(0,bands): + if( (not i == j) and (not j ==k) and (not k == i) ): + combi[:,:,0]=rgbArray[:,:,i] + combi[:,:,1]=rgbArray[:,:,j] + combi[:,:,2]=rgbArray[:,:,k] + combImage= Image.fromarray(combi) + combImage.save(filesavedas+str(count)+'.jpeg') + count=count+1 +f''' + +#end + + + +def exit(): + root.destroy() +def click(): + setkeyx() + +def callback(event): + print "clicked at", event.x, event.y + +def mouse_input_event(event): + global counter + global click2 + global click3 + global canvas + if valueofkey(): + print 'input pixel loc is ',event.xdata,' ', event.ydata + ax.plot(event.xdata, event.ydata,'r.') + resetkeyx() + click2.append(event.xdata) + click3.append(event.ydata) + counter=counter+1 + print counter + if(counter % 2 == 0): + x1=click2[-2] + x2=click2[-1] + fx1=click3[-2] + fx2=click3[-1] + + polygon=([x1,fx1],[x2,fx2]) + + print x1,x2,fx1,fx2,polygon + + poly = plt.Polygon(polygon,closed = event.dblclick, fill = None, edgecolor ='r') + fx.gca().add_patch(poly) + canvas.show() + if (counter % 2 == 0): + getyvalues() + +def showhist(filename,x): + hist_display=tk.Frame(x) + im = array(Image.open(filename).convert('L')) + figure() + a=hist(im.flatten(),128) + print a + show() + hist_display.bind("", callback) + hist_display.pack(side=TOP) + +#filename='' +global pt1,pt2,newpt1,newpt2 + +def getyvalues(): + global pt1,pt2,newpt1,newpt2 + + def dispenhanimg(): + global filechosen + global bandF + print 'File inside loop correct' + print filechosen + pt1=np.round(click2[-2]) + pt2=np.round(click2[-1]) + newpt1=int(entry1.get()) + newpt2=int(entry2.get()) + saveas=entry_fn.get() + print 'values obtained now' + print pt1,pt2,newpt1,newpt2,saveas + finaloutcome2(filechosen,pt1,pt2,newpt1,newpt2,saveas,bandF) + a.destroy() + + + global a,frame4 + a=tk.Tk() + a.geometry('300x300') + global counter + ename='Contrast enhancement :'+str(counter/2) + + a.title(ename) + label=tk.Label(a,text='Fill the dn values to stretch') + label.pack() + + + + text1='Original Pt1 :' + str(round(click2[-2])) + text2='Original Pt2 :' + str(round(click2[-1])) + + frame1=tk.Frame(a) + + label1=tk.Label(frame1,text=text1) + label1.pack(side=tk.LEFT) + label3=tk.Label(frame1,text='Transform Pt1 :') + label3.pack(side=tk.LEFT) + entry1=tk.Entry(frame1,width=10) + entry1.pack(side=tk.LEFT) + frame1.pack(side=tk.TOP) + + frame2=tk.Frame(a) + + label2=tk.Label(frame2,text=text2) + label2.pack(side=tk.LEFT) + + label4=tk.Label(frame2,text='Transform Pt2 :') + label4.pack(side=tk.LEFT) + entry2=tk.Entry(frame2,width=10) + entry2.pack(side=tk.LEFT) + + frame2.pack(side=tk.TOP) + + optionList=['Linear','Non-linear(power n)','Exponential','Logarithmic'] + #TYpe of enhancement + frame_type=tk.Frame(a) + labeltp=tk.Label(frame_type,text='Type of enhancement :',pady = 5 , padx = 5) + labeltp.pack(side=tk.LEFT) + global opt1 + opt1= ttk.Combobox(frame_type, values=optionList) + opt1.pack(side = tk.LEFT ) + frame_type.pack(side=tk.TOP) + #end + def getpower(): + global num,den + num=entrypw1.get() + den=entrypw2.get() + print num,den + + label_nl1=tk.Label(a,text=' ---------------------------------') + label_nl1.pack(side=tk.TOP) + label_nl=tk.Label(a,text=' For non-linear of power n only :') + label_nl.pack(side=tk.TOP) + fw1=tk.Frame(a) + + lpw1=tk.Label(fw1,text='Enter Numerator') + entrypw1=tk.Entry(fw1) + lpw1.pack(side=tk.LEFT) + entrypw1.pack(side=tk.LEFT) + fw1.pack(side=tk.TOP) + + fw2=tk.Frame(a) + + lpw2=tk.Label(fw2,text='Enter Denominator') + entrypw2=tk.Entry(fw2) + lpw2.pack(side=tk.LEFT) + entrypw2.pack(side=tk.LEFT) + entrypw2.insert(0,'1') + fw2.pack(side=tk.TOP) + + label_nl2=tk.Label(a,text=' --------------------------------') + label_nl2.pack(side=tk.TOP) + + frame4=tk.Frame(a) + label_fn=tk.Label(frame4,text='Save File as :') + label_fn.pack(side=tk.LEFT) + + entry_fn=tk.Entry(frame4) + entry_fn.pack(side=tk.LEFT) + frame4.pack(side=tk.TOP) + + frame3=tk.Frame(a) + button6=tk.Button(frame3,text='SUBMIT',command=dispenhanimg) + button6.pack(side=tk.LEFT) + + frame3.pack(side=tk.TOP) + + a.mainloop() + + +filechosen='' +def showhist2(filename,Root1,band): + global bandF + bandF=band + global fx,ax + print band + fx = Figure() + ax = fx.add_subplot(111) + + ax.xlim=([0,30]) + global Rootx + global filechosen + filechosen=filename + print filename + resetkeyx() + + dataset =gdal.Open(filename,gdal.GA_ReadOnly) + band_select=dataset.GetRasterBand(band) + array_img=band_select.ReadAsArray() + print array_img + + #img1=mpimg.imread(filename) + #print img1 + ax.hist(array_img.flatten(),128) + + + + + + + print ';sbhsbvbsjv sv obdi' + #im = array(Image.open(filename).convert('L')) + #figure() + + + +# a tk.DrawingArea + global canvas + canvas = FigureCanvasTkAgg(fx, master=Root1) + canvas.show() + + canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1) + + toolbar = NavigationToolbar2TkAgg( canvas, Root1 ) + toolbar.update() + canvas._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=1) + + def on_key_event(event): + print('you pressed %s'%event.key) + key_press_handler(event, canvas, toolbar) + + + fx.canvas.mpl_connect('button_press_event',mouse_input_event) + fx.canvas.mpl_connect('key_press_event', on_key_event) + + def _quitx(): + Root1.quit() # stops mainloop + Root1.destroy() # this is necessary on Windows to pprevent + # Fatal Python Error: PyEval_RestoreThread: NULL tstate + button1 = tk.Button(master=Root1, text='Quit', command=_quitx) + button1.pack(side=tk.BOTTOM) + button = tk.Button(master=Root1, text='Select', command=click) + button.pack(side=tk.BOTTOM) + + + + + +''' + +""" +def histeq(im,nbr_bins=256): + +# get image histogram + imhist,bins = histogram(im.flatten(),nbr_bins,normed=True) + cdf = imhist.cumsum() # cumulative distribution function + cdf = 255 * cdf / cdf[-1] # normalize +# use linear interpolation of cdf to find new pixel values + im2 = interp(im.flatten(),bins[:-1],cdf) + return im2.reshape(im.shape), cdf + +figure() +im2=histeq(im) +hist(im2,256) +show() + +#plt.imshow(im2,cmap=plt.cm.gray) +#plt.savefig('output.jpeg') +#figure##() +#gray() +# show contours with origin upper left corner +#contour(im, origin='image') +#axis('equal') +#axis('off')""" + +''' diff --git a/histequalfinal.py b/histequalfinal.py new file mode 100644 index 0000000..1c65b6f --- /dev/null +++ b/histequalfinal.py @@ -0,0 +1,247 @@ +''' +The software aims to be an open-source package with basic, and advanced Image Processing features. +Copyright (C) 2014 Indian Institute of Remote Sensing, Dehradun + +The original authors of this program (in alphabetical order) are: + +--------------------------------------------------------------------------------------------------------------------------------------- +Sno. NAME Email( AT gmail DOT com) Role(s) +--------------------------------------------------------------------------------------------------------------------------------------- +1. Pragun Vinayak pragunvinayak GUI, Contrast, Histogram +2. Abhishek Kumar Roushan abhishek.roushan12 Histogram, Contrast +---------------------------------------------------------------------------------------------------------------------------------------- + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +''' +from osgeo import gdal +from PIL import Image +from pylab import * +import numpy as np +import pandas as pd +import matplotlib.pyplot as plt +import numpy.random +import matplotlib.cm as cm +import cv2 + +from PIL import Image +from pylab import * +from Tkinter import * +import Tkinter as tk +from tkMessageBox import * +import ttk +import tkFileDialog +from PIL import Image +import tifwork +import sys +import matplotlib +import math +from osgeo import gdal +#import piecewise + +matplotlib.use('TkAgg') +#global fx,ax +from numpy import arange, sin, pi +from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg +# implement the default mpl key bindings +from matplotlib.backend_bases import key_press_handler +import matplotlib.pyplot as plt +import matplotlib.image as mpimg +from matplotlib.figure import Figure +import pylab +#import Image, ImageTk +#import tktable +import tifwork +import matplotlib.gridspec as gridspec + + + + +fileName=tkFileDialog.askopenfilename(filetypes=[('TIF','*.tif')]) +if(fileName == ''): + pass +else: + print(fileName) + dataset=(tifwork.openTIF(fileName)) + + +def histeq(im,nbr_bins=256): + +# get image histogram + imhist,bins = histogram(im.flatten(),nbr_bins,normed=True) + cdf = imhist.cumsum() # cumulative distribution function + cdf = 255 * cdf / cdf[-1] # normalize +# use linear interpolation of cdf to find new pixel values + im2 = interp(im.flatten(),bins[:-1],cdf) + + return im2.reshape(im.shape), cdf + + +def showallhist(imgname): + im = array(Image.open(imgname).convert('L')) + print im + im3 = histeq(im) + im_output=cv2.equalizeHist(im) + + combImage2= Image.fromarray(im_output) + img2=combImage2.save(imgname+'_enhance_'+'.jpeg') + + + + print im_output + + ax1=plt.subplot(221) + plt.xlim([0,255]) + plt.title('Histogram BEFORE Equalization') + plt.xlabel('DN values') + plt.ylabel('Number of pixels') + + ax2=plt.subplot(222) + plt.xlim([0,255]) + plt.title('Histogram AFTER Equalization') + plt.xlabel('DN values') + plt.ylabel('NUmber of pixels') + + + ax3=plt.subplot(223) + plt.axis('off') + plt.title('Image BEFORE Equalization') + + ax4=plt.subplot(224) + plt.axis('off') + plt.title('Image AFTER Equalization') + ax1.hist(im.flatten(),256) + ax2.hist(im3,256) + ax3.imshow(im,cmap=cm.Greys_r) + ax4.imshow(im_output,cmap=cm.Greys_r) + plt.tight_layout() + + plt.show() + + + + + +def bandPrint(): + global entry_fn + savefn=entry_fn.get() + + if(opt1.get()== ""): + showerror("Error", "Two same bands selected") + else: + global fileName + print fileName + ch1 = int(opt1.get()) + dataset =gdal.Open(fileName,gdal.GA_ReadOnly) + band_select=dataset.GetRasterBand(ch1) + array_img=band_select.ReadAsArray() + + Image_of_band= Image.fromarray(array_img) + img=Image_of_band.save(savefn +'.jpeg') + imgn=savefn+'.jpeg' + print 'completed' + print img + print array_img + showallhist(imgn) + + + #hist(im) + + #combImage.show() + +w=tk.Tk() + +w.title("Histogram Equalization") +frame2=tk.Frame(w) +(cols,rows,bands,bandArray) = tifwork.detailsTIF(dataset) + + +optionList=[] +for k in range(1, bands+1): + optionList.append(k) + +x1=tk.Label(frame2, text="Select Band") +x1.pack(side=tk.LEFT, pady = 5 , padx = 5 ) +opt1= ttk.Combobox(frame2,values=optionList, width=5) +opt1.pack(side = tk.LEFT , pady = 5,padx = 5 ) + +frame2.pack(side=tk.TOP, pady = 5 , padx = 5 ) + +frame6=tk.Frame(w) +lfn=tk.Label(frame6,text='Save file As :') +lfn.pack(side=tk.LEFT) +entry_fn=tk.Entry(frame6) +entry_fn.pack(side=tk.LEFT) + + + +frame6.pack(side=tk.TOP) + +button = tk.Button(w, width=20, text="Show Histogram Equalization", command=bandPrint) +button.pack(side = tk.TOP , pady = 5 , padx = 5 ) + +w.mainloop() +# read image to array +#im = array(Image.open('x.jpg').convert('L')) +#figure() +# don't use colors +#gray() +# show contours with origin upper left corner +#contour(im, origin='image') +#axis('equal') +#axis('off') +#show() + +""" + +def showequalhist(): + pass + +def displayimg(im): + figure() + # don't use colors + gray() +# show contours with origin upper left corner + contour(im, origin='image') + axis('equal') + axis('off') + show() +""" + +""" +def numbands(filename_extract): + dataset =gdal.Open(filename_extract,gdal.GA_ReadOnly) + if dataset is None: + print 'Could Not Open' + filename + #Alternatively Raise an Event here + sys.exit(1) + bands = dataset.RasterCount + return bands + + +#GUI + + + + +#end of GUI +# create a new figure +#figure() +# don't use colors +#gray() +# show contours with origin upper left corner +#contour(im, origin='image') +#axis('equal') +#axis('off') +""" diff --git a/iirs.gif b/iirs.gif new file mode 100644 index 0000000..95cc266 Binary files /dev/null and b/iirs.gif differ diff --git a/imageGUI.py b/imageGUI.py new file mode 100644 index 0000000..68798ab --- /dev/null +++ b/imageGUI.py @@ -0,0 +1,60 @@ + +import Tkinter as tk +from Tkinter import * +from tkMessageBox import * +import ttk +import tkFileDialog +from PIL import Image +import tifwork +import sys +import matplotlib +matplotlib.use('TkAgg') + +from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg +from matplotlib.backend_bases import key_press_handler +import matplotlib.pyplot as plt +import matplotlib.image as mpimg +from matplotlib.figure import Figure +import matplotlib.cm as cm +#from tkFileDialog import askopenfilename + +# implement the default mpl key bindings +#import Image, ImageTk + + +def imdisplay(filename,title,x=0): + openImFile(filename,title,x) + +def openImFile(filename,title,x): + Root1 = tk.Tk() + Root1.wm_title(title) + Root1.geometry("600x600") + fx = Figure(figsize=(5,4), dpi=100) + ax = fx.add_subplot(111) + img=mpimg.imread(filename) + if (x == 0): + ax.imshow(img) + else: + ax.imshow(img,cmap = cm.Greys_r) + + canvasx = FigureCanvasTkAgg(fx, master=Root1) + canvasx.draw() + canvasx.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1) + toolbar = NavigationToolbar2TkAgg( canvasx, Root1 ) + toolbar.update() + canvasx._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=1) + + def on_key_event(event): + print('you pressed %s'%event.key) + key_press_handler(event, canvasx, toolbar) + + def _quitx(): + Root1.quit() # stops mainloop + Root1.destroy() + button1 = tk.Button(master=Root1, text='Quit', command=_quitx) + button1.pack(side=tk.BOTTOM) + + fx.canvas.mpl_connect('key_press_event', on_key_event) + + +# a tk.DrawingArea diff --git a/img/classification.png b/img/classification.png new file mode 100644 index 0000000..2569e82 Binary files /dev/null and b/img/classification.png differ diff --git a/img/close.png b/img/close.png new file mode 100644 index 0000000..4296073 Binary files /dev/null and b/img/close.png differ diff --git a/img/display.png b/img/display.png new file mode 100644 index 0000000..a1900dd Binary files /dev/null and b/img/display.png differ diff --git a/img/enhancement.png b/img/enhancement.png new file mode 100644 index 0000000..50729bf Binary files /dev/null and b/img/enhancement.png differ diff --git a/img/rectification.png b/img/rectification.png new file mode 100644 index 0000000..91d69a6 Binary files /dev/null and b/img/rectification.png differ diff --git a/isodata-working.py b/isodata-working.py new file mode 100644 index 0000000..ece4a15 --- /dev/null +++ b/isodata-working.py @@ -0,0 +1,463 @@ +import numpy as np +from scipy.cluster import vq +import scipy.misc +from PIL import Image +import tifwork + +def initialize_parameters(parameters=None): + """Auxiliar function to set default values to all the parameters not + given a value by the user. + + """ + parameters = {} if not parameters else parameters + + def safe_pull_value(parameters, key, default): + return parameters.get(key, default) + + # number of clusters desired + K = safe_pull_value(parameters, 'K', 5) + + # maximum number of iterations + I = safe_pull_value(parameters, 'I', 100) + + # maximum of number of pairs of clusters which can be merged + P = safe_pull_value(parameters, 'P', 4) + + # threshold value for minimum number of samples in each cluster + # (discarding clusters) + THETA_M = safe_pull_value(parameters, 'THETA_M', 10) + + # threshold value for standard deviation (for split) + THETA_S = safe_pull_value(parameters, 'THETA_S', 1) + # threshold value for pairwise distances (for merge) + THETA_C = safe_pull_value(parameters, 'THETA_C', 20) + + # percentage of change in clusters between each iteration + #(to stop algorithm) + THETA_O = 0.05 + + #can use any of both fixed or random + # number of starting clusters + #k = np.random.randint(1, K) + k = safe_pull_value(parameters, 'k', K) + + ret = locals() + ret.pop('safe_pull_value') + ret.pop('parameters') + globals().update(ret) + + +def quit_low_change_in_clusters(centers, last_centers, iter): + """Stop algorithm by low change in the clusters values between each + iteration. + + :returns: True if should stop, otherwise False. + + """ + quit = False + + if centers.shape == last_centers.shape: + thresholds = np.abs((centers - last_centers) / (last_centers + 1)) + + if np.all(thresholds <= THETA_O): # percent of change in [0:1] + quit = True +# print "Isodata(info): Stopped by low threshold at the centers." +# print "Iteration step: %s" % iter + + return quit + + + + +def merge_clusters(img_class_flat, centers, clusters_list): + """ + Merge by pair of clusters in 'below_threshold' to form new clusters. + """ + pair_dists = compute_pairwise_distances(centers) + + first_p_elements = pair_dists[:P] + + below_threshold = [(c1, c2) for d, (c1, c2) in first_p_elements + if d < THETA_C] + + if below_threshold: + k, bands = centers.shape + count_per_cluster = np.zeros(k) + to_add = np.array([[]]).reshape(0,bands) # new clusters to add + to_delete = np.array([[]]).reshape(0,bands) # clusters to delete + + for cluster in xrange(0, k): + result = np.where(img_class_flat == clusters_list[cluster]) + indices = result[0] + count_per_cluster[cluster] = indices.size + + for c1, c2 in below_threshold: + c1_count = float(count_per_cluster[c1]) + 1 + c2_count = float(count_per_cluster[c2]) + factor = 1.0 / (c1_count + c2_count) + weight_c1 = c1_count * centers[c1] #weight_c1 = [x,y,z] + weight_c2 = c2_count * centers[c2] #weight_c1 = [x,y,z] + + value = round(factor * (weight_c1 + weight_c2)) #value = [x,y,z] + + to_add = np.vstack([to_add, value]) + to_delete = np.vstack([to_delete, [c1, c2]]) + + #delete old clusters and their indices from the availables array + centers = np.delete(centers, to_delete,axis =0) + clusters_list = np.delete(clusters_list, to_delete) + + #generate new indices for the new clusters + #starting from the max index 'to_add.size' times + start = int(clusters_list.max()) + end = to_add.size + start + + centers = np.append(centers, to_add) + clusters_list = np.append(clusters_list, xrange(start, end)) + + #centers, clusters_list = sort_arrays_by_first(centers, clusters_list) + + return centers, clusters_list + + +def compute_pairwise_distances(centers): + """ + Compute the pairwise distances 'pair_dists', between every two clusters + centers and returns them sorted. + Returns: + - a list with tuples, where every tuple has in it's first coord the + distance between to clusters, and in the second coord has a tuple, + with the numbers of the clusters measured. + Output example: + [(d1,(cluster_1,cluster_2)), + (d2,(cluster_3,cluster_4)), + ... + (dn, (cluster_n,cluster_n+1))] + """ + pair_dists = [] + size = centers.shape[0] + + for i in xrange(0, size): + for j in xrange(0, size): + if i > j: + di = np.abs(centers[i] - centers[j]) + di = di**2 + d = np.sum(di) + d = d**0.5 + pair_dists.append((d, (i, j))) + + #return it sorted on the first elem + return sorted(pair_dists ) + + +def split_clusters(img_flat, img_class_flat, centers, clusters_list): + """ + Split clusters to form new clusters. + """ + assert centers.shape[0] == clusters_list.size, \ + "ERROR: split() centers and clusters_list size are different" + + delta = 10 + (k,bands) = centers.shape + count_per_cluster = np.zeros(k) + stddev = np.array([]).reshape(0,bands) + + avg_dists_to_clusters = compute_avg_distance(img_flat, img_class_flat, + centers, clusters_list) + d = compute_overall_distance(img_class_flat, avg_dists_to_clusters, + clusters_list) + + # compute all the standard deviation of the clusters + for cluster in xrange(0, k): + indices = np.where(img_class_flat == clusters_list[cluster])[0] + count_per_cluster[cluster] = indices.size + value = ((img_flat[indices] - centers[cluster]) ** 2).sum(axis = 0) + value /= count_per_cluster[cluster] + value = np.sqrt(value) + stddev = np.vstack([stddev, value]) + + meanstd = np.mean(stddev,axis= 1) + cluster = meanstd.argmax() + max_stddev = meanstd[cluster] + max_clusters_list = int(clusters_list.max()) + + if max_stddev > THETA_S: + if avg_dists_to_clusters[cluster] >= d: + if count_per_cluster[cluster] > (2.0 * THETA_M): + old_cluster = centers[cluster] + new_cluster_1 = old_cluster + delta + new_cluster_2 = old_cluster - delta + + centers = np.delete(centers, cluster, axis = 0) + clusters_list = np.delete(clusters_list, cluster) + + centers = np.vstack([centers, new_cluster_1, new_cluster_2]) + clusters_list = np.append(clusters_list, [max_clusters_list, + (max_clusters_list + 1)]) + + centers, clusters_list = sort_arrays_by_first(centers, + clusters_list) + + assert centers.shape[0] == clusters_list.size, \ + "ERROR: split() centers and clusters_list size are different" + + return centers, clusters_list + +def compute_overall_distance(img_class_flat, avg_dists_to_clusters, + clusters_list): + """ + Computes the overall distance of the samples from their respective cluster + centers. + """ + k = avg_dists_to_clusters.size + total = img_class_flat.size + count_per_cluster = np.zeros(k) + + for cluster in xrange(0, k): + indices = np.where(img_class_flat == clusters_list[cluster])[0] + count_per_cluster[cluster] = indices.size + + d = ((count_per_cluster / total) * avg_dists_to_clusters).sum() + + return d + +def compute_avg_distance(img_flat, img_class_flat, centers, clusters_list): + """ + Computes all the average distances to the center in each cluster. + """ + (k,bands) = centers.shape + avg_dists_to_clusters = np.array([]) + + for cluster in xrange(0, k): + indices = np.where(img_class_flat == clusters_list[cluster])[0] + + total_per_cluster = indices.size + 1 + cen = centers[cluster].reshape(1,bands) + + x , dist = vq.vq(img_flat[indices],cen) + + sum_per_cluster = dist.sum() + #sum_per_cluster = (np.abs(img_flat[indices] - centers[cluster])).sum() + + dj = (sum_per_cluster / float(total_per_cluster)) + + avg_dists_to_clusters = np.append(avg_dists_to_clusters, dj) + + return avg_dists_to_clusters + +def discard_clusters(img_class_flat, centers, clusters_list): + """ + Discard clusters with fewer than THETA_M. + """ + (k,bands) = centers.shape + to_delete = np.array([]) + + assert centers.shape[0] == clusters_list.size, \ + "ERROR: discard_cluster() centers and clusters_list size are different" + + for cluster in xrange(0, k): + indices = np.where(img_class_flat == clusters_list[cluster])[0] + total_per_cluster = indices.size + if total_per_cluster <= THETA_M: + to_delete = np.append(to_delete, cluster) + + if to_delete.size: + new_centers = np.delete(centers, to_delete,axis= 0) + new_clusters_list = np.delete(clusters_list, to_delete) + else: + new_centers = centers + new_clusters_list = clusters_list + + #new_centers, new_clusters_list = sort_arrays_by_first(new_centers, new_clusters_list) + +# shape_bef = centers.shape[0] +# shape_aft = new_centers.shape[0] +# print "Isodata(info): Discarded %s clusters." % (shape_bef - shape_aft) + +# if to_delete.size: +# print "Clusters discarded %s" % to_delete + + assert new_centers.shape[0] == new_clusters_list.size, \ + "ERROR: discard_cluster() centers and clusters_list size are different" + + return new_centers, new_clusters_list + +def update_clusters(img_flat, img_class_flat, centers, clusters_list): + + """ Update clusters. """ + (k,bands) = centers.shape + new_centers = np.array([]).reshape(0,bands) + + new_clusters_list = np.array([]) + + assert centers.shape[0] == clusters_list.size, \ + "ERROR: update_clusters() centers and clusters_list size are different" + + for cluster in xrange(0, k): + indices = np.where(img_class_flat == clusters_list[cluster])[0] + #get whole cluster + cluster_values = img_flat[indices] + #sum and count the values + sum_per_cluster = cluster_values.sum(axis = 0) + total_per_cluster = (cluster_values.shape[0]) + 1 + #compute the new center of the cluster + new_cluster = sum_per_cluster / total_per_cluster + + new_centers = np.vstack([new_centers, new_cluster]) + new_clusters_list = np.append(new_clusters_list, cluster) + + #new_centers, new_clusters_list = sort_arrays_by_first(new_centers, new_clusters_list) + + assert new_centers.shape[0] == new_clusters_list.size, \ + "ERROR: update_clusters() centers and clusters_list size are different" + + return new_centers, new_clusters_list + +def initial_clusters(img_flat, k, method="linspace"): + """ + Define initial clusters centers as startup. + By default, the method is "linspace". Other method available is "random". + """ + methods_availables = ["linspace", "random"] + + assert method in methods_availables, "ERROR: method %s is no valid." \ + "Methods availables %s" \ + % (method, methods_availables) + if method == "linspace": + start, end = 0, img_flat.shape[0] + indices = np.random.randint(start, end, k) + centers = np.array([]) + for x in indices: + centers = np.append(centers,img_flat[x]) + + centers = centers.reshape(k,img_flat.shape[1]) + if method == "random": + start, end = 0, img_flat.shape[0] + indices = np.random.randint(start, end, k) + centers = np.array([]) + for x in indices: + centers = np.append(centers,img_flat[x]) + + centers = centers.reshape(k,img_flat.shape[1]) + return centers + +def sort_arrays_by_first(centers, clusters_list): + """ + Sort the array 'centers' and the with indices of the sorted centers + order the array 'clusters_list'. + Example: centers=[22, 33, 0, 11] and cluster_list=[7,6,5,4] + returns (array([ 0, 11, 22, 33]), array([5, 4, 7, 6])) + """ + assert centers.shape[0] == clusters_list.size, \ + "ERROR: sort_arrays_by_first centers and clusters_list size are not equal" + + indices = np.argsort(centers,axis=1) #sorted indic + + sorted_centers = centers[indices[:,0]] + sorted_clusters_list = clusters_list[indices[:,0]] + + return sorted_centers, sorted_clusters_list + + + + + +def isodata_classification(img, parameters=None): + """ + Classify a numpy 'img' using Isodata algorithm. + Parameters: a dictionary with the following keys. + - img: an input numpy array that contains the image to classify. + - parameters: a dictionary with the initial values. + If 'parameters' are not specified, the algorithm uses the default + ones. + + number of clusters desired. + K = 15 + + max number of iterations. + I = 100 + + max number of pairs of clusters which can be ,erged. + P = 2 + + threshold value for min number in each cluster. + THETA_M = 10 + + threshold value for standard deviation (for split). + THETA_S = 0.1 + + threshold value for pairwise distances (for merge). + THETA_C = 2 + + threshold change in the clusters between each iter. + THETA_O = 0.01 + Note: if some(or all) parameters are nos providen, default values + will be used. + Returns: + - img_class: a numpy array with the classification. + """ + global K, I, P, THETA_M, THETA_S, THEHTA_C, THETA_O, k + initialize_parameters(parameters) + + N, M,bands = img.shape # for reshaping at the end + img_flat = img.reshape((N*M),bands) + clusters_list = np.arange(k) # number of clusters availables + + print "Isodata(info): Starting algorithm with %s classes" % k + centers = initial_clusters(img_flat, k, "linspace") + + for iter in xrange(0, I): + # print "Isodata(info): Iteration:%s Num Clusters:%s" % (iter, k) + last_centers = centers.copy() + # assing each of the samples to the closest cluster center + img_class_flat, dists = vq.vq(img_flat, centers) + + centers, clusters_list = discard_clusters(img_class_flat, + centers, clusters_list) + centers, clusters_list = update_clusters(img_flat, + img_class_flat, + centers, clusters_list) + k = centers.shape[0] + + if k <= (K / 2.0): # too few clusters => split clusters + centers, clusters_list = split_clusters(img_flat, img_class_flat, + centers, clusters_list) + + elif k > (K * 2.0): # too many clusters => merge clusters + centers, clusters_list = merge_clusters(img_class_flat, centers, + clusters_list) + else: # nor split or merge are needed + pass + + k , bands = centers.shape +############################################################################### + if quit_low_change_in_clusters(centers, last_centers, iter): + break + +# take_snapshot(img_class_flat.reshape(N, M), iteration_step=iter) +############################################################################### + print "Isodata(info): Finished with %s classes" % k + print "Isodata(info): Number of Iterations: %s" % (iter + 1) + + return img_class_flat + + + +filename = 'liss2.tif' +dataset = tifwork.openTIF(filename) + +(cols,rows,bands,bandArr) = tifwork.detailsTIF(dataset) + +bandArr = tifwork.getBand(dataset,bands,bandArr) + + +imageArray = np.array(bandArr,dtype =float) +x = {'K':5 , 'I':200} +isoarr = isodata_classification(imageArray,x) +#print rows +colorArray=np.array([[0,0,100],[100,0,0],[0,100,0],[100,100,0],[75,75,75],[0,100,100],[100,0,100],[50,25,25],[25,50,25],[25,25,50]]) +clusteredArray = np.zeros((rows*cols,3)) + +clusters = isoarr.max() +#print clusters +for i in xrange(clusters+1): + indices = np.where(isoarr == i)[0] + if indices.size: + clusteredArray[indices] = colorArray[i] + +clusteredArray = clusteredArray.reshape(rows,cols,3) +#print clusteredArray +scipy.misc.imsave('iso.jpg',clusteredArray) diff --git a/isodata.py b/isodata.py new file mode 100644 index 0000000..a715976 --- /dev/null +++ b/isodata.py @@ -0,0 +1,469 @@ +import numpy as np +from scipy.cluster import vq +import scipy.misc +from PIL import Image +import tifwork +import sys +sys.path.append('../GUI/') +import imageGUI +def initialize_parameters(parameters=None): + """Auxiliar function to set default values to all the parameters not + given a value by the user. + + """ + parameters = {} if not parameters else parameters + + def safe_pull_value(parameters, key, default): + return parameters.get(key, default) + + # number of clusters desired + K = safe_pull_value(parameters, 'K', 5) + + # maximum number of iterations + I = safe_pull_value(parameters, 'I', 100) + + # maximum of number of pairs of clusters which can be merged + P = safe_pull_value(parameters, 'P', 4) + + # threshold value for minimum number of samples in each cluster + # (discarding clusters) + THETA_M = safe_pull_value(parameters, 'THETA_M', 10) + + # threshold value for standard deviation (for split) + THETA_S = safe_pull_value(parameters, 'THETA_S', 1) + # threshold value for pairwise distances (for merge) + THETA_C = safe_pull_value(parameters, 'THETA_C', 20) + + # percentage of change in clusters between each iteration + #(to stop algorithm) + THETA_O = 0.01 + + #can use any of both fixed or random + # number of starting clusters + #k = np.random.randint(1, K) + k = safe_pull_value(parameters, 'k', K) + + ret = locals() + ret.pop('safe_pull_value') + ret.pop('parameters') + globals().update(ret) + + +def quit_low_change_in_clusters(centers, last_centers, iter): + """Stop algorithm by low change in the clusters values between each + iteration. + + :returns: True if should stop, otherwise False. + + """ + quit = False + + if centers.shape == last_centers.shape: + thresholds = np.abs((centers - last_centers) / (last_centers + 1)) + + if np.all(thresholds <= THETA_O): # percent of change in [0:1] + quit = True +# print "Isodata(info): Stopped by low threshold at the centers." +# print "Iteration step: %s" % iter + + return quit + + + + +def merge_clusters(img_class_flat, centers, clusters_list): + """ + Merge by pair of clusters in 'below_threshold' to form new clusters. + """ + pair_dists = compute_pairwise_distances(centers) + + first_p_elements = pair_dists[:P] + + below_threshold = [(c1, c2) for d, (c1, c2) in first_p_elements + if d < THETA_C] + + if below_threshold: + k, bands = centers.shape + count_per_cluster = np.zeros(k) + to_add = np.array([[]]).reshape(0,bands) # new clusters to add + to_delete = np.array([[]]).reshape(0,bands) # clusters to delete + + for cluster in xrange(0, k): + result = np.where(img_class_flat == clusters_list[cluster]) + indices = result[0] + count_per_cluster[cluster] = indices.size + + for c1, c2 in below_threshold: + c1_count = float(count_per_cluster[c1]) + 1 + c2_count = float(count_per_cluster[c2]) + factor = 1.0 / (c1_count + c2_count) + weight_c1 = c1_count * centers[c1] #weight_c1 = [x,y,z] + weight_c2 = c2_count * centers[c2] #weight_c1 = [x,y,z] + + value = round(factor * (weight_c1 + weight_c2)) #value = [x,y,z] + + to_add = np.vstack([to_add, value]) + to_delete = np.vstack([to_delete, [c1, c2]]) + + #delete old clusters and their indices from the availables array + centers = np.delete(centers, to_delete,axis =0) + clusters_list = np.delete(clusters_list, to_delete) + + #generate new indices for the new clusters + #starting from the max index 'to_add.size' times + start = int(clusters_list.max()) + end = to_add.size + start + + centers = np.append(centers, to_add) + clusters_list = np.append(clusters_list, xrange(start, end)) + + #centers, clusters_list = sort_arrays_by_first(centers, clusters_list) + + return centers, clusters_list + + +def compute_pairwise_distances(centers): + """ + Compute the pairwise distances 'pair_dists', between every two clusters + centers and returns them sorted. + Returns: + - a list with tuples, where every tuple has in it's first coord the + distance between to clusters, and in the second coord has a tuple, + with the numbers of the clusters measured. + Output example: + [(d1,(cluster_1,cluster_2)), + (d2,(cluster_3,cluster_4)), + ... + (dn, (cluster_n,cluster_n+1))] + """ + pair_dists = [] + size = centers.shape[0] + + for i in xrange(0, size): + for j in xrange(0, size): + if i > j: + di = np.abs(centers[i] - centers[j]) + di = di**2 + d = np.sum(di) + d = d**0.5 + pair_dists.append((d, (i, j))) + + #return it sorted on the first elem + return sorted(pair_dists ) + + +def split_clusters(img_flat, img_class_flat, centers, clusters_list): + """ + Split clusters to form new clusters. + """ + assert centers.shape[0] == clusters_list.size, \ + "ERROR: split() centers and clusters_list size are different" + + delta = 10 + (k,bands) = centers.shape + count_per_cluster = np.zeros(k) + stddev = np.array([]).reshape(0,bands) + + avg_dists_to_clusters = compute_avg_distance(img_flat, img_class_flat, + centers, clusters_list) + d = compute_overall_distance(img_class_flat, avg_dists_to_clusters, + clusters_list) + + # compute all the standard deviation of the clusters + for cluster in xrange(0, k): + indices = np.where(img_class_flat == clusters_list[cluster])[0] + count_per_cluster[cluster] = indices.size + value = ((img_flat[indices] - centers[cluster]) ** 2).sum(axis = 0) + value /= count_per_cluster[cluster] + value = np.sqrt(value) + stddev = np.vstack([stddev, value]) + + meanstd = np.mean(stddev,axis= 1) + cluster = meanstd.argmax() + max_stddev = meanstd[cluster] + max_clusters_list = int(clusters_list.max()) + + if max_stddev > THETA_S: + if avg_dists_to_clusters[cluster] >= d: + if count_per_cluster[cluster] > (2.0 * THETA_M): + old_cluster = centers[cluster] + new_cluster_1 = old_cluster + delta + new_cluster_2 = old_cluster - delta + + centers = np.delete(centers, cluster, axis = 0) + clusters_list = np.delete(clusters_list, cluster) + + centers = np.vstack([centers, new_cluster_1, new_cluster_2]) + clusters_list = np.append(clusters_list, [max_clusters_list, + (max_clusters_list + 1)]) + + centers, clusters_list = sort_arrays_by_first(centers, + clusters_list) + + assert centers.shape[0] == clusters_list.size, \ + "ERROR: split() centers and clusters_list size are different" + + return centers, clusters_list + +def compute_overall_distance(img_class_flat, avg_dists_to_clusters, + clusters_list): + """ + Computes the overall distance of the samples from their respective cluster + centers. + """ + k = avg_dists_to_clusters.size + total = img_class_flat.size + count_per_cluster = np.zeros(k) + + for cluster in xrange(0, k): + indices = np.where(img_class_flat == clusters_list[cluster])[0] + count_per_cluster[cluster] = indices.size + + d = ((count_per_cluster / total) * avg_dists_to_clusters).sum() + + return d + +def compute_avg_distance(img_flat, img_class_flat, centers, clusters_list): + """ + Computes all the average distances to the center in each cluster. + """ + (k,bands) = centers.shape + avg_dists_to_clusters = np.array([]) + + for cluster in xrange(0, k): + indices = np.where(img_class_flat == clusters_list[cluster])[0] + + total_per_cluster = indices.size + 1 + cen = centers[cluster].reshape(1,bands) + + x , dist = vq.vq(img_flat[indices],cen) + + sum_per_cluster = dist.sum() + #sum_per_cluster = (np.abs(img_flat[indices] - centers[cluster])).sum() + + dj = (sum_per_cluster / float(total_per_cluster)) + + avg_dists_to_clusters = np.append(avg_dists_to_clusters, dj) + + return avg_dists_to_clusters + +def discard_clusters(img_class_flat, centers, clusters_list): + """ + Discard clusters with fewer than THETA_M. + """ + (k,bands) = centers.shape + to_delete = np.array([]) + + assert centers.shape[0] == clusters_list.size, \ + "ERROR: discard_cluster() centers and clusters_list size are different" + + for cluster in xrange(0, k): + indices = np.where(img_class_flat == clusters_list[cluster])[0] + total_per_cluster = indices.size + if total_per_cluster <= THETA_M: + to_delete = np.append(to_delete, cluster) + + if to_delete.size: + new_centers = np.delete(centers, to_delete,axis= 0) + new_clusters_list = np.delete(clusters_list, to_delete) + else: + new_centers = centers + new_clusters_list = clusters_list + + #new_centers, new_clusters_list = sort_arrays_by_first(new_centers, new_clusters_list) + +# shape_bef = centers.shape[0] +# shape_aft = new_centers.shape[0] +# print "Isodata(info): Discarded %s clusters." % (shape_bef - shape_aft) + +# if to_delete.size: +# print "Clusters discarded %s" % to_delete + + assert new_centers.shape[0] == new_clusters_list.size, \ + "ERROR: discard_cluster() centers and clusters_list size are different" + + return new_centers, new_clusters_list + +def update_clusters(img_flat, img_class_flat, centers, clusters_list): + + """ Update clusters. """ + (k,bands) = centers.shape + new_centers = np.array([]).reshape(0,bands) + + new_clusters_list = np.array([]) + + assert centers.shape[0] == clusters_list.size, \ + "ERROR: update_clusters() centers and clusters_list size are different" + + for cluster in xrange(0, k): + indices = np.where(img_class_flat == clusters_list[cluster])[0] + #get whole cluster + cluster_values = img_flat[indices] + #sum and count the values + sum_per_cluster = cluster_values.sum(axis = 0) + total_per_cluster = (cluster_values.shape[0]) + 1 + #compute the new center of the cluster + new_cluster = sum_per_cluster / total_per_cluster + + new_centers = np.vstack([new_centers, new_cluster]) + new_clusters_list = np.append(new_clusters_list, cluster) + + #new_centers, new_clusters_list = sort_arrays_by_first(new_centers, new_clusters_list) + + assert new_centers.shape[0] == new_clusters_list.size, \ + "ERROR: update_clusters() centers and clusters_list size are different" + + return new_centers, new_clusters_list + +def initial_clusters(img_flat, k, method="linspace"): + """ + Define initial clusters centers as startup. + By default, the method is "linspace". Other method available is "random". + """ + methods_availables = ["linspace", "random"] + + assert method in methods_availables, "ERROR: method %s is no valid." \ + "Methods availables %s" \ + % (method, methods_availables) + if method == "linspace": + start, end = 0, img_flat.shape[0] + indices = np.random.randint(start, end, k) + centers = np.array([]) + for x in indices: + centers = np.append(centers,img_flat[x]) + + centers = centers.reshape(k,img_flat.shape[1]) + if method == "random": + start, end = 0, img_flat.shape[0] + indices = np.random.randint(start, end, k) + centers = np.array([]) + for x in indices: + centers = np.append(centers,img_flat[x]) + + centers = centers.reshape(k,img_flat.shape[1]) + return centers + +def sort_arrays_by_first(centers, clusters_list): + """ + Sort the array 'centers' and the with indices of the sorted centers + order the array 'clusters_list'. + Example: centers=[22, 33, 0, 11] and cluster_list=[7,6,5,4] + returns (array([ 0, 11, 22, 33]), array([5, 4, 7, 6])) + """ + assert centers.shape[0] == clusters_list.size, \ + "ERROR: sort_arrays_by_first centers and clusters_list size are not equal" + + indices = np.argsort(centers,axis=1) #sorted indic + + sorted_centers = centers[indices[:,0]] + sorted_clusters_list = clusters_list[indices[:,0]] + + return sorted_centers, sorted_clusters_list + + + + + +def isodata_classification(img, parameters=None): + """ + Classify a numpy 'img' using Isodata algorithm. + Parameters: a dictionary with the following keys. + - img: an input numpy array that contains the image to classify. + - parameters: a dictionary with the initial values. + If 'parameters' are not specified, the algorithm uses the default + ones. + + number of clusters desired. + K = 15 + + max number of iterations. + I = 100 + + max number of pairs of clusters which can be ,erged. + P = 2 + + threshold value for min number in each cluster. + THETA_M = 10 + + threshold value for standard deviation (for split). + THETA_S = 0.1 + + threshold value for pairwise distances (for merge). + THETA_C = 2 + + threshold change in the clusters between each iter. + THETA_O = 0.01 + Note: if some(or all) parameters are nos providen, default values + will be used. + Returns: + - img_class: a numpy array with the classification. + """ + global K, I, P, THETA_M, THETA_S, THEHTA_C, THETA_O, k + initialize_parameters(parameters) + + N, M,bands = img.shape # for reshaping at the end + img_flat = img.reshape((N*M),bands) + clusters_list = np.arange(k) # number of clusters availables + + print "Isodata(info): Starting algorithm with %s classes" % k + centers = initial_clusters(img_flat, k, "linspace") + + for iter in xrange(0, I): + # print "Isodata(info): Iteration:%s Num Clusters:%s" % (iter, k) + last_centers = centers.copy() + # assing each of the samples to the closest cluster center + img_class_flat, dists = vq.vq(img_flat, centers) + + centers, clusters_list = discard_clusters(img_class_flat, + centers, clusters_list) + centers, clusters_list = update_clusters(img_flat, + img_class_flat, + centers, clusters_list) + k = centers.shape[0] + + if k <= (K / 2.0): # too few clusters => split clusters + centers, clusters_list = split_clusters(img_flat, img_class_flat, + centers, clusters_list) + + elif k > (K * 2.0): # too many clusters => merge clusters + centers, clusters_list = merge_clusters(img_class_flat, centers, + clusters_list) + else: # nor split or merge are needed + pass + + k , bands = centers.shape +############################################################################### + if quit_low_change_in_clusters(centers, last_centers, iter): + break + +# take_snapshot(img_class_flat.reshape(N, M), iteration_step=iter) +############################################################################### + print "Isodata(info): Finished with %s classes" % k + print "Isodata(info): Number of Iterations: %s" % (iter + 1) + + return img_class_flat + + + +def isoclass (filename , colorArray,x): + dataset = tifwork.openTIF(filename) + + (cols,rows,bands,bandArr) = tifwork.detailsTIF(dataset) + + bandArr = tifwork.getBand(dataset,bands,bandArr) + + + + imageArray = np.array(bandArr,dtype =float) + + isoarr = isodata_classification(imageArray,x) + print isoarr.shape + #print rows + #colorArray=np.array([[0,0,100],[100,0,0],[0,100,0],[100,100,0],[75,75,75],[0,100,100],[100,0,100],[50,25,25],[25,50,25],[25,25,50]]) + clusteredArray = np.zeros((rows*cols,3)) + print clusteredArray.shape + clusters = isoarr.max() + #print clusters + for i in xrange(clusters+1): + indices = np.where(isoarr == i)[0] + if indices.size: + clusteredArray[indices] = colorArray[i] + + clusteredArray = clusteredArray.reshape(rows,cols,3) + #print clusteredArray + scipy.misc.imsave('iso.jpg',clusteredArray) + imageGUI.imdisplay('iso.jpg','ISODATA-Image') + print 'iso done' diff --git a/kmeans.py b/kmeans.py new file mode 100644 index 0000000..6412711 --- /dev/null +++ b/kmeans.py @@ -0,0 +1,89 @@ +from PIL import Image +import numpy as np +import pylab +#from PIL import Image +import random +import tifwork as tw +import scipy.misc + + + +def initCentroids(Dataset,K,z): + init_centroid = np.zeros((K,z)) + for i in range(0,K): + j = random.choice(Dataset) + init_centroid[i,:] = j + return init_centroid + +def kmeans(Dataset,K,initial_centroid): + (nos,z) = Dataset.shape + + idx = np.zeros((row*col),float) + dis = np.zeros(z,float) + for i in range(0,nos): + for j in range(0,K): + dis = (initial_centroid[j,:] - Dataset[i,:])**2 + dist = 0 + for k in range(0,z): + dist += dis[k] + if( j == 0): + minimum = dist + idx[i] = j + elif (dist < minimum): + minimum = dist + idx[i] = j + + centroid = newclus(K,nos,Dataset,idx) + return (idx,centroid) + +def newclus(K,nos,Dataset,idx): + centroid = np.zeros((K,z)) + for i in range(0,K): + mean = [0,0,0] + count = 0 + for j in range(0,nos): + if(idx[j] == i): + mean = mean+Dataset[j] + count+=1 + + mean = mean/count + centroid[i,:] = mean + return centroid + +Dataset = np.array(Image.open('good.jpg'),float) +(row,col,z) = Dataset.shape + +arr2 = np.zeros(Dataset.shape,float) + +Dataset = Dataset/255 + +# no of clusters +K = 4 + +#no of iters +iters = 3 + +Data_orig = Dataset +Dataset=Dataset.reshape(((row*col),z)) +#print Dataset.shape + + +initial_centroid = initCentroids(Dataset,K,z) +#print initial_centroid + +for q in range(0,iters): + + (idx,centroid)=kmeans(Dataset,K,initial_centroid) + +print idx.max() + +color = [(10,0,0),(0,25,0),(0,0,55),(10,10,10),(12,0,45),(34,65,0),(0,45,87),(100,100,100),(50,50,50),(12,54,77),(43,65,99)] +for i in range(0,(row*col)): + + Dataset[i] = color[int(idx[i])] + +Dataset=Dataset.reshape(row,col,z) + +print Dataset.shape +scipy.misc.imsave('kmeans.jpeg',Dataset) + diff --git a/kmeanswork.py b/kmeanswork.py new file mode 100644 index 0000000..95cdfe7 --- /dev/null +++ b/kmeanswork.py @@ -0,0 +1,44 @@ +from spectral import kmeans +from PIL import Image +import scipy.misc +import tifwork +import numpy as np +import sys +sys.path.append('../GUI/') +import imageGUI + +def kmea(colorArray,iterations,fileName): + print 'Kmeans' + + print colorArray + print iterations + print fileName + dataset = tifwork.openTIF(fileName) + + (cols,rows,bands,bandArr) = tifwork.detailsTIF(dataset) + + bandArr = tifwork.getBand(dataset,bands,bandArr) + + + imageArray = np.array(bandArr,dtype =float) + + clusters = len(colorArray) + print 'clusters = ' , clusters + #iterations = 3 + + (clusterNumber, colorArr) = kmeans(imageArray,clusters,iterations) + + #print colorArray.shape + #print clusterNumber + + clusteredArray = np.zeros((rows,cols,3)) + + for i in range(clusters): + index = clusterNumber == i + clusteredArray[index] = colorArray[i] + + + scipy.misc.imsave('kMeans.jpg',clusteredArray) + + imageGUI.imdisplay('kMeans.jpg','Kmeans-Image') + print 'kmeans done' diff --git a/matrix.py b/matrix.py new file mode 100644 index 0000000..c279c51 --- /dev/null +++ b/matrix.py @@ -0,0 +1,80 @@ +import Tkinter as tk + +class SimpleTableInput(tk.Frame): + def __init__(self, parent, rows, columns): + tk.Frame.__init__(self, parent) + + self._entry = {} + self.rows = rows + self.columns = columns + + # register a command to use for validation + vcmd = (self.register(self._validate), "%P") + + # create the table of widgets + for row in range(self.rows): + for column in range(self.columns): + index = (row, column) + e = tk.Entry(self, validate="key", validatecommand=vcmd) + e.grid(row=row, column=column, stick="nsew") + self._entry[index] = e + # adjust column weights so they all expand equally + for column in range(self.columns): + self.grid_columnconfigure(column, weight=1) + # designate a final, empty row to fill up any extra space + self.grid_rowconfigure(rows, weight=1) + + def get(self): + '''Return a list of lists, containing the data in the table''' + result = [] + for row in range(self.rows): + current_row = [] + for column in range(self.columns): + index = (row, column) + current_row.append(self._entry[index].get()) + result.append(current_row) + return result + + def _validate(self, P): + '''Perform input validation. + + Allow only an empty value, or a value that can be converted to a float + ''' + if P.strip() == "": + return True + + try: + f = float(P) + except ValueError: + self.bell() + return False + return True + +class Example(tk.Frame): + def __init__(self, parent,i): + tk.Frame.__init__(self, parent) + j=int(i) + self.table = SimpleTableInput(self, j, j) + self.submit = tk.Button(self, text="Submit", command=self.on_submit) + self.table.pack(side="top", fill="both", expand=True) + self.submit.pack(side="bottom") + + def on_submit(self): + print(self.table.get()) + + + +def test(): + root = tk.Tk() + def size(): + i=box.get() + box.destroy() + button.destroy() + Example(root,i).pack(side="top", fill="both", expand=True) + box=tk.Entry(root) + box.pack() + button=tk.Button(root, text="Go", command=size) + button.pack() + + + root.mainloop() diff --git a/menu_super.py b/menu_super.py new file mode 100644 index 0000000..423376c --- /dev/null +++ b/menu_super.py @@ -0,0 +1,304 @@ +from Tkinter import * +import tkMessageBox +import tkFileDialog +import math +import numpy +import tkColorChooser +import sys +import tifwork +import numpy as np +import PIL.Image as Image +import matplotlib +matplotlib.use('TkAgg') +from numpy import arange, sin, pi +from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg +# implement the default mpl key bindings +from matplotlib.backend_bases import key_press_handler +import matplotlib.pyplot as plt +import matplotlib.image as mpimg +from matplotlib.figure import Figure +import cv,cv2 +import scipy.misc +import svms +import matplotlib.cm as cm +global bandArray +global bands +global target +global data +global count_target +count_target = 0 +global prev +prev = 0 + +data = None +def getData(fileName, num): + #get dataset + global bandArray + global bands + global target + global data + dataset = tifwork.openTIF(fileName) + + #get details of dataset + (cols,rows,bands,bandArray) = tifwork.detailsTIF(dataset) + + #get all bands + bandArray = tifwork.getBand(dataset,bands,bandArray) + + #input a band + print rows, cols + workData = bandArray[:,:,num-1] + if (data == None): + data = np.array([]).reshape(0,bands) + target = np.array([]) + #show original image and plot it + imdata = Image.fromarray(workData) + imdata = imdata.convert('L') + imdata.save('original.jpg') + #plot(workData,'Original') + filename = 'original.jpg' + return filename + +global index +index = [] +val=[] +def exit(): + root.destroy() + + + +def viewerwin(fileName): + global bandArray + global index + + def index_return(): + global data + global target + global count_target + global prev + if (count_target == 0): + target = np.append(target, np.zeros(data.shape[0])) + prev = data.shape[0] + else: + next = data.shape[0] - prev + target = np.append(target, (np.ones(next)*count_target)) + prev = data.shape[0] + count_target += 1 + print 'index_return data ' ,data.shape + print 'index_return target' ,target.shape + _quit() + Root = Tk() + Root.wm_title("Training Data") + Root.geometry("800x600") + frame8=Frame(Root) + frame8.pack() + f = Figure(figsize=(5,4), dpi=100) + a = f.add_subplot(111) + filename= getData(fileName, 1) + img=mpimg.imread(filename) + print img.shape + #grayScaleImage = cv2.cvtColor(img,cv.CV_BGR2GRAY) + #print grayScaleImage + a.axis('off') + a.imshow(img,cmap = cm.Greys_r) + overlayImage = np.ones_like(img) + overlayImage +=254 + over = np.copy(overlayImage) + #print overlayImage + opacity = 1 + # a tk.DrawingArea + canvas = FigureCanvasTkAgg(f, master=Root) + canvas.show() + canvas.get_tk_widget().pack(side=TOP, fill=BOTH, expand=1) + toolbar = NavigationToolbar2TkAgg( canvas, Root ) + toolbar.update() + canvas._tkcanvas.pack(side=TOP, fill=BOTH, expand=1) + global polygon + polygon = [] + closeFlag = False + def mouse_input_event(event): + global polygon + global index + global bandArray + global data + #print 'Event is ', event + print 'input pixel loc is ',event.xdata,' ', event.ydata + polygon.append([np.int(event.xdata),np.int(event.ydata)]) + a.plot(event.xdata,event.ydata,'r.') + poly = plt.Polygon(polygon,closed = event.dblclick, fill = None, edgecolor ='r') + f.gca().add_patch(poly) + if (event.dblclick == True): + poly = plt.Polygon(polygon,closed = event.dblclick, fill = None, edgecolor ='r') + f.gca().add_patch(poly) + canvas.show() + polygon.pop() + polygon = [polygon] + print polygon + cv2.drawContours(overlayImage,np.array(polygon),0,255) + maskImage = np.zeros_like(img) + cv2.drawContours(maskImage,np.array(polygon),0,255,-1) + extractedImage = np.bitwise_and(over,maskImage) + + rows,cols = extractedImage.shape + #print extractedImage + index = extractedImage > 0 + + #print workData[index] + extract = bandArray.reshape((rows*cols),bands) + index = index.reshape((rows*cols)) + print extract + print index + data = np.vstack([data,extract[index]]) + print 'data shape' , data.shape + scipy.misc.imsave("poly1.jpg",extractedImage) + polygon = [] + canvas.show() + f.canvas.mpl_connect('button_press_event',mouse_input_event) + def _quit(): + Root.destroy() # this is necessary on Windows to pprevent + + button = Button(master=Root, text='Done', command=index_return) + button.pack(side=BOTTOM) + + +filename='' +#iteration=0 +index='' + +def supervi(typ): + global filename + #global iteration + global box1 + global root + root=Tk() + root.geometry('350x350') + root.title('Supervised Classification') + count=0 + + global i + i=0 + + def end(): + global root + root.destroy() + + def showfilename(filen): + tkMessageBox.showinfo('File Chosen',filen) + + def help_tab(): + tkMessageBox.showinfo("Help","You are too dumb") + + def browse(): + global filename + filename=tkFileDialog.askopenfilename(filetypes=[("TIF File","*.tif")]) + showfilename(filename) + print filename + + def changecolor(): + if ( filename == ''): + browse() + viewerwin(filename) + + + def endfield(): + global add + add.destroy() + stopaddition.destroy() + global add2 + add2=Button(framebutton,text='Add More',command=addfield ) + add2.pack() + + + def createfield(name,framename): + + name=Entry(framename,width=5) + name.pack() + + def addfield(): + global i + global l2 + global box1 + i=i+1 + + def changecolor2(): + if ( filename == ''): + browse() + viewerwin(filename) + outerframe=Frame(frame2) + l1=Label(outerframe,text=str(i+1),width=10) + l1.pack(side=LEFT) + + l2=Entry(outerframe,width=5) + l2.pack(side=LEFT) + l3=Button(outerframe,text='Area',command=changecolor2,width=10) + l3.pack(side=LEFT) + outerframe.pack(side=TOP) + + + def supervised(): + global filename + global target + global data + global count_target + print 'data' , data.shape + print 'target' , target.shape + svms.svmwork(filename,data,target,typ) + + # create a toplevel menu + menubar = Menu(root) + filemenu2=Menu(menubar,tearoff='0') + + filemenu3=Menu(menubar,tearoff='0') + filemenu3.add_command(label='Open',command=browse) + filemenu3.add_command(label='Close',command=end) + menubar.add_cascade(label='Import File',menu=filemenu3) + + + # create a pulldown menu, and add it to the menu bar + + menubar.add_cascade(label="Help", menu=filemenu2) + + filemenu2.add_command(label="About Software", command=help_tab) + + root.config(menu=menubar) + + #display buttons + showimg=Button(root,text='Display Image',command= supervised) + showimg.pack() + + #creating labels + frame1=Frame(root) + lu=Label(frame1,text='Cluster No.',width=10) + lu.pack(side=LEFT) + lu1=Label(frame1,text='Name',width=10) + lu1.pack(side=LEFT) + + lu2=Label(frame1,text='Cluster Area',width=10) + lu2.pack(side=LEFT) + + frame1.pack(side=TOP) + + global frame2 + frame2=Frame(root) + #print text + + outerframe=Frame(frame2) + l1=Label(outerframe,text=str(i+1),width=10) + l1.pack(side=LEFT) + + l2=Entry(outerframe,width=5) + l2.pack(side=LEFT) + l3=Button(outerframe,text='Area',command=changecolor,width=10) + l3.pack(side=LEFT) + outerframe.pack(side=TOP) + + frame2.pack(side=TOP) + #submit value + framebutton=Frame(root,pady=30) + global add + add=Button(framebutton,text='Add',command=addfield) + add.pack(side=LEFT) + framebutton.pack(side=TOP) + root.mainloop() + +#supervi('linear') diff --git a/menu_unsuper.py b/menu_unsuper.py new file mode 100644 index 0000000..9bcd583 --- /dev/null +++ b/menu_unsuper.py @@ -0,0 +1,270 @@ +from Tkinter import * +import tkMessageBox +import tkFileDialog +import math +import numpy +import tkColorChooser +import sys +sys.path.append('./K-means') +import kmeanswork as km +import numpy as np +sys.path.append('./ISODATA') +import isodata as iso +sys.path.append('./fuzzy') +import fuzzy as fz +filename='' +iteration=0 + +def unsuper(no): + global filename + global iteration + global box1 + global root + root=Tk() + root.geometry('350x350') + root.title('Unsupervised Classification') + count=0 + global i + i=0 + global text + text=0 + global clustervalue,add2 + clustervalue=numpy.array([]) + global l1,l2,l3,hexc,rgb + + global clusterarray + clusterarray=[] + + global colorArr + colorArr = [] + + global className + className = [] + + + + def end(): + global root + root.destroy() + + def showfilename(filen): + tkMessageBox.showinfo('File Chosen',filen) + + def help_tab(): + tkMessageBox.showinfo("Help","You are too dumb") + + def browse(): + global filename + filename=tkFileDialog.askopenfilename(filetypes=[("TIF File","*.tif")]) + showfilename(filename) + print filename + + def changecolor(): + global hexcsp + global i + global rgb + hexc='hexc'+str(i+1) + + (rgb,hexc)=tkColorChooser.askcolor() + #print hexc + #print rgb + l3.configure(bg=hexc) + + def endfield(): + global add + add.destroy() + stopaddition.destroy() + global add2 + add2=Button(framebutton,text='Add More',command=addfield ) + add2.pack() + + + def createfield(name,framename): + + name=Entry(framename,width=5) + name.pack() + + def addfield(): + global i + global clustervalue + global l2 + global clusterarray + global box1 + global rgb + global colorArr + global className + global iteration + cname=l2.get() + #print cname + + className.append(cname) + clustervalue=[i,cname,rgb] + colorArr.append(rgb) + #print clustervalue + #print colorArr + clusterarray.append(clustervalue) + i=i+1 + iterationnum=box1.get() + clusternum=i + + #print "No. of Iterations: ",iterationnum + #print "No. of Clusters: ",clusternum + + #print clusterarray + + + def changecolor2(): + global rgb + global hexc + global i + rgb='rgb'+str(i+1) + hexc='hexc'+str(i+1) + (rgb,hexc)=tkColorChooser.askcolor() + #print rgb + l3.configure(bg=hexc) + + + + outerframe='outerframe'+str(i+1) + #print outerframe + l1='l1'+str(i+1) + l2='box'+str(i+1) + l3='colorchooser'+str(i+1) + outerframe=Frame(frame2) + l1=Label(outerframe,text=str(i+1),width=10) + l1.pack(side=LEFT) + + l2=Entry(outerframe,width=5) + l2.pack(side=LEFT) + l3=Button(outerframe,text='Color',command=changecolor2,width=10) + l3.pack(side=LEFT) + outerframe.pack(side=TOP) + + + #print i + def setiter(): + global iteration + text=box1.get() + a=len(text) + if a == 0 : + tkMessageBox.showerror('Error','Enter value !') + pass + else: + print text + iteration=int(text) + + outerframe=numpy.array([]) + innerframe1=numpy.array([]) + colorbox=numpy.array([]) + + + + def unsupervised(): + global filename + global iteration + print colorArr + print className + print filename + if (filename == ''): + browse() + + if (no == 1): + km.kmea(colorArr,iteration,filename) + if (no == 2): + x = {'K':len(colorArr) , 'I':iteration} + iso.isoclass(filename, colorArr,x) + if (no == 3): + fz.fuzz(colorArr,filename) + + + # create a toplevel menu + menubar = Menu(root) + filemenu2=Menu(menubar,tearoff='0') + + filemenu3=Menu(menubar,tearoff='0') + filemenu3.add_command(label='Open',command=browse) + filemenu3.add_command(label='Close',command=end) + menubar.add_cascade(label='Import File',menu=filemenu3) + + + # create a pulldown menu, and add it to the menu bar + + menubar.add_cascade(label="Help", menu=filemenu2) + + filemenu2.add_command(label="About Software", command=help_tab) + + root.config(menu=menubar) + + #display buttons + showimg=Button(root,text='Display Image',command= unsupervised) + showimg.pack() + + +#number of iterations + framec=Frame(root) + lnumiter=Label(framec,text='Enter Number of Iterations :',padx=10,pady=10) + lnumiter.pack(side=LEFT) + + box1=Entry(framec,width=5) + box1.pack(side=LEFT) + + submitnum=Button(framec,text='Go',command=setiter) + submitnum.pack(side=LEFT) + framec.pack(side=TOP) + + #creating labels + frame1=Frame(root) + lu=Label(frame1,text='Cluster No.',width=10) + lu.pack(side=LEFT) + lu1=Label(frame1,text='Name',width=10) + lu1.pack(side=LEFT) + + lu2=Label(frame1,text='Color Code',width=10) + lu2.pack(side=LEFT) + + frame1.pack(side=TOP) + + global frame2 + frame2=Frame(root) + #print text + + global arrayvalue + + arrayvalue=numpy.array([]) + + + outerframe='outerframe'+str(i+1) + #print outerframe + l1='l1'+str(i+1) + l2='box'+str(i+1) + l3='colorchooser'+str(i+1) + outerframe=Frame(frame2) + l1=Label(outerframe,text=str(i+1),width=10) + l1.pack(side=LEFT) + + l2=Entry(outerframe,width=5) + l2.pack(side=LEFT) + l3=Button(outerframe,text='Color',command=changecolor,width=10) + l3.pack(side=LEFT) + outerframe.pack(side=TOP) + + + frame2.pack(side=TOP) + + + #submit value + framebutton=Frame(root,pady=30) + global add + add=Button(framebutton,text='Add',command=addfield) + add.pack(side=LEFT) + #stopaddition=Button(framebutton,text='End Addition',command=endfield) + #stopaddition.pack(side=LEFT) + framebutton.pack(side=TOP) + iterationnum=l2.get() + clusternum=i + + #print "No. of Iterations: ",iterationnum + #print "No. of Iterations: ",clusternum + root.mainloop() + + diff --git a/piecewise_guiFinal.py b/piecewise_guiFinal.py new file mode 100644 index 0000000..c5885f7 --- /dev/null +++ b/piecewise_guiFinal.py @@ -0,0 +1,101 @@ +from osgeo import gdal +from Tkinter import * +import Tkinter as tk +import tkMessageBox +import tkFileDialog +from PIL import Image +import pylab +import hist + +root=tk.Tk() +root.geometry('500x200') + +root.title('Piecewise Contrast Enhancement') + +filename='' +bandnum='' +band_chosen='' +def openimage(): + global filename + global box1 + filename=tkFileDialog.askopenfilename(title='Choose Image File',filetypes=[('TIF Image','*.tif')]) + box1.destroy() + labelfile=tk.Entry(frametop,width=35) + labelfile.insert(0,filename) + labelfile.pack(side=LEFT) + +def bandsel(): + global band_chosen + global entry_bb,bandbox + band_chosen=int(entry_bb.get()) + + print band_chosen + bandbox.destroy() + +def chooseband(): + global filename + print filename + if(filename == ''): + tkMessageBox.showerror('Error','Image not selected.') + else: + global bandnum,bandbox + bandnum=hist.numbands(filename) + print bandnum + bandbox=tk.Tk() + bandbox.title('Select Band') + frame_bb=tk.Frame(bandbox) + text_bb='Select Band : 1 -' +str(bandnum) + l_bb=tk.Label(frame_bb,text=text_bb) + l_bb.pack(side=tk.LEFT) + global entry_bb + entry_bb=tk.Entry(frame_bb) + entry_bb.pack(side=tk.LEFT) + + selectbandbutton=tk.Button(frame_bb,text='Proceed',command=bandsel) + selectbandbutton.pack(side=tk.BOTTOM) + frame_bb.pack(side=tk.TOP) + bandbox.mainloop() + +def displayinstruction(): + tkMessageBox.showinfo('Help','Click on "Select" button.Then click on a point in the histogram you want to enhance following the second point to specify the piece') + +def displayhist(): + global root + global filename + global band_chosen,bandnum + if(filename != '' and band_chosen != ''): + + hist.showhist2(filename,root,band_chosen) + root.geometry('500x1000') + + else: + tkMessageBox.showerror('Error','Image not selected') +# create a new figure +#figure() +# don't use colors +#gray() +# show contours with origin upper left corner +#contour(im, origin='image') +#axis('equal') +#axis('off') + +frametop=tk.Frame(root,pady=10) +b1=tk.Button(frametop,text='Choose Image',command=openimage) +b1.pack(side=LEFT) + +box1=tk.Entry(frametop,width=35) +box1.pack(side=LEFT) +box1.insert(0,'None') +frametop.pack(side=TOP) + +frame1=tk.Frame(root,pady=10) + +bband=tk.Button(frame1,text='Choose Band',padx=5,command=chooseband) +bband.pack(side=LEFT) +b2=tk.Button(frame1,text='Display Histogram',padx=5,command=displayhist) +b2.pack(side=LEFT) +b3=tk.Button(frame1,text='Instructions',padx=5,command=displayinstruction) +b3.pack(side=LEFT) +frame1.pack(side=TOP) + +root.mainloop() diff --git a/rectest.py b/rectest.py new file mode 100644 index 0000000..ca28b61 --- /dev/null +++ b/rectest.py @@ -0,0 +1,557 @@ + +import Tkinter as tk +from Tkinter import * +from tkMessageBox import * +import ttk +import tkFileDialog +from PIL import Image +import tifwork +import sys +import matplotlib + + +matplotlib.use('TkAgg') +from Tkinter import * +from tkFileDialog import askopenfilename +from numpy import arange, sin, pi +from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg +# implement the default mpl key bindings +from matplotlib.backend_bases import key_press_handler +import matplotlib.pyplot as plt +import matplotlib.image as mpimg +from matplotlib.figure import Figure +from pylab import * + +import tktable + + + + + + +global mastercount +global slavecount +mastercount=0 +slavecount=0 + +abca=[] +defa=[] +clicks=[] + +x=0 +y=0 + +global list_Master +global list_Slave +list_Master=[] +list_Slave=[] +global keyx +keyx=False + +keyyx=False + +global Xmain , Ymain +Xmain = 0 +Ymain = 0 + +def solve(): + global order + global abca, defa + if order==2: + + #def quadsolve(): + print clicks + + arr=clicks[:] + p=np.array([[(arr[0][0])**2,(arr[0][1])**2,arr[0][0], arr[0][1],arr[0][0]*arr[0][1], 1], [(arr[1][0])**2, (arr[1][1])**2,arr[1][0], arr[1][1], arr[1][0] * arr[1][1], 1], [(arr[2][0])**2, (arr[2][1])**2,arr[2][0], arr[2][1], arr[2][0]*arr[2][1], 1], [(arr[3][0])**2,(arr[3][1])**2,arr[3][0], arr[3][1],arr[3][0]*arr[3][1], 1],[(arr[4][0])**2,(arr[4][1])**2,arr[4][0], arr[4][1],arr[4][0]*arr[4][1], 1],[(arr[5][0])**2,(arr[5][1])**2,arr[5][0], arr[5][1],arr[5][0]*arr[5][1], 1]]) + q=np.array([arr[6][0], arr[7][0], arr[8][0], arr[9][0], arr[10][0], arr[11][0]]) + abca=np.linalg.solve(p,q) + + + print abca + + p=np.array([[(arr[0][0])**2,(arr[0][1])**2,arr[0][0], arr[0][1],arr[0][0]*arr[0][1], 1], [(arr[1][0])**2, (arr[1][1])**2,arr[1][0], arr[1][1], arr[1][0] * arr[1][1], 1], [(arr[2][0])**2, (arr[2][1])**2,arr[2][0], arr[2][1], arr[2][0]*arr[2][1], 1], [(arr[3][0])**2,(arr[3][1])**2,arr[3][0], arr[3][1],arr[3][0]*arr[3][1], 1],[(arr[4][0])**2,(arr[4][1])**2,arr[4][0], arr[4][1],arr[4][0]*arr[4][1], 1],[(arr[5][0])**2,(arr[5][1])**2,arr[5][0], arr[5][1],arr[5][0]*arr[5][1], 1]]) + q=np.array([arr[6][1], arr[7][1], arr[8][1], arr[9][1], arr[10][1], arr[11][1]]) + + defa=np.linalg.solve(p,q) + + print defa + if order==1: + #def linsolve(): + + print clicks + arr=clicks[:] + p=np.array([[arr[0][0],arr[0][1], 1], [arr[1][0], arr[1][1], 1], [arr[2][0], arr[2][1], 1]]) + q=np.array([arr[3][0], arr[4][0], arr[5][0]]) + abca=np.linalg.solve(p,q) + + print abca + + p=np.array([[arr[0][0],arr[0][1], 1], [arr[1][0], arr[1][1], 1], [arr[2][0], arr[2][1], 1]]) + q=np.array([arr[3][1], arr[4][1], arr[5][1]]) + defa=np.linalg.solve(p,q) + + print defa + + X1=(arr[0][0])*abca[0]+()() + + if order==3: + #def cubicsolve(): + print clicks + arr=clicks[:] + p=np.array([[(arr[0][0])**3,(arr[0][1])**3,(arr[0][0])**2,(arr[0][1])**2,((arr[0][0])**2)*(arr[0][1]),(arr[0][0])*(arr[0][1])**2,(arr[0][0])(arr[0][1]),arr[0][0],arr[0][1], 1], [(arr[1][0])**3,(arr[1][1])**3,(arr[1][0])**2,(arr[1][1])**2,((arr[1][0])**2)*(arr[1][1]),(arr[1][0])*(arr[1][1])**2,(arr[1][0])*(arr[1][1]),arr[1][0],arr[1][1], 1], [(arr[2][0])**3,(arr[2][1])**3,(arr[2][0])**2,(arr[2][1])**2,((arr[2][0])**2)*(arr[2][1]),(arr[2][0])*(arr[2][1])**2,(arr[2][0])*(arr[2][1]),arr[2][0],arr[2][1], 1],[(arr[3][0])**3,(arr[3][1])**3,(arr[3][0])**2,(arr[3][1])**2,((arr[3][0])**2)*(arr[3][1]),(arr[3][0])*(arr[3][1])**2,(arr[3][0])*(arr[3][1]),arr[3][0],arr[3][1], 1],[(arr[4][0])**3,(arr[4][1])**3,(arr[4][0])**2,(arr[4][1])**2,((arr[4][0])**2)*(arr[4][1]),(arr[4][0])*(arr[4][1])**2,(arr[4][0])*(arr[4][1]),arr[4][0],arr[4][1], 1],[(arr[5][0])**3,(arr[5][1])**3,(arr[5][0])**2,(arr[5][1])**2,((arr[5][0])**2)*(arr[5][1]),(arr[5][0])*(arr[5][1])**2,(arr[5][0])*(arr[5][1]),arr[5][0],arr[5][1], 1],[(arr[6][0])**3,(arr[6][1])**3,(arr[6][0])**2,(arr[6][1])**2,((arr[6][0])**2)*(arr[6][1]),(arr[6][0])*(arr[6][1])**2,(arr[6][0])*(arr[6][1]),arr[6][0],arr[6][1], 1],[(arr[7][0])**3,(arr[7][1])**3,(arr[7][0])**2,(arr[7][1])**2,((arr[7][0])**2)*(arr[7][1]),(arr[7][0])*(arr[7][1])**2,(arr[7][0])*(arr[7][1]),arr[7][0],arr[7][1], 1],[(arr[8][0])**3,(arr[8][1])**3,(arr[8][0])**2,(arr[8][1])**2,((arr[8][0])**2)*(arr[8][1]),(arr[8][0])*(arr[8][1])**2,(arr[8][0])*(arr[8][1]),arr[8][0],arr[8][1], 1],[(arr[9][0])**3,(arr[9][1])**3,(arr[9][0])**2,(arr[9][1])**2,((arr[9][0])**2)*(arr[9][1]),(arr[9][0])*(arr[9][1])**2,(arr[9][0])*(arr[9][1]),arr[9][0],arr[9][1], 1]]) + q=np.array([arr[10][0], arr[11][0], arr[12][0],arr[13][0],arr[14][0],arr[15][0],arr[16][0],arr[17][0],arr[18][0],arr[19][0]]) + abca=np.linalg.solve(p,q) + + print abca + + p=np.array([[(arr[0][0])**3,(arr[0][1])**3,(arr[0][0])**2,(arr[0][1])**2,((arr[0][0])**2)*(arr[0][1]),(arr[0][0])*(arr[0][1])**2,(arr[0][0])(arr[0][1]),arr[0][0],arr[0][1], 1], [(arr[1][0])**3,(arr[1][1])**3,(arr[1][0])**2,(arr[1][1])**2,((arr[1][0])**2)*(arr[1][1]),(arr[1][0])*(arr[1][1])**2,(arr[1][0])*(arr[1][1]),arr[1][0],arr[1][1], 1], [(arr[2][0])**3,(arr[2][1])**3,(arr[2][0])**2,(arr[2][1])**2,((arr[2][0])**2)*(arr[2][1]),(arr[2][0])*(arr[2][1])**2,(arr[2][0])*(arr[2][1]),arr[2][0],arr[2][1], 1],[(arr[3][0])**3,(arr[3][1])**3,(arr[3][0])**2,(arr[3][1])**2,((arr[3][0])**2)*(arr[3][1]),(arr[3][0])*(arr[3][1])**2,(arr[3][0])*(arr[3][1]),arr[3][0],arr[3][1], 1],[(arr[4][0])**3,(arr[4][1])**3,(arr[4][0])**2,(arr[4][1])**2,((arr[4][0])**2)*(arr[4][1]),(arr[4][0])*(arr[4][1])**2,(arr[4][0])*(arr[4][1]),arr[4][0],arr[4][1], 1],[(arr[5][0])**3,(arr[5][1])**3,(arr[5][0])**2,(arr[5][1])**2,((arr[5][0])**2)*(arr[5][1]),(arr[5][0])*(arr[5][1])**2,(arr[5][0])*(arr[5][1]),arr[5][0],arr[5][1], 1],[(arr[6][0])**3,(arr[6][1])**3,(arr[6][0])**2,(arr[6][1])**2,((arr[6][0])**2)*(arr[6][1]),(arr[6][0])*(arr[6][1])**2,(arr[6][0])*(arr[6][1]),arr[6][0],arr[6][1], 1],[(arr[7][0])**3,(arr[7][1])**3,(arr[7][0])**2,(arr[7][1])**2,((arr[7][0])**2)*(arr[7][1]),(arr[7][0])*(arr[7][1])**2,(arr[7][0])*(arr[7][1]),arr[7][0],arr[7][1], 1],[(arr[8][0])**3,(arr[8][1])**3,(arr[8][0])**2,(arr[8][1])**2,((arr[8][0])**2)*(arr[8][1]),(arr[8][0])*(arr[8][1])**2,(arr[8][0])*(arr[8][1]),arr[8][0],arr[8][1], 1],[(arr[9][0])**3,(arr[9][1])**3,(arr[9][0])**2,(arr[9][1])**2,((arr[9][0])**2)*(arr[9][1]),(arr[9][0])*(arr[9][1])**2,(arr[9][0])*(arr[9][1]),arr[9][0],arr[9][1], 1]]) + q=np.array([arr[10][1], arr[11][1], arr[12][1],arr[13][1],arr[14][1],arr[15][1],arr[16][1],arr[17][1],arr[18][1],arr[19][1]]) + defa=np.linalg.solve(p,q) + + print defa + + + + +def valueofkey(): + global keyx + return keyx + +def setkeyx(): + global keyx + keyx=True + +def resetkeyx(): + global keyx + keyx=False + +global keyy +keyy=False + +def valueofkey1(): + global keyy + return keyy + + +keyyx=False + +def valueofkey2(): + global keyyx + return keyyx + +def setkeyy(): + global keyy + keyy=True + +def resetkeyy(): + global keyy + keyy=False + +def resetkeyyx(): + global keyyx + keyyx=False + + + +def valueofkey2(): + global keyyx + return keyyx + +val=[] +def setkeyyx(): + global keyyx + keyyx=True + +def exit(): + root.destroy() + +def viewerwin2(): + global Root4 + global order + global r1 + order=r1.get() + order = int(order) + print 'order=',order + Root4.quit() + Root4.destroy() + + global Root1 + Root1 = tk.Toplevel(root) + Root1.wm_title("Open Master Image") + Root1.geometry("600x600") + + global keyy + resetkeyy() + + frame=tk.Frame(Root1) + frame1=tk.Frame(frame) + frame2=tk.Frame(frame) + button = tk.Button(frame1, width=5, height=2, text='Open',command=open_rectification_Slave) + button.pack(side=tk.LEFT) + button2=tk.Button(frame1, width=5, height=2, text='GO', command=solve) + button2.pack(side=tk.LEFT) + + button3=tk.Button(frame1, width=10, height=2, text='POINT SHOW',command=setkeyyx) + button3.pack(side=tk.LEFT) + frame1.pack(side=tk.LEFT) + frame2.pack(side=tk.LEFT) + frame.pack() + + + +def viewerwin(): + + global Root + Root = tk.Toplevel(root) + Root.wm_title("Open Slave Image") + Root.geometry("600x600") + global keyx + resetkeyx() + + + frame=tk.Frame(Root) + frame1=tk.Frame(frame) + frame2=tk.Frame(frame) + button = tk.Button(frame1, width=5, height=2, text='Open',command=open_rectification_Master) + button.pack() + + button1 = tk.Button(frame2, width=5, height=2, text='Proceed',command=openref) + button1.pack() + + + frame1.pack(side=tk.LEFT) + frame2.pack(side=tk.LEFT) + frame.pack() + + + +def click(): + setkeyx() + + +#slave +def mouse_input_event(event): + global x,y + global order + global clicks + if valueofkey(): + global mastercount + global slavecount + mastercount=mastercount+1 + print 'input pixel loc is ',event.xdata,' ', event.ydata + a.plot(event.xdata, event.ydata,'rx') + if valueofkey2(): + x=event.xdata + y=event.ydata + print x, y + print "\n" + tktable.write_to_table_master(np.round(event.xdata),np.round(event.ydata),mastercount,slavecount) + clicks.append([event.xdata,event.ydata]) + list_Master.append([np.round(event.xdata), np.round(event.ydata)]) + print "List slave \n", list_Master + print "\n" + resetkeyx() + if keyyx: + print "yoyo\n yoyo \n yooy\n" + global Xmain + global Ymain + if order==1: + Xmain=abca[0]*(x)+abca[1]*(y)+abca[2] + Ymain=defa[0]*(x)+defa[1]*(y)+defa[2] + mouse_input_eventx(event) + if order==2: + Xmain=abca[0]*(x)**2+abca[1]*(y)**2+abca[2]*(x)+abca[3]*(y)+abca[4]*(x)*(y)+abca[5] + Ymain=defa[0]*(x)**2+defa[1]*(y)**2+defa[2]*(x)+defa[3]*(y)+defa[4]*(x)*(y)+defa[5] + mouse_input_eventx(event) + if order==3: + Xmain=abca[0]*(x)**3+abca[1]*(y)**3+abca[2]*(x)**2+abca[3]*(y)**2+abca[4]*(x)**2*(y)+abca[5]*(x)*(y)**2+abca[6]*(x)*(y)+abca[7]*(x)+abca[8]*(y)+abca[9] + Ymain=defa[0]*(x)**3+defa[1]*(y)**3+defa[2]*(x)**2+defa[3]*(y)**2+defa[4]*(x)**2*(y)+defa[5]*(x)*(y)**2+defa[6]*(x)*(y)+defa[7]*(x)+defa[8]*(y)+defa[9] + mouse_input_eventx(event) + canvas.show() + + + + +def open_rectification_Master(): + + + + fileName=tkFileDialog.askopenfilename(title='select image to be rectified') + + global f + global a + f = Figure(figsize=(5,4), dpi=100) + a = f.add_subplot(111) + img=mpimg.imread(fileName) + a.imshow(img) + +# a tk.DrawingArea + global canvas + canvas = FigureCanvasTkAgg(f, master=Root) + canvas.show() + + canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1) + + toolbar = NavigationToolbar2TkAgg( canvas, Root ) + toolbar.update() + canvas._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=1) + + def on_key_event(event): + print 'event is ', event + key_press_handler(event, canvas, toolbar) + print "Tkable" + + f.canvas.mpl_connect('button_press_event',mouse_input_event) + f.canvas.mpl_connect('key_press_event', on_key_event) + + def _quit(): + Root.quit() # stops mainloop + Root.destroy() # this is necessary on Windows to pprevent + # Fatal Python Error: PyEval_RestoreThread: NULL tstate + button1 = tk.Button(master=Root, text='Quit', command=_quit) + button1.pack(side=tk.BOTTOM) + button = tk.Button(master=Root, text='select', command=click) + button.pack(side=tk.BOTTOM) + tktable.sample_test() +def clickx(): + setkeyy() + +def mouse_input_eventx(event): + global clicks + global x,y + global Xmain + global Ymain + global mastercount + global slavecount + if valueofkey2(): + + print Xmain,"\n" , Ymain + ax.plot(Xmain, Ymain,'rx') + print 'fyfdflih' + tktable.write_to_table_master(np.round(Xmain),np.round(Ymain),mastercount,slavecount) + resetkeyyx() + if valueofkey1(): + + slavecount=slavecount+1 + print 'input pixel loc is ',event.xdata,' ', event.ydata + ax.plot(event.xdata, event.ydata,'rx') + tktable.write_to_table_slave(np.round(event.xdata),np.round(event.ydata),slavecount,mastercount) + clicks.append([event.xdata,event.ydata]) + list_Slave.append([np.round(event.xdata), np.round(event.ydata)]) + print list_Slave + resetkeyy() + canvasx.show() + +def key_input_eventx(event): + if valueofkey1(): + global mastercount + global slavecount + slavecount=slavecount+1 + print 'input pixel loc is ',event.xdata,' ', event.ydata + ax.plot(event.xdata, event.ydata,'bx') + tktable.write_to_table_slave(np.round(event.xdata),np.round(event.ydata),slavecount,mastercount) + list_Slave.append([np.round(event.xdata), np.round(event.ydata)]) + print list_Slave + resetkeyy() + + canvasx.show() +def open_rectification_Slave(): + + fileName=tkFileDialog.askopenfilename(title='select reference image') + + global fx + global ax + fx = Figure(figsize=(5,4), dpi=100) + ax = fx.add_subplot(111) + img=mpimg.imread(fileName) + ax.imshow(img) + print 'hi' +# a tk.DrawingArea + global canvasx + global x,y + + canvasx = FigureCanvasTkAgg(fx, master=Root1) + canvasx.show() + + canvasx.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1) + + toolbar = NavigationToolbar2TkAgg( canvasx, Root1 ) + toolbar.update() + canvasx._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=1) + + def on_key_event(event): + print('you pressed %s'%event.key) + key_press_handler(event, canvasx, toolbar) + + fx.canvas.mpl_connect('button_press_event',mouse_input_eventx) + fx.canvas.mpl_connect('key_press_event', on_key_event) + def _quitx(): + Root1.quit() # stops mainloop + Root1.destroy() # this is necessary on Windows to pprevent + # Fatal Python Error: PyEval_RestoreThread: NULL tstate + button1 = tk.Button(master=Root1, text='Quit', command=_quitx) + button1.pack(side=tk.BOTTOM) + button = tk.Button(master=Root1, text='select', command=clickx) + button.pack(side=tk.BOTTOM) + + + + +def openref(): + global poly + global r1 + """selection=" " + #fileName=tkFileDialog.askopenfilename() + if(fileName == ''): + pass + else: + print(fileName) + im=(tifwork.openTIF(fileName)) + def sel(): + selection =str(var.get()) + print selection + + def printEntry(): + print selection """ + + global Root4 + Root4=tk.Tk() + Root4.title('Choose Polynomial order') + Root4.geometry('200x200') + var = IntVar() + r1=Spinbox(Root4,from_=1,to=3) + r1.pack() + + print poly + buttona = tk.Button(master=Root4, text='GO', command=viewerwin2) + buttona.pack(side=tk.BOTTOM) + """R1 = Radiobutton(a, text="Order 0", variable=var, value=0) + R1.pack( anchor = W ) + + R2 = Radiobutton(a, text="Order 1", variable=var, value=1) + R2.pack( anchor = W ) + + R3 = Radiobutton(a, text="Order 2", variable=var, value=2) + R3.pack( anchor = W) + + label = Label(a) + label.pack() + + + L1 = Label(a, text="other") + L1.pack( side = LEFT) + E1 = Entry(a, bd =5) +s + E1.pack(side = RIGHT) + selection=E1.get()""" + + Root4.mainloop() + + ''' + image=Image.open(im) + image1=ImageTk.PhotoImage(image) + imagesprite=c.create_image(500,500,image=image1) + return im + ''' + + + + + +def rgbselect(): + + fileName=tkFileDialog.askopenfilename() + if(fileName == ''): + pass + else: + print(fileName) + dataset=(tifwork.openTIF(fileName)) + + w=tk.Tk() + + def bandPrint(): + if(not(opt1.get() and opt2.get() and opt3.get())): + + showerror("Error", "All bands not selected") + elif(opt1.get()==opt2.get() or opt1.get()==opt3.get() or opt2.get()==opt3.get()): + showerror("Error", "Two same bands selected") + else: + bandArr = tifwork.getBand(dataset,bands,bandArray) + tifwork.selectBand(bandArr,rows,cols,opt1.get(),opt2.get(),opt3.get()) + + frame4 = tk.Frame(w) +# frame4.grid() + frame2=tk.Frame(frame4) +# frame2.grid() + frame3=tk.Frame(frame4) +# frame3.grid() + frame5 = tk.Frame(w) +# frame5.grid() + w.title("Band Selection") + (cols,rows,bands,bandArray) = tifwork.detailsTIF(dataset) + + + optionList=[] + for k in range(1, bands+1): + optionList.append(k) + + x1=tk.Label(frame2, text="Red") + x1.pack(side=tk.TOP, pady = 5 , padx = 5 ) + opt1= ttk.Combobox(frame3,values=optionList, width=5) + opt1.pack(side = tk.TOP , pady = 5,padx = 5 ) + + x2=tk.Label(frame2, text="Blue") + x2.pack(side = tk.TOP , pady = 5 , padx = 5 ) + opt2= ttk.Combobox(frame3 , values=optionList, width=5) + opt2.pack(side = tk.TOP , pady = 5 , padx = 5 ) + + x3=tk.Label(frame2, text="Green") + x3.pack(side = tk.TOP , pady = 5 , padx = 5 ) + opt3= ttk.Combobox(frame3, values=optionList, width=5) + opt3.pack(side = tk.TOP , pady = 5 , padx = 5 ) + + frame2.pack(side=tk.LEFT, pady = 5 , padx = 5 ) + frame3.pack(side=tk.LEFT, pady = 5 , padx = 5 ) + frame4.pack(side= tk.TOP, pady = 5 , padx = 5 ) + + button = tk.Button(frame5, width=10, text="Show", command=bandPrint) + button.pack(side = tk.TOP , pady = 5 , padx = 5 ) + frame5.pack(side=tk.TOP , pady = 5 , padx = 5 ) + +#opens the root window +root=tk.Tk() + +root.title("Image Processing") + +frame1 = tk.Frame(root, width=800) + +#to display the frame +frame1.pack() + +#keeps only the frame +root.overrideredirect(0) +root.resizable(0,0) + +photo3 = tk.PhotoImage(file="close.gif") +button3 = tk.Button(frame1, width=100, height=100, image=photo3) +button3.pack(side=tk.LEFT, padx=2, pady=2) +button3.image = photo3 + + +photo2 = tk.PhotoImage(file="1.gif") +button2 = tk.Button(frame1, width=100, height=100, image=photo2, command=rgbselect) +button2.pack(side=tk.LEFT, padx=2, pady=2) +button2.image = photo2 + +button5 = tk.Button(frame1, width=20, height=6, text='Geometric correction',justify=tk.LEFT,command=viewerwin) +button5.pack(side=tk.LEFT, padx=2, pady=2) + + +photo1 = tk.PhotoImage(file="3.gif") +button1 = tk.Button(frame1, width=100, height=100, image=photo1, command=exit) +button1.pack(side=tk.LEFT, padx=2, pady=2) +button1.image = photo1 + +root.mainloop() + diff --git a/rectification.gif b/rectification.gif new file mode 100644 index 0000000..f8317b5 Binary files /dev/null and b/rectification.gif differ diff --git a/rectification_copy.py b/rectification_copy.py new file mode 100644 index 0000000..69eaaec --- /dev/null +++ b/rectification_copy.py @@ -0,0 +1,553 @@ + +import Tkinter as tk +from Tkinter import * +from tkMessageBox import * +import ttk +import tkFileDialog +from PIL import Image +import tifwork +import sys +import matplotlib + + +matplotlib.use('TkAgg') +from Tkinter import * +from tkFileDialog import askopenfilename +from numpy import arange, sin, pi +from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg +# implement the default mpl key bindings +from matplotlib.backend_bases import key_press_handler +import matplotlib.pyplot as plt +import matplotlib.image as mpimg +from matplotlib.figure import Figure +from pylab import * +import Image, ImageTk +import tktable + + + +#initializing the clicks in master and slave +mastercount=0 +slavecount=0 + +abca=[] +defa=[] +clicks=[] + +x=0 +y=0 + + +list_Master=[] +list_Slave=[] +global keyx +keyx=False + +keyyx=False + +global Xmain , Ymain +Xmain = 0 +Ymain = 0 + +#function to solve the constant coefficients +def solve(): + global order + global abca, defa #single dimension array to store the constant coefficients + #algorithm to solve 2nd order transformation + if order==2: + + #def quadsolve(): + print clicks + + arr=clicks[:] + p=np.array([[(arr[0][0])**2,(arr[0][1])**2,arr[0][0], arr[0][1],arr[0][0]*arr[0][1], 1], [(arr[1][0])**2, (arr[1][1])**2,arr[1][0], arr[1][1], arr[1][0] * arr[1][1], 1], [(arr[2][0])**2, (arr[2][1])**2,arr[2][0], arr[2][1], arr[2][0]*arr[2][1], 1], [(arr[3][0])**2,(arr[3][1])**2,arr[3][0], arr[3][1],arr[3][0]*arr[3][1], 1],[(arr[4][0])**2,(arr[4][1])**2,arr[4][0], arr[4][1],arr[4][0]*arr[4][1], 1],[(arr[5][0])**2,(arr[5][1])**2,arr[5][0], arr[5][1],arr[5][0]*arr[5][1], 1]]) + q=np.array([arr[6][0], arr[7][0], arr[8][0], arr[9][0], arr[10][0], arr[11][0]]) + abca=np.linalg.solve(p,q) + + + print abca + + p=np.array([[(arr[0][0])**2,(arr[0][1])**2,arr[0][0], arr[0][1],arr[0][0]*arr[0][1], 1], [(arr[1][0])**2, (arr[1][1])**2,arr[1][0], arr[1][1], arr[1][0] * arr[1][1], 1], [(arr[2][0])**2, (arr[2][1])**2,arr[2][0], arr[2][1], arr[2][0]*arr[2][1], 1], [(arr[3][0])**2,(arr[3][1])**2,arr[3][0], arr[3][1],arr[3][0]*arr[3][1], 1],[(arr[4][0])**2,(arr[4][1])**2,arr[4][0], arr[4][1],arr[4][0]*arr[4][1], 1],[(arr[5][0])**2,(arr[5][1])**2,arr[5][0], arr[5][1],arr[5][0]*arr[5][1], 1]]) + q=np.array([arr[6][1], arr[7][1], arr[8][1], arr[9][1], arr[10][1], arr[11][1]]) + + defa=np.linalg.solve(p,q) + + print defa + #algorithm to solve 1st order transformation + if order==1: + #def linsolve(): + + print clicks + arr=clicks[:] + p=np.array([[arr[0][0],arr[0][1], 1], [arr[1][0], arr[1][1], 1], [arr[2][0], arr[2][1], 1]]) + q=np.array([arr[3][0], arr[4][0], arr[5][0]]) + abca=np.linalg.solve(p,q) + + print abca + + p=np.array([[arr[0][0],arr[0][1], 1], [arr[1][0], arr[1][1], 1], [arr[2][0], arr[2][1], 1]]) + q=np.array([arr[3][1], arr[4][1], arr[5][1]]) + defa=np.linalg.solve(p,q) + + print defa + + X1=(arr[0][0])*abca[0]+()() + #algorithm to solve 3rd order transformation + if order==3: + #def cubicsolve(): + print clicks + arr=clicks[:] + p=np.array([[(arr[0][0])**3,(arr[0][1])**3,(arr[0][0])**2,(arr[0][1])**2,((arr[0][0])**2)*(arr[0][1]),(arr[0][0])*(arr[0][1])**2,(arr[0][0])(arr[0][1]),arr[0][0],arr[0][1], 1], [(arr[1][0])**3,(arr[1][1])**3,(arr[1][0])**2,(arr[1][1])**2,((arr[1][0])**2)*(arr[1][1]),(arr[1][0])*(arr[1][1])**2,(arr[1][0])*(arr[1][1]),arr[1][0],arr[1][1], 1], [(arr[2][0])**3,(arr[2][1])**3,(arr[2][0])**2,(arr[2][1])**2,((arr[2][0])**2)*(arr[2][1]),(arr[2][0])*(arr[2][1])**2,(arr[2][0])*(arr[2][1]),arr[2][0],arr[2][1], 1],[(arr[3][0])**3,(arr[3][1])**3,(arr[3][0])**2,(arr[3][1])**2,((arr[3][0])**2)*(arr[3][1]),(arr[3][0])*(arr[3][1])**2,(arr[3][0])*(arr[3][1]),arr[3][0],arr[3][1], 1],[(arr[4][0])**3,(arr[4][1])**3,(arr[4][0])**2,(arr[4][1])**2,((arr[4][0])**2)*(arr[4][1]),(arr[4][0])*(arr[4][1])**2,(arr[4][0])*(arr[4][1]),arr[4][0],arr[4][1], 1],[(arr[5][0])**3,(arr[5][1])**3,(arr[5][0])**2,(arr[5][1])**2,((arr[5][0])**2)*(arr[5][1]),(arr[5][0])*(arr[5][1])**2,(arr[5][0])*(arr[5][1]),arr[5][0],arr[5][1], 1],[(arr[6][0])**3,(arr[6][1])**3,(arr[6][0])**2,(arr[6][1])**2,((arr[6][0])**2)*(arr[6][1]),(arr[6][0])*(arr[6][1])**2,(arr[6][0])*(arr[6][1]),arr[6][0],arr[6][1], 1],[(arr[7][0])**3,(arr[7][1])**3,(arr[7][0])**2,(arr[7][1])**2,((arr[7][0])**2)*(arr[7][1]),(arr[7][0])*(arr[7][1])**2,(arr[7][0])*(arr[7][1]),arr[7][0],arr[7][1], 1],[(arr[8][0])**3,(arr[8][1])**3,(arr[8][0])**2,(arr[8][1])**2,((arr[8][0])**2)*(arr[8][1]),(arr[8][0])*(arr[8][1])**2,(arr[8][0])*(arr[8][1]),arr[8][0],arr[8][1], 1],[(arr[9][0])**3,(arr[9][1])**3,(arr[9][0])**2,(arr[9][1])**2,((arr[9][0])**2)*(arr[9][1]),(arr[9][0])*(arr[9][1])**2,(arr[9][0])*(arr[9][1]),arr[9][0],arr[9][1], 1]]) + q=np.array([arr[10][0], arr[11][0], arr[12][0],arr[13][0],arr[14][0],arr[15][0],arr[16][0],arr[17][0],arr[18][0],arr[19][0]]) + abca=np.linalg.solve(p,q) + + print abca + + p=np.array([[(arr[0][0])**3,(arr[0][1])**3,(arr[0][0])**2,(arr[0][1])**2,((arr[0][0])**2)*(arr[0][1]),(arr[0][0])*(arr[0][1])**2,(arr[0][0])(arr[0][1]),arr[0][0],arr[0][1], 1], [(arr[1][0])**3,(arr[1][1])**3,(arr[1][0])**2,(arr[1][1])**2,((arr[1][0])**2)*(arr[1][1]),(arr[1][0])*(arr[1][1])**2,(arr[1][0])*(arr[1][1]),arr[1][0],arr[1][1], 1], [(arr[2][0])**3,(arr[2][1])**3,(arr[2][0])**2,(arr[2][1])**2,((arr[2][0])**2)*(arr[2][1]),(arr[2][0])*(arr[2][1])**2,(arr[2][0])*(arr[2][1]),arr[2][0],arr[2][1], 1],[(arr[3][0])**3,(arr[3][1])**3,(arr[3][0])**2,(arr[3][1])**2,((arr[3][0])**2)*(arr[3][1]),(arr[3][0])*(arr[3][1])**2,(arr[3][0])*(arr[3][1]),arr[3][0],arr[3][1], 1],[(arr[4][0])**3,(arr[4][1])**3,(arr[4][0])**2,(arr[4][1])**2,((arr[4][0])**2)*(arr[4][1]),(arr[4][0])*(arr[4][1])**2,(arr[4][0])*(arr[4][1]),arr[4][0],arr[4][1], 1],[(arr[5][0])**3,(arr[5][1])**3,(arr[5][0])**2,(arr[5][1])**2,((arr[5][0])**2)*(arr[5][1]),(arr[5][0])*(arr[5][1])**2,(arr[5][0])*(arr[5][1]),arr[5][0],arr[5][1], 1],[(arr[6][0])**3,(arr[6][1])**3,(arr[6][0])**2,(arr[6][1])**2,((arr[6][0])**2)*(arr[6][1]),(arr[6][0])*(arr[6][1])**2,(arr[6][0])*(arr[6][1]),arr[6][0],arr[6][1], 1],[(arr[7][0])**3,(arr[7][1])**3,(arr[7][0])**2,(arr[7][1])**2,((arr[7][0])**2)*(arr[7][1]),(arr[7][0])*(arr[7][1])**2,(arr[7][0])*(arr[7][1]),arr[7][0],arr[7][1], 1],[(arr[8][0])**3,(arr[8][1])**3,(arr[8][0])**2,(arr[8][1])**2,((arr[8][0])**2)*(arr[8][1]),(arr[8][0])*(arr[8][1])**2,(arr[8][0])*(arr[8][1]),arr[8][0],arr[8][1], 1],[(arr[9][0])**3,(arr[9][1])**3,(arr[9][0])**2,(arr[9][1])**2,((arr[9][0])**2)*(arr[9][1]),(arr[9][0])*(arr[9][1])**2,(arr[9][0])*(arr[9][1]),arr[9][0],arr[9][1], 1]]) + q=np.array([arr[10][1], arr[11][1], arr[12][1],arr[13][1],arr[14][1],arr[15][1],arr[16][1],arr[17][1],arr[18][1],arr[19][1]]) + defa=np.linalg.solve(p,q) + + print defa + + + +#function returning the value of keyx (used in slave image select points) +def valueofkey(): + global keyx + return keyx +#function to set keyx +def setkeyx(): + global keyx + keyx=True +#function to reset keyx +def resetkeyx(): + global keyx + keyx=False + +global keyy +keyy=False +#function to return the value of keyy(used in master select points) +def valueofkey1(): + global keyy + return keyy + + +keyyx=False +#function to return the value of keyyx(used in 'point show' button) +def valueofkey2(): + global keyyx + return keyyx +#function to set keyy +def setkeyy(): + global keyy + keyy=True +#function to reset keyy +def resetkeyy(): + global keyy + keyy=False +#function to reset keyyx +def resetkeyyx(): + global keyyx + keyyx=False + + + + +val=[] +#function to set keyyx +def setkeyyx(): + global keyyx + keyyx=True +#functio +def exit(): + root.destroy() + +def viewerwin2(): + global Root4 + global order + global r1 + order=r1.get() + order = int(order) + print 'order=',order + Root4.quit() + Root4.destroy() + + global Root1 + Root1 = tk.Toplevel(root) + Root1.wm_title("Open Master Image") + Root1.geometry("600x600") + + global keyy + resetkeyy() + + frame=tk.Frame(Root1) + frame1=tk.Frame(frame) + frame2=tk.Frame(frame) + button = tk.Button(frame1, width=5, height=2, text='Open',command=open_rectification_Slave) + button.pack(side=tk.LEFT) + button2=tk.Button(frame1, width=5, height=2, text='GO', command=solve) + button2.pack(side=tk.LEFT) + + button3=tk.Button(frame1, width=10, height=2, text='POINT SHOW',command=setkeyyx) + button3.pack(side=tk.LEFT) + frame1.pack(side=tk.LEFT) + frame2.pack(side=tk.LEFT) + frame.pack() + + + +def viewerwin(): + + global Root + Root = tk.Toplevel(root) + Root.wm_title("Open Slave Image") + Root.geometry("600x600") + global keyx + resetkeyx() + + + frame=tk.Frame(Root) + frame1=tk.Frame(frame) + frame2=tk.Frame(frame) + button = tk.Button(frame1, width=5, height=2, text='Open',command=open_rectification_Master) + button.pack() + + button1 = tk.Button(frame2, width=5, height=2, text='Proceed',command=openref) + button1.pack() + + + frame1.pack(side=tk.LEFT) + frame2.pack(side=tk.LEFT) + frame.pack() + + + +def click(): + setkeyx() + + +#slave +def mouse_input_event(event): + global x,y + global order + global clicks + if valueofkey(): + global mastercount + global slavecount + mastercount=mastercount+1 + print 'input pixel loc is ',event.xdata,' ', event.ydata + a.plot(event.xdata, event.ydata,'rx') + if valueofkey2(): + x=event.xdata + y=event.ydata + print x, y + print "\n" + tktable.write_to_table_master(np.round(event.xdata),np.round(event.ydata),mastercount,slavecount) + clicks.append([event.xdata,event.ydata]) + list_Master.append([np.round(event.xdata), np.round(event.ydata)]) + print "List slave \n", list_Master + print "\n" + resetkeyx() + if keyyx: + print "yoyo\n yoyo \n yooy\n" + global Xmain + global Ymain + if order==1: + Xmain=abca[0]*(x)+abca[1]*(y)+abca[2] + Ymain=defa[0]*(x)+defa[1]*(y)+defa[2] + mouse_input_eventx(event) + if order==2: + Xmain=abca[0]*(x)**2+abca[1]*(y)**2+abca[2]*(x)+abca[3]*(y)+abca[4]*(x)*(y)+abca[5] + Ymain=defa[0]*(x)**2+defa[1]*(y)**2+defa[2]*(x)+defa[3]*(y)+defa[4]*(x)*(y)+defa[5] + mouse_input_eventx(event) + if order==3: + Xmain=abca[0]*(x)**3+abca[1]*(y)**3+abca[2]*(x)**2+abca[3]*(y)**2+abca[4]*(x)**2*(y)+abca[5]*(x)*(y)**2+abca[6]*(x)*(y)+abca[7]*(x)+abca[8]*(y)+abca[9] + Ymain=defa[0]*(x)**3+defa[1]*(y)**3+defa[2]*(x)**2+defa[3]*(y)**2+defa[4]*(x)**2*(y)+defa[5]*(x)*(y)**2+defa[6]*(x)*(y)+defa[7]*(x)+defa[8]*(y)+defa[9] + mouse_input_eventx(event) + canvas.show() + + + + +def open_rectification_Master(): + + + + fileName=tkFileDialog.askopenfilename(title='select image to be rectified') + + global f + global a + f = Figure(figsize=(5,4), dpi=100) + a = f.add_subplot(111) + img=mpimg.imread(fileName) + a.imshow(img) + +# a tk.DrawingArea + global canvas + canvas = FigureCanvasTkAgg(f, master=Root) + canvas.show() + + canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1) + + toolbar = NavigationToolbar2TkAgg( canvas, Root ) + toolbar.update() + canvas._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=1) + + def on_key_event(event): + print 'event is ', event + key_press_handler(event, canvas, toolbar) + print "Tkable" + + f.canvas.mpl_connect('button_press_event',mouse_input_event) + f.canvas.mpl_connect('key_press_event', on_key_event) + + def _quit(): + Root.quit() # stops mainloop + Root.destroy() # this is necessary on Windows to pprevent + # Fatal Python Error: PyEval_RestoreThread: NULL tstate + button1 = tk.Button(master=Root, text='Quit', command=_quit) + button1.pack(side=tk.BOTTOM) + button = tk.Button(master=Root, text='select', command=click) + button.pack(side=tk.BOTTOM) + tktable.sample_test() +def clickx(): + setkeyy() + +def mouse_input_eventx(event): + global clicks + global x,y + global Xmain + global Ymain + global mastercount + global slavecount + if valueofkey2(): + + print Xmain,"\n" , Ymain + ax.plot(Xmain, Ymain,'rx') + print 'fyfdflih' + tktable.write_to_table_master(np.round(Xmain),np.round(Ymain),mastercount,slavecount) + resetkeyyx() + if valueofkey1(): + + slavecount=slavecount+1 + print 'input pixel loc is ',event.xdata,' ', event.ydata + ax.plot(event.xdata, event.ydata,'rx') + tktable.write_to_table_slave(np.round(event.xdata),np.round(event.ydata),slavecount,mastercount) + clicks.append([event.xdata,event.ydata]) + list_Slave.append([np.round(event.xdata), np.round(event.ydata)]) + print list_Slave + resetkeyy() + canvasx.show() + +def key_input_eventx(event): + if valueofkey1(): + global mastercount + global slavecount + slavecount=slavecount+1 + print 'input pixel loc is ',event.xdata,' ', event.ydata + ax.plot(event.xdata, event.ydata,'bx') + tktable.write_to_table_slave(np.round(event.xdata),np.round(event.ydata),slavecount,mastercount) + list_Slave.append([np.round(event.xdata), np.round(event.ydata)]) + print list_Slave + resetkeyy() + + canvasx.show() +def open_rectification_Slave(): + + fileName=tkFileDialog.askopenfilename(title='select reference image') + + global fx + global ax + fx = Figure(figsize=(5,4), dpi=100) + ax = fx.add_subplot(111) + img=mpimg.imread(fileName) + ax.imshow(img) + print 'hi' +# a tk.DrawingArea + global canvasx + global x,y + + canvasx = FigureCanvasTkAgg(fx, master=Root1) + canvasx.show() + + canvasx.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1) + + toolbar = NavigationToolbar2TkAgg( canvasx, Root1 ) + toolbar.update() + canvasx._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=1) + + def on_key_event(event): + print('you pressed %s'%event.key) + key_press_handler(event, canvasx, toolbar) + + fx.canvas.mpl_connect('button_press_event',mouse_input_eventx) + fx.canvas.mpl_connect('key_press_event', on_key_event) + def _quitx(): + Root1.quit() # stops mainloop + Root1.destroy() # this is necessary on Windows to pprevent + # Fatal Python Error: PyEval_RestoreThread: NULL tstate + button1 = tk.Button(master=Root1, text='Quit', command=_quitx) + button1.pack(side=tk.BOTTOM) + button = tk.Button(master=Root1, text='select', command=clickx) + button.pack(side=tk.BOTTOM) + + + + +def openref(): + global poly + global r1 + """selection=" " + #fileName=tkFileDialog.askopenfilename() + if(fileName == ''): + pass + else: + print(fileName) + im=(tifwork.openTIF(fileName)) + def sel(): + selection =str(var.get()) + print selection + + def printEntry(): + print selection """ + + global Root4 + Root4=tk.Tk() + Root4.title('Choose Polynomial order') + Root4.geometry('200x200') + var = IntVar() + r1=Spinbox(Root4,from_=1,to=3) + r1.pack() + + print poly + buttona = tk.Button(master=Root4, text='GO', command=viewerwin2) + buttona.pack(side=tk.BOTTOM) + """R1 = Radiobutton(a, text="Order 0", variable=var, value=0) + R1.pack( anchor = W ) + + R2 = Radiobutton(a, text="Order 1", variable=var, value=1) + R2.pack( anchor = W ) + + R3 = Radiobutton(a, text="Order 2", variable=var, value=2) + R3.pack( anchor = W) + + label = Label(a) + label.pack() + + + L1 = Label(a, text="other") + L1.pack( side = LEFT) + E1 = Entry(a, bd =5) +s + E1.pack(side = RIGHT) + selection=E1.get()""" + + Root4.mainloop() + + ''' + image=Image.open(im) + image1=ImageTk.PhotoImage(image) + imagesprite=c.create_image(500,500,image=image1) + return im + ''' + + + + + +def rgbselect(): + + fileName=tkFileDialog.askopenfilename() + if(fileName == ''): + pass + else: + print(fileName) + dataset=(tifwork.openTIF(fileName)) + + w=tk.Tk() + + def bandPrint(): + if(not(opt1.get() and opt2.get() and opt3.get())): + + showerror("Error", "All bands not selected") + elif(opt1.get()==opt2.get() or opt1.get()==opt3.get() or opt2.get()==opt3.get()): + showerror("Error", "Two same bands selected") + else: + bandArr = tifwork.getBand(dataset,bands,bandArray) + tifwork.selectBand(bandArr,rows,cols,opt1.get(),opt2.get(),opt3.get()) + + frame4 = tk.Frame(w) +# frame4.grid() + frame2=tk.Frame(frame4) +# frame2.grid() + frame3=tk.Frame(frame4) +# frame3.grid() + frame5 = tk.Frame(w) +# frame5.grid() + w.title("Band Selection") + (cols,rows,bands,bandArray) = tifwork.detailsTIF(dataset) + + + optionList=[] + for k in range(1, bands+1): + optionList.append(k) + + x1=tk.Label(frame2, text="Red") + x1.pack(side=tk.TOP, pady = 5 , padx = 5 ) + opt1= ttk.Combobox(frame3,values=optionList, width=5) + opt1.pack(side = tk.TOP , pady = 5,padx = 5 ) + + x2=tk.Label(frame2, text="Blue") + x2.pack(side = tk.TOP , pady = 5 , padx = 5 ) + opt2= ttk.Combobox(frame3 , values=optionList, width=5) + opt2.pack(side = tk.TOP , pady = 5 , padx = 5 ) + + x3=tk.Label(frame2, text="Green") + x3.pack(side = tk.TOP , pady = 5 , padx = 5 ) + opt3= ttk.Combobox(frame3, values=optionList, width=5) + opt3.pack(side = tk.TOP , pady = 5 , padx = 5 ) + + frame2.pack(side=tk.LEFT, pady = 5 , padx = 5 ) + frame3.pack(side=tk.LEFT, pady = 5 , padx = 5 ) + frame4.pack(side= tk.TOP, pady = 5 , padx = 5 ) + + button = tk.Button(frame5, width=10, text="Show", command=bandPrint) + button.pack(side = tk.TOP , pady = 5 , padx = 5 ) + frame5.pack(side=tk.TOP , pady = 5 , padx = 5 ) + +#opens the root window +root=tk.Tk() + +root.title("Image Processing") + +frame1 = tk.Frame(root, width=800) + +#to display the frame +frame1.pack() + +#keeps only the frame +root.overrideredirect(0) +root.resizable(0,0) + +photo3 = tk.PhotoImage(file="2.gif") +button3 = tk.Button(frame1, width=100, height=100, image=photo3) +button3.pack(side=tk.LEFT, padx=2, pady=2) +button3.image = photo3 + + +photo2 = tk.PhotoImage(file="1.gif") +button2 = tk.Button(frame1, width=100, height=100, image=photo2, command=rgbselect) +button2.pack(side=tk.LEFT, padx=2, pady=2) +button2.image = photo2 + +button5 = tk.Button(frame1, width=20, height=6, text='Geometric correction',justify=tk.LEFT,command=viewerwin) +button5.pack(side=tk.LEFT, padx=2, pady=2) + + +photo1 = tk.PhotoImage(file="3.gif") +button1 = tk.Button(frame1, width=100, height=100, image=photo1, command=exit) +button1.pack(side=tk.LEFT, padx=2, pady=2) +button1.image = photo1 + +root.mainloop() + diff --git a/retable.py b/retable.py new file mode 100644 index 0000000..9356445 --- /dev/null +++ b/retable.py @@ -0,0 +1,440 @@ + +import Tkinter as tk +from Tkinter import * +from tkMessageBox import * +import ttk +import tkFileDialog +from PIL import Image +import tifwork +import sys +import matplotlib + + +matplotlib.use('TkAgg') +from Tkinter import * +from tkFileDialog import askopenfilename +from numpy import arange, sin, pi +from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg +# implement the default mpl key bindings +from matplotlib.backend_bases import key_press_handler +import matplotlib.pyplot as plt +import matplotlib.image as mpimg +from matplotlib.figure import Figure +from pylab import * +#import Image, ImageTk +import tktable + + + + + + +global mastercount +global slavecount +mastercount=0 +slavecount=0 + + +global list_Master +global list_Slave +list_Master=[] +list_Slave=[] +global keyx +keyx=False +def valueofkey(): + global keyx + return keyx + +def setkeyx(): + global keyx + keyx=True + +def resetkeyx(): + global keyx + keyx=False + +global keyy +keyy=False +def valueofkey1(): + global keyy + return keyy + +def setkeyy(): + global keyy + keyy=True + +def resetkeyy(): + global keyy + keyy=False + +val=[] + +def exit(): + root.destroy() + + + +def imdisplay(filename): + + filename = '2.gif' + + global Root1 + Root1 = tk.Toplevel(root) + Root1.wm_title("Image Display") + Root1.geometry("600x600") + + global keyy + resetkeyy() + + openImFile(filename) + + +def openImFile(filename): + + + global fx + global ax + fx = Figure(figsize=(5,4), dpi=100) + ax = fx.add_subplot(111) + img=mpimg.imread(filename) + ax.imshow(img) + +# a tk.DrawingArea + global canvasx + canvasx = FigureCanvasTkAgg(fx, master=Root1) + canvasx.show() + + canvasx.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1) + + toolbar = NavigationToolbar2TkAgg( canvasx, Root1 ) + toolbar.update() + canvasx._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=1) + + def on_key_event(event): + print('you pressed %s'%event.key) + key_press_handler(event, canvasx, toolbar) + + + fx.canvas.mpl_connect('button_press_event',mouse_input_eventx) + fx.canvas.mpl_connect('key_press_event', on_key_event) + + def _quitx(): + Root1.quit() # stops mainloop + Root1.destroy() # this is necessary on Windows to pprevent + # Fatal Python Error: PyEval_RestoreThread: NULL tstate + button1 = tk.Button(master=Root1, text='Quit', command=_quitx) + button1.pack(side=tk.BOTTOM) + button = tk.Button(master=Root1, text='select', command=clickx) + button.pack(side=tk.BOTTOM) + + +def viewerwin2(): + global Root4 + Root4.quit() + Root4.destroy() + + global Root1 + Root1 = tk.Toplevel(root) + Root1.wm_title("Open Master Image") + Root1.geometry("600x600") + + global keyy + resetkeyy() + + frame=tk.Frame(Root1) + frame1=tk.Frame(frame) + frame2=tk.Frame(frame) + button = tk.Button(frame1, width=5, height=2, text='Open',command=open_rectification_Slave) + button.pack() + frame1.pack(side=tk.LEFT) + frame2.pack(side=tk.LEFT) + frame.pack() + + + +def viewerwin(): + + global Root + Root = tk.Toplevel(root) + Root.wm_title("Open Slave Image") + Root.geometry("600x600") + global keyx + resetkeyx() + + + frame=tk.Frame(Root) + frame1=tk.Frame(frame) + frame2=tk.Frame(frame) + button = tk.Button(frame1, width=5, height=2, text='Open',command=open_rectification_Master) + button.pack() + + button1 = tk.Button(frame2, width=5, height=2, text='Proceed',command=openref) + button1.pack() + + + frame1.pack(side=tk.LEFT) + frame2.pack(side=tk.LEFT) + frame.pack() + + + +def click(): + setkeyx() + + +def mouse_input_event(event): + if valueofkey(): + global mastercount + global slavecount + mastercount=mastercount+1 + print 'input pixel loc is ',event.xdata,' ', event.ydata + a.plot(event.xdata, event.ydata,'b.') + tktable.write_to_table_master(np.round(event.xdata),np.round(event.ydata),mastercount,slavecount) + list_Master.append([np.round(event.xdata), np.round(event.ydata)]) + print list_Master + resetkeyx() + canvas.show() + + + + +def open_rectification_Master(): + + + + fileName=tkFileDialog.askopenfilename(title='select image to be rectified') + + global f + global a + f = Figure(figsize=(5,4), dpi=100) + a = f.add_subplot(111) + img=mpimg.imread(fileName) + a.imshow(img) + +# a tk.DrawingArea + global canvas + canvas = FigureCanvasTkAgg(f, master=Root) + canvas.show() + + canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1) + + toolbar = NavigationToolbar2TkAgg( canvas, Root ) + toolbar.update() + canvas._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=1) + + def on_key_event(event): + print('you pressed %s'%event.key) + key_press_handler(event, canvas, toolbar) + print "Tkable" + + f.canvas.mpl_connect('button_press_event',mouse_input_event) + f.canvas.mpl_connect('key_press_event', on_key_event) + + def _quit(): + Root.quit() # stops mainloop + Root.destroy() # this is necessary on Windows to pprevent + # Fatal Python Error: PyEval_RestoreThread: NULL tstate + button1 = tk.Button(master=Root, text='Quit', command=_quit) + button1.pack(side=tk.BOTTOM) + button = tk.Button(master=Root, text='select', command=click) + button.pack(side=tk.BOTTOM) + tktable.sample_test() +def clickx(): + setkeyy() + +def mouse_input_eventx(event): + if valueofkey1(): + global mastercount + global slavecount + slavecount=slavecount+1 + print 'input pixel loc is ',event.xdata,' ', event.ydata + ax.plot(event.xdata, event.ydata,'b.') + tktable.write_to_table_slave(np.round(event.xdata),np.round(event.ydata),slavecount,mastercount) + list_Slave.append([np.round(event.xdata), np.round(event.ydata)]) + print list_Slave + resetkeyy() + + canvasx.show() + +def open_rectification_Slave(): + + fileName=tkFileDialog.askopenfilename(title='select slave image to be rectified') + + global fx + global ax + fx = Figure(figsize=(5,4), dpi=100) + ax = fx.add_subplot(111) + img=mpimg.imread(fileName) + ax.imshow(img) + +# a tk.DrawingArea + global canvasx + canvasx = FigureCanvasTkAgg(fx, master=Root1) + canvasx.show() + + canvasx.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1) + + toolbar = NavigationToolbar2TkAgg( canvasx, Root1 ) + toolbar.update() + canvasx._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=1) + + def on_key_event(event): + print('you pressed %s'%event.key) + key_press_handler(event, canvasx, toolbar) + + + fx.canvas.mpl_connect('button_press_event',mouse_input_eventx) + fx.canvas.mpl_connect('key_press_event', on_key_event) + + def _quitx(): + Root1.quit() # stops mainloop + Root1.destroy() # this is necessary on Windows to pprevent + # Fatal Python Error: PyEval_RestoreThread: NULL tstate + button1 = tk.Button(master=Root1, text='Quit', command=_quitx) + button1.pack(side=tk.BOTTOM) + button = tk.Button(master=Root1, text='select', command=clickx) + button.pack(side=tk.BOTTOM) + + +def openref(): + + + global Root4 + Root4=tk.Tk() + Root4.title('Choose Polynomial order') + Root4.geometry('200x200') + var = IntVar() + r1=Spinbox(Root4,from_=0,to=100) + r1.pack() + buttona = tk.Button(master=Root4, text='GO', command=viewerwin2) + buttona.pack(side=tk.BOTTOM) + """R1 = Radiobutton(a, text="Order 0", variable=var, value=0) + R1.pack( anchor = W ) + + R2 = Radiobutton(a, text="Order 1", variable=var, value=1) + R2.pack( anchor = W ) + + R3 = Radiobutton(a, text="Order 2", variable=var, value=2) + R3.pack( anchor = W) + + label = Label(a) + label.pack() + + + L1 = Label(a, text="other") + L1.pack( side = LEFT) + E1 = Entry(a, bd =5) + + E1.pack(side = RIGHT) + selection=E1.get()""" + + a.mainloop() + + + image=Image.open(im) + image1=ImageTk.PhotoImage(image) + imagesprite=c.create_image(500,500,image=image1) + return im + + + + + + +def rgbselect(): + + fileName=tkFileDialog.askopenfilename() + if(fileName == ''): + pass + else: + print(fileName) + dataset=(tifwork.openTIF(fileName)) + + w=tk.Tk() + + def bandPrint(): + if(not(opt1.get() and opt2.get() and opt3.get())): + showerror("Error", "All bands not selected") + elif(opt1.get()==opt2.get() or opt1.get()==opt3.get() or opt2.get()==opt3.get()): + showerror("Error", "Two same bands selected") + else: + bandArr = tifwork.getBand(dataset,bands,bandArray) + tifwork.selectBand(bandArr,rows,cols,opt1.get(),opt2.get(),opt3.get()) + + frame4 = tk.Frame(w) +# frame4.grid() + frame2=tk.Frame(frame4) +# frame2.grid() + frame3=tk.Frame(frame4) +# frame3.grid() + frame5 = tk.Frame(w) +# frame5.grid() + w.title("Band Selection") + (cols,rows,bands,bandArray) = tifwork.detailsTIF(dataset) + + + optionList=[] + for k in range(1, bands+1): + optionList.append(k) + + x1=tk.Label(frame2, text="Red") + x1.pack(side=tk.TOP, pady = 5 , padx = 5 ) + opt1= ttk.Combobox(frame3,values=optionList, width=5) + opt1.pack(side = tk.TOP , pady = 5,padx = 5 ) + + x2=tk.Label(frame2, text="Blue") + x2.pack(side = tk.TOP , pady = 5 , padx = 5 ) + opt2= ttk.Combobox(frame3 , values=optionList, width=5) + opt2.pack(side = tk.TOP , pady = 5 , padx = 5 ) + + x3=tk.Label(frame2, text="Green") + x3.pack(side = tk.TOP , pady = 5 , padx = 5 ) + opt3= ttk.Combobox(frame3, values=optionList, width=5) + opt3.pack(side = tk.TOP , pady = 5 , padx = 5 ) + + frame2.pack(side=tk.LEFT, pady = 5 , padx = 5 ) + frame3.pack(side=tk.LEFT, pady = 5 , padx = 5 ) + frame4.pack(side= tk.TOP, pady = 5 , padx = 5 ) + + button = tk.Button(frame5, width=10, text="Show", command=bandPrint) + button.pack(side = tk.TOP , pady = 5 , padx = 5 ) + frame5.pack(side=tk.TOP , pady = 5 , padx = 5 ) + +#opens the root window +root=tk.Tk() + +root.title("Image Processing") + +frame1 = tk.Frame(root, width=800) + +#to display the frame +frame1.pack() + +#keeps only the frame +root.overrideredirect(0) +root.resizable(0,0) + +photo3 = tk.PhotoImage(file="2.gif") +button3 = tk.Button(frame1, width=100, height=100, image=photo3) +button3.pack(side=tk.LEFT, padx=2, pady=2) +button3.image = photo3 + + +photo2 = tk.PhotoImage(file="1.gif") +button2 = tk.Button(frame1, width=100, height=100, image=photo2, command=rgbselect) +button2.pack(side=tk.LEFT, padx=2, pady=2) +button2.image = photo2 + +button5 = tk.Button(frame1, width=20, height=6, text='Geometric correction',justify=tk.LEFT,command=viewerwin) +button5.pack(side=tk.LEFT, padx=2, pady=2) + + +photo1 = tk.PhotoImage(file="3.gif") +button1 = tk.Button(frame1, width=100, height=100, image=photo1, command=exit) +button1.pack(side=tk.LEFT, padx=2, pady=2) +button1.image = photo1 + +imdisplay('3.jpg') + +root.mainloop() + diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..130ceeb --- /dev/null +++ b/setup.py @@ -0,0 +1,18 @@ +from distutils.core import setup +import py2exe +import numpy +import scipy +import matplotlib +import sklearn + +setup(windows=['start.py'], + options={ + 'py2exe':{ + r'includes':[r'scipy.sparse.csgraph._validation', + r'scipy.special._ufuncs_cxx', + r'sklearn.utils.sparsetools._graph_validation', + r'sklearn.utils.lgamma', + r'sklearn.utils.weight_vector'] + } + } +) \ No newline at end of file diff --git a/spatial.py b/spatial.py new file mode 100644 index 0000000..d727b99 --- /dev/null +++ b/spatial.py @@ -0,0 +1,279 @@ +import matplotlib.pyplot as plt +import numpy as np +from scipy import ndimage +import PIL.Image as Image +import tifwork +import sys +sys.path.append('./GUI/') +import imageGUI +#import scipy.signal as sig + +''' +def plot(data,title): + + plot.i = plot.i + 1 + plt.subplot(3,2,plot.i) + plt.imshow(data) + plt.gray() + plt.title(title) + + +plot.i = 0 +''' + +def getData(fileName, num): + #get dataset + dataset = tifwork.openTIF(fileName) + + #get details of dataset + (cols,rows,bands,bandArray) = tifwork.detailsTIF(dataset) + + #get all bands + bandArray = tifwork.getBand(dataset,bands,bandArray) + + #input a band + + workData = bandArray[:,:,num-1] + + #show original image and plot it + imdata = Image.fromarray(workData) + imdata = imdata.convert('L') + imdata.save('original.jpg') + imageGUI.imdisplay('original.jpg','Original',1) + #plot(workData,'Original') + + return workData + #print workData + #print bandArray + +#get kernel +def getKernel(): + print 'Input Size of Kernel' + inp = raw_input() + kernel_size = int(inp) + kernel = np.zeros((kernel_size,kernel_size),dtype = float) + + print 'Enter kernel elements in matrix form' + + for i in range(0,kernel_size): + for j in range(0,kernel_size): + + kernel[i,j] = float(raw_input()) + + print 'Input Kernel is' + print kernel + + return kernel + +#getKernel() + +def meanFilter(fileName,size,num): + workData = getData(fileName,num) + kernel_size = size + kernel = np.ones((kernel_size,kernel_size),dtype = float) + + print kernel + kernel = kernel / (kernel_size**2) + + meanFilter = ndimage.convolve(workData, kernel,cval =1.0) + print 'Mean Filter' + + meanFilter1 = 2 * workData - meanFilter + + mfSave = Image.fromarray(meanFilter) + mfSave1 = Image.fromarray(meanFilter1) + + mfSave = mfSave.convert('1') + mfSave1 = mfSave1.convert('1') + + mfSave.save('Mean Filter.jpg') + mfSave1.save('Mean Filter1.jpg') + imageGUI.imdisplay('Mean Filter.jpg','Mean Filter',1) + imageGUI.imdisplay('Mean Filter1.jpg','Mean Filter1',1) + +def medianFilter(fileName,size,num): + workData = getData(fileName,num) + print 'Input filter size' + #size = int(raw_input()) + medFilter = ndimage.median_filter(workData,size) + mfSave = Image.fromarray(medFilter) + mfSave = mfSave.convert('1') + mfSave.save('Median Filter.jpg') + imageGUI.imdisplay('Median Filter.jpg','Median Filter',1) + # print 'med filter' , medFilter[100,:] + +def gaussFilter(fileName,sigma,num): + workData = getData(fileName,num) + print 'INput sigma' + #sigma = float(raw_input()) + gauFilter = ndimage.gaussian_filter(workData,sigma) + mfSave = Image.fromarray(gauFilter) + mfSave = mfSave.convert('1') + mfSave.save('Gauss Filter.jpg') + imageGUI.imdisplay('Gauss Filter.jpg','Guass Filter',1) + +def sobelFilter(fileName,num): + workData = getData(fileName,num) + sobFilter = ndimage.sobel(workData) + mfSave = Image.fromarray(sobFilter) + mfSave = mfSave.convert('1') + mfSave.save('Sobel Filter.jpg') + imageGUI.imdisplay('Sobel Filter.jpg','Sobel Filter',1) +def laplaceFilter(fileName,num): + + workData = getData(fileName,num) + lapFilter = ndimage.laplace(workData) + lapFilter = workData + lapFilter + mfSave = Image.fromarray(lapFilter) + mfSave = mfSave.convert('1') + mfSave.save('Laplace Filter.jpg') + imageGUI.imdisplay('Laplace Filter.jpg','Laplace Filter',1) +#High Pass Filters + +def fourierFilter(fileName,sigma,num): + workData = getData(fileName,num) + print 'INput sigma' + #sigma = float(raw_input()) + fourFilter1 = ndimage.fourier_uniform(workData,sigma) + fourFilter = ndimage.fourier_uniform(fourFilter1,sigma) + mfSave = Image.fromarray(fourFilter) + mfSave = mfSave.convert('L') + mfSave.save('Fourier Filter.jpg') + imageGUI.imdisplay('Fourier Filter.jpg','Fourier Filter',1) +# user defined +def filterUser(fileName,kernel,num): + workData = getData(fileName,num) + + userFil = ndimage.convolve(workData,kernel) + imsave = Image.fromarray(userFil) + imsave = imsave.convert('1') + imsave.save('User defined kernel.jpg') + imageGUI.imdisplay('User defined kernel.jpg','User defined kernel',1) + +# HIGH PASS PREDEFINED + +def hpfEmbossE(fileName,num): + workData = getData(fileName,num) + kernel = np.array([[0,0,0], + [1,0,-1], + [0,0,0]],dtype = float) + eeFilter = ndimage.convolve(workData, kernel) + mfSave = Image.fromarray(eeFilter) + mfSave = mfSave.convert('1') + mfSave.save('Emboss East Filter.jpg') + imageGUI.imdisplay('Emboss East Filter.jpg','Emboss East Filter',1) + +def hpfEmbossW(fileName,num): + workData = getData(fileName,num) + kernel = np.array([[0,0,0], + [-1,0,1], + [0,0,0]],dtype = float) + eeFilter = ndimage.convolve(workData, kernel) + mfSave = Image.fromarray(eeFilter) + mfSave = mfSave.convert('1') + mfSave.save('Emboss West Filter.jpg') + imageGUI.imdisplay('Emboss West Filter.jpg','Emboss West Filter',1) + +def hpfEdgeDetect(fileName,num): + workData = getData(fileName,num) + kernel = np.array([[-1,-1,-1], + [-1,9,-1], + [-1,-1,-1]],dtype = float) + eeFilter = ndimage.convolve(workData, kernel) + mfSave = Image.fromarray(eeFilter) + mfSave = mfSave.convert('1') + mfSave.save('Edge Detect Filter.jpg') + imageGUI.imdisplay('Edge Detect Filter.jpg','Edge Detect Filter',1) + +def hpfN(fileName,num): + workData = getData(fileName,num) + kernel = np.array([[1,1,1], + [1,-2,1], + [-1,-1,-1]],dtype = float) + eeFilter = ndimage.convolve(workData, kernel) + mfSave = Image.fromarray(eeFilter) + mfSave = mfSave.convert('1') + mfSave.save('North.jpg') + imageGUI.imdisplay('North.jpg','North',1) + +def hpfNE(fileName,num): + workData = getData(fileName,num) + kernel = np.array([[1,1,1], + [-1,-2,1], + [-1,-1,1]],dtype = float) + eeFilter = ndimage.convolve(workData, kernel) + mfSave = Image.fromarray(eeFilter) + mfSave = mfSave.convert('1') + mfSave.save('NorthE.jpg') + imageGUI.imdisplay('NorthE.jpg','NorthE',1) +def hpfE(fileName,num): + workData = getData(fileName,num) + kernel = np.array([[-1,1,1], + [-1,-2,1], + [-1,1,1]],dtype = float) + eeFilter = ndimage.convolve(workData, kernel) + mfSave = Image.fromarray(eeFilter) + mfSave = mfSave.convert('1') + mfSave.save('East.jpg') + imageGUI.imdisplay('East.jpg','East',1) +def hpfSE(fileName,num): + workData = getData(fileName,num) + kernel = np.array([[-1,-1,1], + [-1,-2,1], + [-1,1,1]],dtype = float) + eeFilter = ndimage.convolve(workData, kernel) + mfSave = Image.fromarray(eeFilter) + mfSave = mfSave.convert('1') + mfSave.save('SouthE.jpg') + imageGUI.imdisplay('SouthE.jpg','SouthE',1) +def hpfS(fileName,num): + workData = getData(fileName,num) + kernel = np.array([[-1,-1,-1], + [1,-2,1], + [1,1,1]],dtype = float) + eeFilter = ndimage.convolve(workData, kernel) + mfSave = Image.fromarray(eeFilter) + mfSave = mfSave.convert('1') + mfSave.save('South.jpg') + imageGUI.imdisplay('South.jpg','South',1) +def hpfSW(fileName,num): + workData = getData(fileName,num) + kernel = np.array([[1,-1,-1], + [1,-2,-1], + [1,1,1]],dtype = float) + eeFilter = ndimage.convolve(workData, kernel) + mfSave = Image.fromarray(eeFilter) + mfSave = mfSave.convert('1') + mfSave.save('SouthW.jpg') + imageGUI.imdisplay('SouthW.jpg','SouthW',1) +def hpfW(fileName,num): + workData = getData(fileName,num) + kernel = np.array([[1,1,-1], + [1,-2,-1], + [1,1,-1]],dtype = float) + eeFilter = ndimage.convolve(workData, kernel) + mfSave = Image.fromarray(eeFilter) + mfSave = mfSave.convert('1') + mfSave.save('West.jpg') + imageGUI.imdisplay('West.jpg','West',1) +def hpfNW(fileName,num): + workData = getData(fileName,num) + kernel = np.array([[1,1,1], + [1,-2,-1], + [1,-1,-1]],dtype = float) + eeFilter = ndimage.convolve(workData, kernel) + mfSave = Image.fromarray(eeFilter) + mfSave = mfSave.convert('1') + mfSave.save('NorthW.jpg') + imageGUI.imdisplay('NorthW.jpg','NorthW',1) + + +def hpfPrewitt(fileName,num): + + workData = getData(fileName,num) + preFilter = ndimage.prewitt(workData) + mfSave = Image.fromarray(preFilter) + mfSave = mfSave.convert('1') + mfSave.save('Prewitt Filter.png') + imageGUI.imdisplay('Prewitt Filter.png','Prewitt',1) + diff --git a/start.py b/start.py new file mode 100644 index 0000000..9efab32 --- /dev/null +++ b/start.py @@ -0,0 +1,149 @@ +''' +The software aims to be an open-source package with basic, and advanced Image Processing features. +Copyright (C) 2014 Indian Institute of Remote Sensing, Dehradun + +The original authors of this script/ program (in alphabetical order) are: + +--------------------------------------------------------------------------------------------------------------------------------------- +Sno. NAME Email( AT gmail DOT com) Role(s) +--------------------------------------------------------------------------------------------------------------------------------------- + +1. Shalaka Somani shalaka195 GUI +---------------------------------------------------------------------------------------------------------------------------------------- + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +''' + +import Tkinter as tk +from tkMessageBox import * +import ttk +import tkFileDialog +from PIL import Image +import tifwork +import guiEnhance as sg +import guiClass as cg +import sys +import imageGUI + +def exit(): + root.destroy() + sys.exit() + +def rectification(): + import rectest + + +def rgbselect(): + fileName=tkFileDialog.askopenfilename(filetypes=[('tiff file','*.tif')]) + if(fileName == ''): + showerror("Error", "Please select an image.") + return + else: + print(fileName) + dataset = tifwork.openTIF(fileName) + + w=tk.Tk() + + def bandPrint(): + if(not(opt1.get() and opt2.get() and opt3.get())): + showerror("Error", "All bands not selected") + elif(opt1.get()==opt2.get() or opt1.get()==opt3.get() or opt2.get()==opt3.get()): + showerror("Error", "Same bands selected") + else: + bandArr = tifwork.getBand(dataset,bands,bandArray) + tifwork.selectBand(bandArr,rows,cols,opt1.get(),opt2.get(),opt3.get()) + w.destroy() + + mainframe = tk.Frame(w) +# frame4.grid() + frame2=tk.Frame(mainframe) +# frame2.grid() + frame3=tk.Frame(mainframe) +# frame3.grid() + frame5 = tk.Frame(w) +# frame5.grid() + w.title("Band Selection") + (cols,rows,bands,bandArray) = tifwork.detailsTIF(dataset) + + + optionList=[] + for k in range(1, bands+1): + optionList.append(k) + + x1=tk.Label(frame2, text="Red") + x1.pack(side=tk.TOP, pady = 5 , padx = 5 ) + opt1= ttk.Combobox(frame3,values=optionList, width=5) + opt1.pack(side = tk.TOP , pady = 5,padx = 5 ) + + x2=tk.Label(frame2, text="Blue") + x2.pack(side = tk.TOP , pady = 5 , padx = 5 ) + opt2= ttk.Combobox(frame3 , values=optionList, width=5) + opt2.pack(side = tk.TOP , pady = 5 , padx = 5 ) + + x3=tk.Label(frame2, text="Green") + x3.pack(side = tk.TOP , pady = 5 , padx = 5 ) + opt3= ttk.Combobox(frame3, values=optionList, width=5) + opt3.pack(side = tk.TOP , pady = 5 , padx = 5 ) + + frame2.pack(side=tk.LEFT, pady = 5 , padx = 5 ) + frame3.pack(side=tk.LEFT, pady = 5 , padx = 5 ) + mainframe.pack(side= tk.TOP, pady = 5 , padx = 5 ) + + button = tk.Button(frame5, width=10, text="Display Image", command=bandPrint) + button.pack(side = tk.TOP , pady = 5 , padx = 5 ) + frame5.pack(side=tk.TOP , pady = 5 , padx = 5 ) + +#opens the root window +root=tk.Tk() + +root.title("Image Processing Software") + +frame1 = tk.Frame(root, width=1000) + +#to display the frame +frame1.pack() + +#keeps only the frame +root.overrideredirect(0) +root.resizable(0,0) + +photo3 = tk.PhotoImage(file="iirs.gif") +button3 = tk.Button(frame1, width=100, height=100,image=photo3) +button3.pack(side=tk.LEFT, padx=2, pady=2) + +photo2 = tk.PhotoImage(file="display.gif") +button2 = tk.Button(frame1, width=100, height=100, image=photo2, command=rgbselect) +button2.pack(side=tk.LEFT, padx=2, pady=2) + +#enhancement +photo4 = tk.PhotoImage(file="enhancement.gif") +button4 = tk.Button(frame1, width=100, height=100, image=photo4,command = sg.guiEn) +button4.pack(side=tk.LEFT, padx=2, pady=2) + +#classification +photo5 = tk.PhotoImage(file="classification.gif") +button5 = tk.Button(frame1, width=100, height=100, image=photo5 , command = cg.classgui) +button5.pack(side=tk.LEFT, padx=2, pady=2) + +#rectification +photo6 = tk.PhotoImage(file="rectification.gif") +button6 = tk.Button(frame1, width=100, height=100, image=photo6, command=rectification ) +button6.pack(side=tk.LEFT, padx=2, pady=2) + +photo1 = tk.PhotoImage(file="close.gif") +button1 = tk.Button(frame1, width=100, height=100, image=photo1, command=exit) +button1.pack(side=tk.LEFT, padx=2, pady=2) + +root.mainloop() diff --git a/svm.py b/svm.py new file mode 100644 index 0000000..f0611ca --- /dev/null +++ b/svm.py @@ -0,0 +1,81 @@ +from PIL import Image +import scipy.misc +import tifwork +import numpy as np +from sklearn import svm +import sys +sys.path.append('../GUI/') +import imageGUI + +def svmwork(fileName,data,target,typ): + print 'SVM' + dataset = tifwork.openTIF(fileName) + + (cols,rows,bands,bandArr) = tifwork.detailsTIF(dataset) + + bandArr = tifwork.getBand(dataset,bands,bandArr) + + + imageArray = np.array(bandArr,dtype =float) + + print imageArray.shape + + array = imageArray.copy() + + array = array.reshape((cols*rows),bands) + + #print array.shape + + + # training data extract + + # classifying training data + + + + #print target.shape + #print data.shape + #print array.shape + + # SVM + if (typ == 'poly'): + clf = svm.SVC(kernel=typ,degree=3) + else: + clf = svm.SVC(kernel=typ) + + clf.fit(data, target) + + isoarr = clf.predict(array) + + isoarr = np.array(isoarr,dtype =int) + #print isoarr + + #print isoarr.max() + + + #print z.shape + #print z + + + colorArray=np.array([[0,0,100],[100,0,0],[0,100,0],[100,100,0],[75,75,75],[0,100,100],[100,0,100],[50,25,25],[25,50,25],[25,25,50]]) + clusteredArray = np.zeros((rows*cols,3)) + #print clusteredArray.shape + clusters = isoarr.max() + + #print clusters + for i in xrange(clusters+1): + indices = np.where(isoarr == i)[0] + print i ,indices.size + if indices.size: + clusteredArray[indices] = colorArray[i] + + + print clusteredArray + clusteredArray = clusteredArray.reshape(rows,cols,3) + + #print clusteredArray + + scipy.misc.imsave('svm'+typ+'.jpg',clusteredArray) + imageGUI.imdisplay('svm'+typ+'.jpg','SVM-'+typ+'-Image') + print 'SVM Done' + diff --git a/svms.py b/svms.py new file mode 100644 index 0000000..f0611ca --- /dev/null +++ b/svms.py @@ -0,0 +1,81 @@ +from PIL import Image +import scipy.misc +import tifwork +import numpy as np +from sklearn import svm +import sys +sys.path.append('../GUI/') +import imageGUI + +def svmwork(fileName,data,target,typ): + print 'SVM' + dataset = tifwork.openTIF(fileName) + + (cols,rows,bands,bandArr) = tifwork.detailsTIF(dataset) + + bandArr = tifwork.getBand(dataset,bands,bandArr) + + + imageArray = np.array(bandArr,dtype =float) + + print imageArray.shape + + array = imageArray.copy() + + array = array.reshape((cols*rows),bands) + + #print array.shape + + + # training data extract + + # classifying training data + + + + #print target.shape + #print data.shape + #print array.shape + + # SVM + if (typ == 'poly'): + clf = svm.SVC(kernel=typ,degree=3) + else: + clf = svm.SVC(kernel=typ) + + clf.fit(data, target) + + isoarr = clf.predict(array) + + isoarr = np.array(isoarr,dtype =int) + #print isoarr + + #print isoarr.max() + + + #print z.shape + #print z + + + colorArray=np.array([[0,0,100],[100,0,0],[0,100,0],[100,100,0],[75,75,75],[0,100,100],[100,0,100],[50,25,25],[25,50,25],[25,25,50]]) + clusteredArray = np.zeros((rows*cols,3)) + #print clusteredArray.shape + clusters = isoarr.max() + + #print clusters + for i in xrange(clusters+1): + indices = np.where(isoarr == i)[0] + print i ,indices.size + if indices.size: + clusteredArray[indices] = colorArray[i] + + + print clusteredArray + clusteredArray = clusteredArray.reshape(rows,cols,3) + + #print clusteredArray + + scipy.misc.imsave('svm'+typ+'.jpg',clusteredArray) + imageGUI.imdisplay('svm'+typ+'.jpg','SVM-'+typ+'-Image') + print 'SVM Done' + diff --git a/tifwork.py b/tifwork.py new file mode 100644 index 0000000..9543c01 --- /dev/null +++ b/tifwork.py @@ -0,0 +1,46 @@ +from osgeo import gdal +import PIL.Image as Image +import numpy as np +import imageGUI +import scipy.misc + +gdal.AllRegister() + +def openTIF(filename): + dataset =gdal.Open(filename,gdal.GA_ReadOnly) + if dataset is None: + print 'Could Not Open' + filename + #Alternatively Raise an Event here + sys.exit(1) + + return dataset + +def detailsTIF(dataset): + cols = dataset.RasterXSize + rows = dataset.RasterYSize + bands = dataset.RasterCount + bandArray = np.zeros((rows,cols,bands),dtype = float) + return (cols, rows,bands,bandArray) + +def getBand(dataset,bands,bandArr): + for x in range(1,bands+1): + band=dataset.GetRasterBand(x) + array=band.ReadAsArray() + bandArr[:,:,x-1] = array + return bandArr + + +def selectBand(bandArray,rows,cols,ch1,ch2,ch3): + + ch1 = int(ch1) + ch2 = int(ch2) + ch3 = int(ch3) + combi= np.zeros((rows,cols,3),'uint8') + combi[:,:,0]=bandArray[:,:,ch1-1] + combi[:,:,1]=bandArray[:,:,ch2-1] + combi[:,:,2]=bandArray[:,:,ch3-1] + combImage= Image.fromarray(combi) + scipy.misc.imsave('fcc.jpg',combImage) + imageGUI.imdisplay('fcc.jpg','False Colour Composite',1) + + diff --git a/tktable.py b/tktable.py new file mode 100644 index 0000000..d833b2c --- /dev/null +++ b/tktable.py @@ -0,0 +1,738 @@ +# Copyright (c) 2008, Guilherme Polo +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +""" +This contains a wrapper class for the tktable widget as well a class for using +tcl arrays that are, in some instances, required by tktable. +""" + +__author__ = "Guilherme Polo " + +__all__ = ["ArrayVar", "Table"] + +import os +import Tkinter + +def _setup_master(master): + if master is None: + if Tkinter._support_default_root: + master = Tkinter._default_root or Tkinter.Tk() + else: + raise RuntimeError("No master specified and Tkinter is " + "configured to not support default master") + return master + +class ArrayVar(Tkinter.Variable): + """Class for handling Tcl arrays. + + An array is actually an associative array in Tcl, so this class supports + some dict operations. + """ + + def __init__(self, master=None, name=None): + # Tkinter.Variable.__init__ is not called on purpose! I don't wanna + # see an ugly _default value in the pretty array. + self._master = _setup_master(master) + self._tk = self._master.tk + if name: + self._name = name + else: + self._name = 'PY_VAR%s' % id(self) + + def __del__(self): + if bool(self._tk.call('info', 'exists', self._name)): + self._tk.globalunsetvar(self._name) + + def __len__(self): + return int(self._tk.call('array', 'size', str(self))) + + def __getitem__(self, key): + return self.get(key) + + def __setitem__(self, key, value): + self.set(**{str(key): value}) + + def names(self): + return self._tk.call('array', 'names', self._name) + + def get(self, key=None): + if key is None: + flatten_pairs = self._tk.call('array', 'get', str(self)) + return dict(zip(flatten_pairs[::2], flatten_pairs[1::2])) + + return self._tk.globalgetvar(str(self), str(key)) + + def set(self, **kw): + self._tk.call('array', 'set', str(self), Tkinter._flatten(kw.items())) + + def unset(self, pattern=None): + """Unsets all of the elements in the array. If pattern is given, only + the elements that match pattern are unset. """ + self._tk.call('array', 'unset', str(self), pattern) + + +_TKTABLE_LOADED = False + +class Table(Tkinter.Widget): + """Create and manipulate tables.""" + + _switches = ('holddimensions', 'holdselection', 'holdtags', 'holdwindows', + 'keeptitles', '-') + _tabsubst_format = ('%c', '%C', '%i', '%r', '%s', '%S', '%W') + _tabsubst_commands = ('browsecommand', 'browsecmd', 'command', + 'selectioncommand', 'selcmd', + 'validatecommand', 'valcmd') + + def __init__(self, master=None, **kw): + master = _setup_master(master) + global _TKTABLE_LOADED + if not _TKTABLE_LOADED: + tktable_lib = os.environ.get('TKTABLE_LIBRARY') + if tktable_lib: + master.tk.eval('global auto_path; ' + 'lappend auto_path {%s}' % tktable_lib) + master.tk.call('package', 'require', 'Tktable') + _TKTABLE_LOADED = True + + Tkinter.Widget.__init__(self, master, 'table', kw) + + + def _options(self, cnf, kw=None): + if kw: + cnf = Tkinter._cnfmerge((cnf, kw)) + else: + cnf = Tkinter._cnfmerge(cnf) + + res = () + for k, v in cnf.iteritems(): + if callable(v): + if k in self._tabsubst_commands: + v = "%s %s" % (self._register(v, self._tabsubst), + ' '.join(self._tabsubst_format)) + else: + v = self._register(v) + res += ('-%s' % k, v) + + return res + + + def _tabsubst(self, *args): + if len(args) != len(self._tabsubst_format): + return args + + tk = self.tk + c, C, i, r, s, S, W = args + e = Tkinter.Event() + + e.widget = self + e.c = tk.getint(c) + e.i = tk.getint(i) + e.r = tk.getint(r) + e.C = "%d,%d" % (e.r, e.c) + e.s = s + e.S = S + try: + e.W = self._nametowidget(W) + except KeyError: + e.W = None + + return (e,) + + + def _handle_switches(self, args): + args = args or () + return tuple(('-%s' % x) for x in args if x in self._switches) + + + def activate(self, index): + """Set the active cell to the one indicated by index.""" + self.tk.call(self._w, 'activate', index) + + + def bbox(self, first, last=None): + """Return the bounding box for the specified cell (range) as a + 4-tuple of x, y, width and height in pixels. It clips the box to + the visible portion, if any, otherwise an empty tuple is returned.""" + return self._getints(self.tk.call(self._w, 'bbox', first, last)) or () + + + def clear(self, option, first=None, last=None): + """This is a convenience routine to clear certain state information + managed by the table. first and last represent valid table indices. + If neither are specified, then the command operates on the whole + table.""" + self.tk.call(self._w, 'clear', option, first, last) + + + def clear_cache(self, first=None, last=None): + """Clear the specified section of the cache, if the table has been + keeping one.""" + self.clear('cache', first, last) + + + def clear_sizes(self, first=None, last=None): + """Clear the specified row and column areas of specific height/width + dimensions. When just one index is specified, for example 2,0, that + is interpreted as row 2 and column 0.""" + self.clear('sizes', first, last) + + + def clear_tags(self, first=None, last=None): + """Clear the specified area of tags (all row, column and cell tags).""" + self.clear('tags', first, last) + + + def clear_all(self, first=None, last=None): + """Perform all of the above clear functions on the specified area.""" + self.clear('all', first, last) + + + def curselection(self, value=None): + """With no arguments, it returns the sorted indices of the currently + selected cells. Otherwise it sets all the selected cells to the given + value if there is an associated ArrayVar and the state is not + disabled.""" + result = self.tk.call(self._w, 'curselection', value) + if value is None: + return result + + + def curvalue(self, value=None): + """If no value is given, the value of the cell being edited (indexed + by active) is returned, else it is set to the given value. """ + return self.tk.call(self._w, 'curvalue', value) + + + def delete_active(self, index1, index2=None): + """Deletes text from the active cell. If only one index is given, + it deletes the character after that index, otherwise it deletes from + the first index to the second. index can be a number, insert or end.""" + self.tk.call(self._w, 'delete', 'active', index1, index2) + + + def delete_cols(self, index, count=None, switches=None): + args = self._handle_switches(switches) + (index, count) + self.tk.call(self._w, 'delete', 'cols', *args) + + + def delete_rows(self, index, count=None, switches=None): + args = self._handle_switches(switches) + (index, count) + self.tk.call(self._w, 'delete', 'rows', *args) + + + def get(self, first, last=None): + """Returns the value of the cells specified by the table indices + first and (optionally) last.""" + return self.tk.call(self._w, 'get', first, last) + + + def height(self, row=None, **kwargs): + """If row and kwargs are not given, a list describing all rows for + which a width has been set is returned. + If row is given, the height of that row is returnd. + If kwargs is given, then it sets the key/value pairs, where key is a + row and value represents the height for the row.""" + if row is None and not kwargs: + pairs = self.tk.splitlist(self.tk.call(self._w, 'height')) + return dict(pair.split() for pair in pairs) + elif row: + return int(self.tk.call(self._w, 'height', str(row))) + + args = Tkinter._flatten(kwargs.items()) + self.tk.call(self._w, 'height', *args) + + + def hidden(self, *args): + """When called without args, it returns all the hidden cells (those + cells covered by a spanning cell). If one index is specified, it + returns the spanning cell covering that index, if any. If multiple + indices are specified, it returns 1 if all indices are hidden cells, + 0 otherwise.""" + return self.tk.call(self._w, 'hidden', *args) + + + def icursor(self, arg=None): + """If arg is not specified, return the location of the insertion + cursor in the active cell. Otherwise, set the cursor to that point in + the string. + + 0 is before the first character, you can also use insert or end for + the current insertion point or the end of the text. If there is no + active cell, or the cell or table is disabled, this will return -1.""" + return self.tk.call(self._w, 'icursor', arg) + + + def index(self, index, rc=None): + """Return the integer cell coordinate that corresponds to index in the + form row, col. If rc is specified, it must be either 'row' or 'col' so + only the row or column index is returned.""" + res = self.tk.call(self._w, 'index', index, rc) + if rc is None: + return res + else: + return int(res) + + + def insert_active(self, index, value): + """The value is a text string which is inserted at the index postion + of the active cell. The cursor is then positioned after the new text. + index can be a number, insert or end. """ + self.tk.call(self._w, 'insert', 'active', index, value) + + + def insert_cols(self, index, count=None, switches=None): + args = self._handle_switches(switches) + (index, count) + self.tk.call(self._w, 'insert', 'cols', *args) + + + def insert_rows(self, index, count=None, switches=None): + args = self._handle_switches(switches) + (index, count) + self.tk.call(self._w, 'insert', 'rows', *args) + + + #def postscript(self, **kwargs): + # """Skip this command if you are under Windows. + # + # Accepted options: + # colormap, colormode, file, channel, first, fontmap, height, + # last, pageanchor, pageheight, pagewidth, pagex, pagey, rotate, + # width, x, y + # """ + # args = () + # for key, val in kwargs.iteritems(): + # args += ('-%s' % key, val) + # + # return self.tk.call(self._w, 'postscript', *args) + + + def reread(self): + """Rereads the old contents of the cell back into the editing buffer. + Useful for a key binding when is pressed to abort the edit + (a default binding).""" + self.tk.call(self._w, 'reread') + + + def scan_mark(self, x, y): + self.tk.call(self._w, 'scan', 'mark', x, y) + + + def scan_dragto(self, x, y): + self.tk.call(self._w, 'scan', 'dragto', x, y) + + + def see(self, index): + self.tk.call(self._w, 'see', index) + + + def selection_anchor(self, index): + self.tk.call(self._w, 'selection', 'anchor', index) + + + def selection_clear(self, first, last=None): + self.tk.call(self._w, 'selection', 'clear', first, last) + + + def selection_includes(self, index): + return self.getboolean(self.tk.call(self._w, 'selection', 'includes', + index)) + + + def selection_set(self, first, last=None): + self.tk.call(self._w, 'selection', 'set', first, last) + + + def set(self, rc=None, index=None, *args, **kwargs): + """If rc is specified (either 'row' or 'col') then it is assumes that + args (if given) represents values which will be set into the + subsequent columns (if row is specified) or rows (for col). + If index is not None and args is not given, then it will return the + value(s) for the cell(s) specified. + + If kwargs is given, assumes that each key in kwargs is a index in this + table and sets the specified index to the associated value. Table + validation will not be triggered via this method. + + Note that the table must have an associated array (defined through the + variable option) in order to this work.""" + if not args and index is not None: + if rc: + args = (rc, index) + else: + args = (index, ) + return self.tk.call(self._w, 'set', *args) + + if rc is None: + args = Tkinter._flatten(kwargs.items()) + self.tk.call(self._w, 'set', *args) + else: + self.tk.call(self._w, 'set', rc, index, args) + + + def spans(self, index=None, **kwargs): + """Manipulate row/col spans. + + When called with no arguments, all known spans are returned as a dict. + When called with only the index, the span for that index only is + returned, if any. Otherwise kwargs is assumed to contain keys/values + pairs used to set spans. A span starts at the row,col defined by a key + and continues for the specified number of rows,cols specified by + its value. A span of 0,0 unsets any span on that cell.""" + if kwargs: + args = Tkinter._flatten(kwargs.items()) + self.tk.call(self._w, 'spans', *args) + else: + return self.tk.call(self._w, 'spans', index) + + + def tag_cell(self, tagname, *args): + return self.tk.call(self._w, 'tag', 'cell', tagname, *args) + + + def tag_cget(self, tagname, option): + return self.tk.call(self._w, 'tag', 'cget', tagname, '-%s' % option) + + + def tag_col(self, tagname, *args): + return self.tk.call(self._w, 'tag', 'col', tagname, *args) + + + def tag_configure(self, tagname, option=None, **kwargs): + """Query or modify options associated with the tag given by tagname. + + If no option is specified, a dict describing all of the available + options for tagname is returned. If option is specified, then the + command returns a list describing the one named option. Lastly, if + kwargs is given then it corresponds to option-value pairs that should + be modified.""" + if option is None and not kwargs: + split1 = self.tk.splitlist( + self.tk.call(self._w, 'tag', 'configure', tagname)) + + result = {} + for item in split1: + res = self.tk.splitlist(item) + result[res[0]] = res[1:] + + return result + + elif option: + return self.tk.call(self._w, 'tag', 'configure', tagname, + '-%s' % option) + + else: + args = () + for key, val in kwargs.iteritems(): + args += ('-%s' % key, val) + + self.tk.call(self._w, 'tag', 'configure', tagname, *args) + + + def tag_delete(self, tagname): + self.tk.call(self._w, 'tag', 'delete', tagname) + + + def tag_exists(self, tagname): + return self.getboolean(self.tk.call(self._w, 'tag', 'exists', tagname)) + + + def tag_includes(self, tagname, index): + return self.getboolean(self.tk.call(self._w, 'tag', 'includes', + tagname, index)) + + + def tag_lower(self, tagname, belowthis=None): + self.tk.call(self._w, 'tag', 'lower', belowthis) + + + def tag_names(self, pattern=None): + return self.tk.call(self._w, 'tag', 'names', pattern) + + + def tag_raise(self, tagname, abovethis=None): + self.tk.call(self._w, 'tag', 'raise', tagname, abovethis) + + + def tag_row(self, tagname, *args): + return self.tk.call(self._w, 'tag', 'row', tagname, *args) + + + def validate(self, index): + """Explicitly validates the specified index based on the current + callback set for the validatecommand option. Return 0 or 1 based on + whether the cell was validated.""" + return self.tk.call(self._w, 'validate', index) + + + @property + def version(self): + """Return tktable's package version.""" + return self.tk.call(self._w, 'version') + + + def width(self, column=None, **kwargs): + """If column and kwargs are not given, a dict describing all columns + for which a width has been set is returned. + If column is given, the width of that column is returnd. + If kwargs is given, then it sets the key/value pairs, where key is a + column and value represents the width for the column.""" + if column is None and not kwargs: + pairs = self.tk.splitlist(self.tk.call(self._w, 'width')) + return dict(pair.split() for pair in pairs) + elif column is not None: + return int(self.tk.call(self._w, 'width', str(column))) + + args = Tkinter._flatten(kwargs.items()) + self.tk.call(self._w, 'width', *args) + + + def window_cget(self, index, option): + return self.tk.call(self._w, 'window', 'cget', index, option) + + + def window_configure(self, index, option=None, **kwargs): + """Query or modify options associated with the embedded window given + by index. This should also be used to add a new embedded window into + the table. + + If no option is specified, a dict describing all of the available + options for index is returned. If option is specified, then the + command returns a list describing the one named option. Lastly, if + kwargs is given then it corresponds to option-value pairs that should + be modified.""" + if option is None and not kwargs: + return self.tk.call(self._w, 'window', 'configure', index) + elif option: + return self.tk.call(self._w, 'window', 'configure', index, + '-%s' % option) + else: + args = () + for key, val in kwargs.iteritems(): + args += ('-%s' % key, val) + + self.tk.call(self._w, 'window', 'configure', index, *args) + + + def window_delete(self, *indexes): + self.tk.call(self._w, 'window', 'delete', *indexes) + + + def window_move(self, index_from, index_to): + self.tk.call(self._w, 'window', 'move', index_from, index_to) + + + def window_names(self, pattern=None): + return self.tk.call(self._w, 'window', 'names', pattern) + + + def xview(self, index=None): + """If index is not given a tuple containing two fractions is returned, + each fraction is between 0 and 1. Together they describe the + horizontal span that is visible in the window. + + If index is given the view in the window is adjusted so that the + column given by index is displayed at the left edge of the window.""" + res = self.tk.call(self._w, 'xview', index) + if index is None: + return self._getdoubles(res) + + + def xview_moveto(self, fraction): + """Adjusts the view in the window so that fraction of the total width + of the table text is off-screen to the left. The fraction parameter + must be a fraction between 0 and 1.""" + self.tk.call(self._w, 'xview', 'moveto', fraction) + + + def xview_scroll(self, *L): + #change by frank gao for attach scrollbar 11/11/2010 + """Shift the view in the window left or right according to number and + what. The 'number' parameter must be an integer. The 'what' parameter + must be either units or pages or an abbreviation of one of these. + + If 'what' is units, the view adjusts left or right by number cells on + the display; if it is pages then the view adjusts by number screenfuls. + If 'number' is negative then cells farther to the left become visible; + if it is positive then cells farther to the right become visible. """ + #self.tk.call(self._w, 'xview', 'scroll', number, what) + if op=='scroll': + units=L[2] + self.tk.call(self._w, 'xview', 'scroll',howMany,units) + elif op=='moveto': + self.tk.call(self._w, 'xview', 'moveto',howMany) + + + def yview(self, index=None): + """If index is not given a tuple containing two fractions is returned, + each fraction is between 0 and 1. The first element gives the position + of the table element at the top of the window, relative to the table + as a whole. The second element gives the position of the table element + just after the last one in the window, relative to the table as a + whole. + + If index is given the view in the window is adjusted so that the + row given by index is displayed at the top of the window.""" + res = self.tk.call(self._w, 'yview', index) + if index is None: + return self._getdoubles(res) + + + def yview_moveto(self, fraction): + """Adjusts the view in the window so that the element given by + fraction appears at the top of the window. The fraction parameter + must be a fraction between 0 and 1.""" + self.tk.call(self._w, 'yview', 'moveto', fraction) + + + def yview_scroll(self, *L): + #change by frank gao for attach scrollbar 11/11/2010 + """Adjust the view in the window up or down according to number and + what. The 'number' parameter must be an integer. The 'what' parameter + must be either units or pages or an abbreviation of one of these. + + If 'what' is units, the view adjusts up or down by number cells; if it + is pages then the view adjusts by number screenfuls. + If 'number' is negative then earlier elements become visible; if it + is positive then later elements become visible. """ + #self.tk.call(self._w, 'yview', 'scroll', number, what) + op,howMany=L[0],L[1] + if op=='scroll': + units=L[2] + self.tk.call(self._w, 'yview', 'scroll',howMany,units) + elif op=='moveto': + self.tk.call(self._w, 'yview', 'moveto',howMany) + + +# Sample test taken from tktable cvs, original tktable python wrapper +def sample_test(): + global Root1 + from Tkinter import Tk, Label, Button + + def test_cmd(event): + if event.i == 0: + return '%i, %i' % (event.r, event.c) + else: + return 'set' + + def browsecmd(event): + print "event:", event.__dict__ + print "curselection:", test.curselection() + print "active cell index:", test.index('active') + print "active:", test.index('active', 'row') + print "anchor:", test.index('anchor', 'row') + + root3 = Tkinter.Tk() + global var + var = ArrayVar(root3) + '''for y in range(-1, 4): + for x in range(-1, 5): + index = "%i,%i" % (y, x) + var[index] = index + ''' + index = "%i,%i" % (-1, -1) + var[index]="Serial no" + index = "%i,%i" % (-1, 0) + var[index]="SlaveX" + index = "%i,%i" % (-1, 1) + var[index]="SlaveY" + index = "%i,%i" % (-1, 2) + var[index]="MasterX" + index = "%i,%i" % (-1, 3) + var[index]="MasterY" + index = "%i,%i" % (-1, 4) + var[index]="RMS_XY-" + #index = "%i,%i" % (-1, 5) + #var[index]="RMS_Y" + for y in range (0,11): + index = "%i,%i" % (y, -1) + var[index]=y+1 + + label = Label(root3, text="Rectification") + label.pack(side = 'top', fill = 'x') + + quit = Button(root3, text="QUIT", command=root3.destroy) + quit.pack(side = 'bottom', fill = 'x') + global test + test = Table(root3, + rows=10, + cols=7, + state='disabled', + width=8, + height=8, + titlerows=1, + titlecols=1, + roworigin=-1, + colorigin=-1, + selectmode='browse', + selecttype='row', + rowstretch='unset', + colstretch='last', + browsecmd=browsecmd, + flashmode='on', + variable=var, + usecommand=0, + command=test_cmd) + test.pack(expand=1, fill='both') + test.tag_configure('sel', background = 'yellow') + test.tag_configure('active', background = 'blue') + test.tag_configure('title', anchor='w', bg='red', relief='sunken') + root3.mainloop() +def write_to_table_master(x,y,count,count1): + global var,test + index = "%i,%i" % (count-1, 0) + var[index]=x + index = "%i,%i" % (count-1, 1) + var[index]=y + test.pack(expand=1, fill='both') +#if (count1==count): +#RMS_clac() +def write_to_table_slave(x,y,count,count1): + global var,test + index = "%i,%i" % (count-1, 2) + var[index]=x + index = "%i,%i" % (count-1, 3) + var[index]=y + test.pack(expand=1, fill='both') + #if (count1==count): +# RMS_clac(count) +'''def RMS_calc(order,): + global var,test + for i in range(0,count) + index'i' = "%i,%i" % (count-1, i-1) + index2 = "%i,%i" % (count-1, 1) + index3 = "%i,%i" % (count-1, 2) + index4= "%i,%i" % (count-1, 3) + x1=var[index1] + x2=var[index3] + y1=var[index2] + y2=var[index4] + xrms=(x1**2+x2**2)/2 + xrms=xrms**0.5 + yrms=(y1**2+y2**2)/2 + yrms=yrms**0.5 + index1 = "%i,%i" % (count-1, 4) + index2 = "%i,%i" % (count-1, 5) + var[index1]=xrms + var[index2]=yrms + test.pack(expand=1, fill='both') +'''