-
Notifications
You must be signed in to change notification settings - Fork 2
/
Root.py
280 lines (244 loc) · 10.6 KB
/
Root.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
'''This code is a part of the 3D Scanner project'''
'''Developed by team SAAS'''
'''Ekalavya 2017'''
'''IIT Bombay'''
#The necessary packages are imported
#Downloaded packages
import pygame as pg
from pygame.locals import *
import numpy as np
import cv2
import imutils
import matplotlib.pyplot as plt
#local packages
from About import *
from ShowBmp import *
import ValueSelected
import Integration
#python inbuilt packages
import Tkinter as tk
import ttk
import os
import time
import serial
import threading
from time import gmtime, strftime
def Show3D(x):
ScannedObject=Integration.Integration()
ScannedObject.ReadFile('./'+x)
ScannedObject.Plot3D()
class Root(): #A class called Root is defined
w,h=800,600 #local variables w(width) and h(height) are specified
def __init__(self,x,y,z,a,n): #constructor of the class
#values are assigned to the instance variables
self.VideoDeviceNumber=x
self.Names=y
self.Dict=z
self.Boards=a
self.BoardNumber=n
self.root = tk.Tk()
self.FlagValue=0
self.FrameCount=0
self.X=[]
self.Y=[]
self.redlow=240
self.redup=255
self.greenlow=150
self.greenup=255
self.bluelow=150
self.blueup=255
def setDeviceNumber(self,x): #callback function to set the VideoDeviceNumber
self.VideoDeviceNumber=x
def func(self): #callback function when 'Settings' is selected
self.cap.release() #camera is made inactive
obj=ValueSelected.ComboBox(self.Names,self.Dict,self.Boards) #a combobox object is created
obj.CreateComboBox()#combobox is created
self.VideoDeviceNumber = obj.d #VideoDeviceNumber is assigned
self.BoardNumber = obj.b #Arduino's BoardNumber is assigned
print "Opening Device Number:", self.VideoDeviceNumber #Prints a message about the selection of the camera by the user
self.CreateMainWindow() #The mainwindow is created again
def ProgressbarWindow(self):
self.ProgressVar = tk.DoubleVar() #here you have ints but when calc. %'s usually floats
self.TheLabel = tk.Label(self.root, text="Percentage completed")
self.TheLabel.pack()
self.progressbar = ttk.Progressbar(self.root, variable=self.ProgressVar, maximum=48)
self.progressbar.pack()
def Capture(self): #callback function to start the rotation of the stepper motor and save the .png files and coordinates in .txt files
self.FlagValue=1 #FlagValue is a flag that is turned 0 to stop the stepper and the saving of images and 1 to start
self.FrameCount=0 #It is a counter variable used to count the number of frames captured
self.FolderName=strftime("%Y-%m-%d_%H:%M:%S", gmtime()) #string to store the folder name "<CurrentDate CurrentTime>"
os.mkdir('./'+self.FolderName) #creates a folder in the local directory
os.chdir('./'+self.FolderName) #changes the directory to the created directory
self.ProgressbarWindow()
def StopCapture(self):
self.FlagValue=0 # makes the flag value to 0 to stop the capturing of frames
self.FrameCount=0
os.chdir('../')
self.progressbar.pack_forget()
self.TheLabel.pack_forget()
def thread2(self):
self.th2=threading.Thread(target=self.Capture) #a thread is initiated to call the self.Capture() function
self.th2.start() #the thread is started
def plot(self):
#some local variables are created
X=[]
Y=[]
temp1=[]
temp=[]
towrite=[]
#the under written functions are for extracting the coordinates from numpy.ndarray datatype
for i in range(len(self.c)):
temp1.append(self.c[i][0])
for i in range(len(temp1)):
temp.append(str(temp1[i]).split(','))
for i in temp:
a=(str(i[0]).split('['))[1].split(']')[0] #Extract the information between two square brackets
towrite.append(a)
#A file is opened to write the coordinates of the contour
f=open(str(self.FrameCount)+".txt", 'w')
for i in towrite:
i=str(i)
i=i.strip()
i=i.replace(' ',' ')
i=i.replace(' ', ' ')
i=i.strip()
temp=i.split(' ')
self.X.append(int(temp[0]))
self.Y.append(-int(temp[1]))
f.write(str(self.X)+'\n\n')
f.write(str(self.Y)+'\n\n')
f.close()
def SetRGBValues(self): #function to set the RGB values in the variables
self.redlow=int(self.rlow.get())
self.redup=int(self.rup.get())
self.greenlow=int(self.glow.get())
self.greenup=int(self.gup.get())
self.bluelow=int(self.blow.get())
self.blueup=int(self.bhigh.get())
def PlotPointCloud(self): #callback function to plot the point cloud
ScannedObject=Integration.Integration()
ScannedObject.ReadFile('./')
ScannedObject.CalculateXYZ()
ScannedObject.PlotScatter()
self.FlagValue=0
self.FrameCount=0
os.chdir('../')
def PlotSurfacePlot(self): #callback function to plot the surface plot
ScannedObject=Integration.Integration()
ScannedObject.ReadFile('./')
ScannedObject.CalculateXYZ()
ScannedObject.PlotTrisurf()
self.FlagValue=0
self.FrameCount=0
os.chdir('../')
def ShowFrame(self):
try:
del self.embed
except:
pass
self.cap = cv2.VideoCapture(self.VideoDeviceNumber) #Video Device(webcam) is opened
self.embed = tk.Frame(self.root, width=Root.w, height=Root.h)#a frame called 'embed' is created that hosts the pygame graphics
self.embed.pack() #The frame is packed
self.button=tk.Button(self.root, text="Start Capturing", command=self.Capture) #Button is created
self.button.pack() #Button is packed in left side
self.button=tk.Button(self.root, text="Stop Capturing" , command=self.StopCapture) #Button is created
self.button.pack() #Button is packed in right side
self.button=tk.Button(self.root, text="Plot Point Cloud" , command=self.PlotPointCloud) #Button is created
self.button.pack() #Button is packed in right side
self.button=tk.Button(self.root, text="Plot Surface Plot" , command=self.PlotSurfacePlot) #Button is created
self.button.pack() #Button is packed in right side
#variables to set the lower and the upper values of RGB are initialised
self.rlow=tk.StringVar(self.root)
self.rlow.set(self.redlow)
self.entry_rlow=tk.Entry(self.root, textvariable=self.rlow)
self.entry_rlow.pack()
self.rup=tk.StringVar(self.root)
self.rup.set(self.redup)
self.entry_rup=tk.Entry(self.root, textvariable=self.rup)
self.entry_rup.pack()
self.glow=tk.StringVar(self.root)
self.glow.set(self.greenlow)
self.entry_glow=tk.Entry(self.root, textvariable=self.glow)
self.entry_glow.pack()
self.gup=tk.StringVar(self.root)
self.gup.set(self.greenup)
self.entry_gup=tk.Entry(self.root, textvariable=self.gup)
self.entry_gup.pack()
self.blow=tk.StringVar(self.root)
self.blow.set(self.bluelow)
self.entry_blow=tk.Entry(self.root, textvariable=self.blow)
self.entry_blow.pack()
self.bhigh=tk.StringVar(self.root)
self.bhigh.set(self.blueup)
self.entry_bhigh=tk.Entry(self.root, textvariable=self.bhigh)
self.entry_bhigh.pack()
self.SetButton=tk.Button(self.root, text="Set RGB Values", command=self.SetRGBValues) #Button is created
self.SetButton.pack() #Button is packed in left side
os.environ['SDL_WINDOWID'] = str(self.embed.winfo_id())# Tell pygame's SDL window which window ID to use
self.root.update() #the window is updated
pg.display.init()# Usual pygame initialization
pg.display.set_mode((640,480), DOUBLEBUF|OPENGL|HWSURFACE|RESIZABLE) #refer to https://www.pygame.org/docs/ref/display.html
while 1:
_, self.frame = self.cap.read() #Read the video device input
#self.frame = cv2.flip(self.frame, 1) #This should be uncommented to get the mirror image of the actual frame
self.lower = np.array([self.bluelow,self.greenlow,self.redlow]) #lower limit of BGR values of the laser line
self.upper= np.array([self.blueup,self.greenup,self.redup]) #upper limit of BGR values of the laser line
self.mask = cv2.inRange(self.frame, self.lower, self.upper) #create a mask within the specified values of RED
self.output_img = self.frame.copy() #a copy of the main frame is created
self.output_img[np.where(self.mask==0)] = 0 #where the mask value is 0, make those coordinates black
self.output_img[np.where(self.mask>100)] =255 #The target points, or the points which belong to the laser line are displayed in white
self.gray = cv2.cvtColor(self.output_img, cv2.COLOR_BGR2GRAY)
self.gray = cv2.GaussianBlur(self.gray, (5, 5), 0)
self.thresh = cv2.threshold(self.gray, 45, 255, cv2.THRESH_BINARY)[1]
self.thresh = cv2.erode(self.thresh, None, iterations=2)
self.thresh = cv2.dilate(self.thresh, None, iterations=2)
#finding the contours with RED colour
self.cnts = cv2.findContours(self.thresh.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
self.cnts = self.cnts[0] if imutils.is_cv2() else self.cnts[1]
for i in range(len(self.cnts)):
self.c=self.cnts[i]
cv2.drawContours(self.output_img, [self.c], -1, (0, 255, 255), 2) #Draw all the contours with a red background
if (self.FlagValue==1):
self.plot()
self.im=ShowBmp(self.output_img) #process the output_img with OpenGL functions defined inside ShowBmp
wall(self.im) #create the wall to be displayed in pygame
pg.display.flip()# Update the pygame display
if (self.FlagValue==1 and self.FrameCount<48):
ser=serial.Serial('/dev/'+self.Boards[self.BoardNumber-1], 9600) #open the serial port
ser.write(b'1') #write serial data
cv2.imwrite(str(self.FrameCount)+'.png',self.output_img) #save the .png image
self.ProgressVar.set(self.FrameCount)
self.root.update_idletasks()
time.sleep(0.3) #pause the code for 200ms
if ser.inWaiting():
BytesAvailable=ser.inWaiting()
SerialReadData=ser.read(BytesAvailable)
if (SerialReadData=='.'):
self.FrameCount+=1 #increase the frame counter
#print self.FrameCount
#self.FrameCount+=1
if (self.FlagValue==1 and self.FrameCount==48):
self.FlagValue=0
self.FrameCount=0
self.progressbar.pack_forget()
self.TheLabel.pack_forget()
self.root.update()# Update the Tk display
def CreateMainWindow(self):
self.root.wm_title("Webcam Interface") #assign title to the root window
menubar = tk.Menu(self.root) #Menubar widget is created
filemenu = tk.Menu(menubar, tearoff=0) #Filemenu is created
filemenu.add_command(label="Exit", command=self.root.destroy)
menubar.add_cascade(label="File", menu=filemenu)
editmenu = tk.Menu(menubar, tearoff=0)
menubar.add_cascade(label="Edit", menu=editmenu)
self.VideoDeviceName=tk.StringVar()
editmenu.add_radiobutton(label="Settings", command=self.func)
helpmenu = tk.Menu(menubar, tearoff=0)
helpmenu.add_command(label="About", command=About)
menubar.add_cascade(label="Help", menu=helpmenu)
self.root.config(menu=menubar)#menubar is packed in the frame
self.ShowFrame()
'''This code is a part of the 3D Scanner project'''
'''Developed by team SAAS'''
'''Ekalavya 2017'''
'''IIT Bombay'''