--- /dev/null
+import cv2, sys, Printer
+from utils import MatrixConversion
+from User_Interface import BoxFrame, Draw, MouseManager
+
+cap = cv2.VideoCapture(0)
+ret, frame = cap.read()
+cv2.namedWindow('image')
+
+galvo_corners = [(50, 50), (100, 50), (100, 100), (50, 100)]
+image_corners = galvo_corners[:]
+enableDots = True
+
+laser_frame = BoxFrame.BoxFrame(galvo_corners)
+image_frame = BoxFrame.BoxFrame(image_corners)
+coeffs = MatrixConversion.find_coeffs(image_corners, galvo_corners)
+
+printer = Printer.Printer('COM5', coeffs)
+printer.begin()
+
+mouse = MouseManager.MouseManager(laser_frame, image_frame, printer)
+cv2.setMouseCallback('image', mouse.mouse_event)
+
+while(True):
+ ret, frame = cap.read()
+ Draw.drawImage(frame, laser_frame,coeffs, printer.position, enableDots)
+ cv2.imshow('image', frame)
+
+ command = cv2.waitKey(10) & 0xFF
+ if command == ord('q'):
+ break
+ elif command == ord('d'):
+ enableDots = not enableDots
+
+cap.release()
+cv2.destroyAllWindows()
\ No newline at end of file
--- /dev/null
+import serial
+from utils import MatrixConversion
+
+class Printer():
+ def __init__(self, COM, coeffs):
+ self.COM = COM
+ self.coeffs = coeffs
+ self.max_X = 250
+ self.max_Y = 200
+ self.ser = None
+ self.position = (0,0)
+
+ def begin(self):
+ print("Connecting")
+ try:
+ pass
+ #self.ser = serial.Serial('COM5', 9600, timeout=1)
+ #time.sleep(3)
+ except:
+ print("Connection Fail")
+
+ def withinBounds(self, xy):
+ x, y = xy
+ return (x > 0 and x < self.max_X) and (y > 0 and y < self.max_Y)
+
+ def writeRaw(self, xy):
+ x,y = xy
+ self.position = xy
+ command = 'G0 F5000 X%d Y%d'%(x, y)
+
+ if self.withinBounds(xy):
+ print(command)
+ else:
+ print('out of bounds')
+ # if self.ser not None:
+ # #self.ser.write(command.encode())
+ # return 1
+ # else:
+ # return 0
+
+ def write(self, xy, laser_frame):
+ galvo_points = [(self.max_X,self.max_Y), (0,self.max_Y), (0,0), (self.max_X,0)]
+ self.coeffs = MatrixConversion.find_coeffs(laser_frame.corners, galvo_points)
+ new_x, new_y = MatrixConversion.warped_xy( (xy), self.coeffs)
+ self.writeRaw((new_x, new_y))
+
+ def read(self):
+ print(ser.readline())
\ No newline at end of file
--- /dev/null
+from utils import MatrixConversion, Geometry
+
+class BoxFrame():
+ def __init__(self, corners):
+ self.corners = corners
+ self.selectedCorner = None
+
+ def isTouching(self, cursorPos, diameter):
+ index = 0
+ for point in self.corners:
+ if Geometry.distance(cursorPos, point) <= diameter:
+ self.selectedCorner = index
+ return True
+ else:
+ index += 1
+ # no touching corner
+ return False
+
+ def setSelected(self, point):
+ self.corners[self.selectedCorner] = point
+
+ # geometric center
+ def getCentroid(self):
+ x_total, y_total = 0, 0
+ for x, y in self.corners:
+ x_total += x
+ y_total += y
+ return ((x_total / 4), (y_total / 4))
+
+ def getCenter(self):
+ xy = (0,0)
+ simple = [(0,0),(1,0),(1,1),(0,1)]
+ coeffs = MatrixConversion.find_coeffs(simple, self.corners)
+ return MatrixConversion.warped_xy((0.5, 0.5), coeffs)
+
+ def getSize(self):
+ x_min, x_max, y_min, y_max = 0, 0, 0, 0
+ for x, y in self.corners:
+ x_min = x if x < x_min else x_min
+ x_max = x if x > x_max else x_max
+ y_min = y if y < y_min else y_min
+ y_max = y if y > y_max else y_max
+ return (x_max - x_min, y_max - y_min)
\ No newline at end of file
--- /dev/null
+import cv2
+
+def drawBox(image, points, color, thickness):
+ last_point = points[3]
+ for point in points:
+ cv2.line(image, last_point, point, color, thickness)
+ last_point = point
+
+def drawDots(image, points, size, color, thickness):
+ for point in points:
+ cv2.circle(image, point, size, color, thickness)
+ #Mark TopLeft corner with white dot
+ cv2.circle(image,points[0], 2, (255,255,255),-1)
+
+def drawImage(frame, laser_frame, coeffs, printerPosition ,enableDots):
+ drawBox(frame, laser_frame.corners, (255, 255, 255), 1)
+ if enableDots == True:
+ drawDots(frame, laser_frame.corners, 10, (0, 0, 255), -1)
+ x,y = laser_frame.getCenter()
+ cv2.circle(frame, (int(x),int(y)), 4, (0, 255, 0), 1)
+ cv2.putText(frame, str(laser_frame.corners), (20, 30), cv2.FONT_HERSHEY_COMPLEX, 0.5, (255, 255, 255))
+ cv2.putText(frame, str(laser_frame.getCenter()), (450, 450), cv2.FONT_HERSHEY_COMPLEX, 0.5, (255, 255, 255))
+ cx,cy = printerPosition
+ cv2.putText(frame, str((round(cx),round(cy))), (20, 450), cv2.FONT_HERSHEY_COMPLEX, 0.5, (255, 255, 255))
--- /dev/null
+import cv2
+
+class MouseManager:
+ def __init__(self, laser_frame, image_frame, printer):
+ self.laser_frame = laser_frame
+ self.image_frame = image_frame
+ self.printer = printer
+ self.mouseDrag = False
+ self.activeFrame = None
+
+ def mouse_event(self, event, x, y, flags, param):
+ if event == cv2.EVENT_LBUTTONDBLCLK:
+ pass
+
+ elif event == cv2.EVENT_LBUTTONDOWN:
+ self.mouseDrag = True
+ self.activeFrame = None
+ frames = (self.laser_frame, self.image_frame)
+ for frame in frames:
+ if frame.isTouching((x, y), 10):
+ self.activeFrame = frame
+ break
+ self.printer.write((x,y), self.laser_frame)
+
+ elif event == cv2.EVENT_LBUTTONUP:
+ self.mouseDrag = False
+ self.activeFrame = None
+
+ elif event == cv2.EVENT_MOUSEMOVE:
+ if self.mouseDrag:
+ if self.activeFrame != None:
+ self.activeFrame.setSelected((x, y))
--- /dev/null
+def distance(point_a, point_b):
+ return (((point_b[0] - point_a[0]) ** 2 + (point_b[1] - point_a[1]) ** 2) ** (0.5))
--- /dev/null
+import numpy as np
+
+def find_coeffs(pa, pb):
+ matrix = []
+ for p1, p2 in zip(pa, pb):
+ matrix.append([p1[0], p1[1], 1, 0, 0, 0, -p2[0]*p1[0], -p2[0]*p1[1]])
+ matrix.append([0, 0, 0, p1[0], p1[1], 1, -p2[1]*p1[0], -p2[1]*p1[1]])
+
+ A = np.matrix(matrix, dtype=np.float)
+ B = np.array(pb).reshape(8)
+
+ res = np.dot(np.linalg.inv(A.T * A) * A.T, B)
+ return np.array(res).reshape(8)
+
+def warped_xy(xy, coeffs):
+ x_in = xy[0]
+ y_in = xy[1]
+
+ #x = (ax+by+c)/(gx+hy+1)
+ #y = (dx+ey+f)/(gy+hy+1)
+ warped_x = (coeffs[0]*x_in + coeffs[1]*y_in + coeffs[2]) / (coeffs[6]*x_in + coeffs[7]*y_in + 1)
+ warped_y = (coeffs[3]*x_in + coeffs[4]*y_in + coeffs[5]) / (coeffs[6]*x_in + coeffs[7]*y_in + 1)
+ return (warped_x, warped_y)
\ No newline at end of file