import serial
							 | 
						|
								import threading
							 | 
						|
								import time
							 | 
						|
								
							 | 
						|
								class Frame():
							 | 
						|
								    def __init__(self, time, data):
							 | 
						|
								        self.time = time
							 | 
						|
								        self.data = data
							 | 
						|
								
							 | 
						|
								class GridEye():
							 | 
						|
								    def __init__(self, serialPort, baudrate):
							 | 
						|
								        self.port = serial.Serial(serialPort, baudrate)
							 | 
						|
								        self.frame1 = None
							 | 
						|
								        self.frame2 = None
							 | 
						|
								        self.reading = True
							 | 
						|
								        self.distance = -1
							 | 
						|
								        self.thread = threading.Thread(target = self.reader)
							 | 
						|
								        self.thread.setDaemon(True)
							 | 
						|
								        self.lock = threading.Lock()
							 | 
						|
								
							 | 
						|
								    def start(self):
							 | 
						|
								        self.port.reset_input_buffer()
							 | 
						|
								        self.thread.start()
							 | 
						|
								        
							 | 
						|
								    def stop(self):
							 | 
						|
								        self.reading = False
							 | 
						|
								        self.thread.join()
							 | 
						|
								        
							 | 
						|
								    def reader(self):
							 | 
						|
								        while (self.reading):
							 | 
						|
								            line = b''
							 | 
						|
								            while (self.reading):
							 | 
						|
								                c = self.port.read()
							 | 
						|
								                if c == b'\n':
							 | 
						|
								                    break
							 | 
						|
								                line += c
							 | 
						|
								            #line = self.port.readline()#.decode('utf-8')
							 | 
						|
								            # if line:
							 | 
						|
								                # print (line)
							 | 
						|
								                # time.sleep(0.01)
							 | 
						|
								            # if self.port.in_waiting > 0:
							 | 
						|
								                # print (self.port.in_waiting)
							 | 
						|
								            if b':' in line:
							 | 
						|
								                try:
							 | 
						|
								                    tag = line.decode('utf-8').split(':')[0]
							 | 
						|
								                    
							 | 
						|
								                    
							 | 
						|
								                    if 'Distance' in tag:
							 | 
						|
								                        dist = float(line.decode('utf-8').split(':')[1])
							 | 
						|
								                        if dist > 200.0:
							 | 
						|
								                            dist = 200.0
							 | 
						|
								                        self.lock.acquire()
							 | 
						|
								                        self.distance = dist
							 | 
						|
								                        self.lock.release()
							 | 
						|
								                    else:
							 | 
						|
								                        values = [int(x, 16)*0.25 for x in line.decode('utf-8').split(':')[1].split()]
							 | 
						|
								                        if len(values) == 64:
							 | 
						|
								                            #print (data)
							 | 
						|
								                            data = []
							 | 
						|
								                            for i in range(8):
							 | 
						|
								                                data.append(values[i*8:i*8+8])
							 | 
						|
								                            self.lock.acquire()
							 | 
						|
								                            if '105' in tag:
							 | 
						|
								                                self.frame1 = Frame(time.time(), data)
							 | 
						|
								                            else:
							 | 
						|
								                                self.frame2 = Frame(time.time(), data)
							 | 
						|
								                            self.lock.release()
							 | 
						|
								                        else:
							 | 
						|
								                            print ('something wrong', len(data))
							 | 
						|
								                except Exception as e:
							 | 
						|
								                    print (e)
							 | 
						|
								              
							 | 
						|
								        
							 | 
						|
								if __name__ == '__main__':
							 | 
						|
								    import cv2
							 | 
						|
								    import numpy as np
							 | 
						|
								    import math
							 | 
						|
								    import json
							 | 
						|
								    def exponential(img, value):
							 | 
						|
								        tmp = cv2.pow(img.astype(np.double), value)*(255.0/(255.0**value))
							 | 
						|
								        return tmp.astype(np.uint8)
							 | 
						|
								        
							 | 
						|
								    SIZE = 128
							 | 
						|
								    AVERAGE_FRAME = 10
							 | 
						|
								    distanceBetweenSensors_w = 2.6 #cm
							 | 
						|
								    distanceBetweenSensors_h = 2.6 #cm
							 | 
						|
								    distance2Object = 60.0 #cm
							 | 
						|
								    ADJUST_BACK = 5
							 | 
						|
								    EXPONENTAL_VALUE = 0.4
							 | 
						|
								    PRODUCTION_THRESHOLD = 100
							 | 
						|
								    MIN_EXIST_TIME = 0.5
							 | 
						|
								    W_ARRAY = np.array([list(range(SIZE*2)) for x in range(SIZE*2)])
							 | 
						|
								    H_ARRAY = np.array([[x]*(SIZE*2) for x in range(SIZE*2)])
							 | 
						|
								
							 | 
						|
								    grideye = GridEye('COM18', 115200)
							 | 
						|
								    grideye.start()
							 | 
						|
								    grideye2 = GridEye('COM24', 115200)
							 | 
						|
								    grideye2.start()
							 | 
						|
								    
							 | 
						|
								    # distanceSensor = Distance('COM18', 9600)
							 | 
						|
								    # distanceSensor.start()
							 | 
						|
								    
							 | 
						|
								    fourcc = cv2.VideoWriter_fourcc(*'XVID')
							 | 
						|
								    videoWriter = cv2.VideoWriter('output.avi', fourcc, 10.0, (SIZE*4,SIZE*4))
							 | 
						|
								    siftVideoWriter = cv2.VideoWriter('sift.avi', fourcc, 10.0, (SIZE*2,SIZE*1))
							 | 
						|
								    cv2.imshow('sample', np.zeros((SIZE*3,SIZE*2), np.uint8))
							 | 
						|
								    cnt = 0
							 | 
						|
								    avers = []
							 | 
						|
								    hasPos = False
							 | 
						|
								    endTime = 0
							 | 
						|
								    startTime = 0
							 | 
						|
								    while True:
							 | 
						|
								        if grideye.frame1 and grideye.frame2 and grideye2.frame1 and grideye2.frame2:
							 | 
						|
								            grideye.lock.acquire()
							 | 
						|
								            grideye2.lock.acquire()
							 | 
						|
								            frames = [grideye.frame1, grideye.frame2, grideye2.frame1, grideye2.frame2]
							 | 
						|
								            grideye.frame1 = None
							 | 
						|
								            grideye.frame2 = None
							 | 
						|
								            grideye2.frame1 = None
							 | 
						|
								            grideye2.frame2 = None
							 | 
						|
								            distance2Object = grideye.distance + grideye2.distance + 1
							 | 
						|
								            print (distance2Object)
							 | 
						|
								            if distance2Object <= 0:
							 | 
						|
								                distance2Object = 200
							 | 
						|
								            grideye2.lock.release()
							 | 
						|
								            grideye.lock.release()
							 | 
						|
								            with open('log.txt', 'a') as f:
							 | 
						|
								                f.write(json.dumps(frames[0].time)+'\n')
							 | 
						|
								                for frame in frames:
							 | 
						|
								                    f.write(json.dumps(frame.data)+'\n')
							 | 
						|
								                #print (json.dumps(frames))
							 | 
						|
								            imgs = []
							 | 
						|
								            for frame in frames:
							 | 
						|
								                img = (np.array(frame.data)-15)*10
							 | 
						|
								                img = cv2.resize(img.astype(np.uint8), (SIZE,SIZE), interpolation = cv2.INTER_LINEAR) # INTER_LINEAR, INTER_CUBIC
							 | 
						|
								                imgs.append(img)
							 | 
						|
								                avers.append(np.zeros((SIZE,SIZE), np.uint16))
							 | 
						|
								            
							 | 
						|
								            
							 | 
						|
								            if cnt < AVERAGE_FRAME:
							 | 
						|
								                cnt += 1
							 | 
						|
								                for i in range(len(imgs)):
							 | 
						|
								                    avers[i] += imgs[i]
							 | 
						|
								                if cnt == AVERAGE_FRAME:
							 | 
						|
								                    for i in range(len(avers)):
							 | 
						|
								                        avers[i] = avers[i]/AVERAGE_FRAME
							 | 
						|
								                        avers[i] = avers[i].astype(np.uint8)
							 | 
						|
								                        avers[i] += ADJUST_BACK
							 | 
						|
								                continue
							 | 
						|
								                
							 | 
						|
								            for i in range(len(imgs)):
							 | 
						|
								                imgs[i] = cv2.subtract(imgs[i], avers[i])
							 | 
						|
								            print ('xdd')
							 | 
						|
								            
							 | 
						|
								            out = np.full((SIZE*4, SIZE*4), 255, dtype=np.uint16)
							 | 
						|
								            out[:SIZE, :SIZE] = imgs[0]
							 | 
						|
								            out[:SIZE, SIZE:SIZE*2] = imgs[1]
							 | 
						|
								            out[SIZE:SIZE*2, :SIZE] = imgs[2]
							 | 
						|
								            out[SIZE:SIZE*2, SIZE:SIZE*2] = imgs[3]
							 | 
						|
								            '''
							 | 
						|
								            try:
							 | 
						|
								                overlap_w = int(SIZE - (distanceBetweenSensors_w / (2*distance2Object*math.tan(30.0/180.0*math.pi))) * SIZE)
							 | 
						|
								            except:
							 | 
						|
								                overlap_w = 0
							 | 
						|
								            if overlap_w < 0:
							 | 
						|
								                overlap_w = 0
							 | 
						|
								                
							 | 
						|
								            try:
							 | 
						|
								                overlap_h = int(SIZE - (distanceBetweenSensors_h / (2*distance2Object*math.tan(30.0/180.0*math.pi))) * SIZE)
							 | 
						|
								            except:
							 | 
						|
								                overlap_h = 0
							 | 
						|
								            if overlap_h < 0:
							 | 
						|
								                overlap_h = 0
							 | 
						|
								            
							 | 
						|
								            tmp = np.zeros((SIZE, SIZE*2-overlap_w), dtype=np.uint16)
							 | 
						|
								            tmp[:, :SIZE] = imgs[0]
							 | 
						|
								            tmp[:, -SIZE:] += imgs[1]
							 | 
						|
								            tmp[:, (SIZE-overlap_w): SIZE] = tmp[:, (SIZE-overlap_w): SIZE]/2
							 | 
						|
								            
							 | 
						|
								            tmp2 = np.zeros((SIZE, SIZE*2-overlap_w), dtype=np.uint16)
							 | 
						|
								            tmp2[:, :SIZE] = imgs[2]
							 | 
						|
								            tmp2[:, -SIZE:] += imgs[3]
							 | 
						|
								            tmp2[:, (SIZE-overlap_w): SIZE] = tmp2[:, (SIZE-overlap_w): SIZE]/2
							 | 
						|
								            
							 | 
						|
								            merge = np.zeros((SIZE*2-overlap_h, SIZE*2-overlap_w), dtype=np.uint16)
							 | 
						|
								            merge[:SIZE, :] = tmp
							 | 
						|
								            merge[-SIZE:, :] += tmp2
							 | 
						|
								            merge[(SIZE-overlap_h):SIZE, :] = merge[(SIZE-overlap_h):SIZE, :]/2
							 | 
						|
								            # merge = exponential(merge, EXPONENTAL_VALUE)
							 | 
						|
								            
							 | 
						|
								            
							 | 
						|
								            offset_w = int(overlap_w/2)
							 | 
						|
								            offset_h = int(overlap_h/2)
							 | 
						|
								            print (SIZE*2+offset_h, SIZE*4-overlap_h+offset_h, offset_w, SIZE*2-overlap_w+offset_w)
							 | 
						|
								            out[SIZE*2+offset_h:SIZE*4-overlap_h+offset_h, offset_w: SIZE*2-overlap_w+offset_w] = merge
							 | 
						|
								            
							 | 
						|
								            
							 | 
						|
								            maxProduct = 0
							 | 
						|
								            overlap_w = 0
							 | 
						|
								            for i in range(80, 128):
							 | 
						|
								                product = sum(imgs[0][:,SIZE-i:].astype(np.uint32)*imgs[1][:,:i].astype(np.uint32))
							 | 
						|
								                product += sum(imgs[2][:,SIZE-i:].astype(np.uint32)*imgs[3][:,:i].astype(np.uint32))
							 | 
						|
								                product = sum(product) / len(product)
							 | 
						|
								                if product > maxProduct:
							 | 
						|
								                    maxProduct = product
							 | 
						|
								                    overlap_w = i
							 | 
						|
								                    
							 | 
						|
								            tmp = maxProduct
							 | 
						|
								            maxProduct = 0
							 | 
						|
								            overlap_h = 0
							 | 
						|
								            for i in range(80, 128):
							 | 
						|
								                product = sum(imgs[0][SIZE-i:, :].astype(np.uint32)*imgs[2][:i,:].astype(np.uint32))
							 | 
						|
								                product += sum(imgs[1][SIZE-i:, :].astype(np.uint32)*imgs[3][:i,:].astype(np.uint32))
							 | 
						|
								                product = sum(product) / len(product)
							 | 
						|
								                if product > maxProduct:
							 | 
						|
								                    maxProduct = product
							 | 
						|
								                    overlap_h = i
							 | 
						|
								            maxProduct = (tmp + maxProduct)/2
							 | 
						|
								            
							 | 
						|
								            tmp = np.zeros((SIZE, SIZE*2-overlap_w), dtype=np.uint16)
							 | 
						|
								            tmp[:, :SIZE] = imgs[0]
							 | 
						|
								            tmp[:, -SIZE:] += imgs[1]
							 | 
						|
								            tmp[:, (SIZE-overlap_w): SIZE] = tmp[:, (SIZE-overlap_w): SIZE]/2
							 | 
						|
								            
							 | 
						|
								            tmp2 = np.zeros((SIZE, SIZE*2-overlap_w), dtype=np.uint16)
							 | 
						|
								            tmp2[:, :SIZE] = imgs[2]
							 | 
						|
								            tmp2[:, -SIZE:] += imgs[3]
							 | 
						|
								            tmp2[:, (SIZE-overlap_w): SIZE] = tmp2[:, (SIZE-overlap_w): SIZE]/2
							 | 
						|
								            
							 | 
						|
								            merge = np.zeros((SIZE*2-overlap_h, SIZE*2-overlap_w), dtype=np.uint16)
							 | 
						|
								            merge[:SIZE, :] = tmp
							 | 
						|
								            merge[-SIZE:, :] += tmp2
							 | 
						|
								            merge[(SIZE-overlap_h):SIZE, :] = merge[(SIZE-overlap_h):SIZE, :]/2
							 | 
						|
								            
							 | 
						|
								                
							 | 
						|
								            offset_w = int(overlap_w/2)
							 | 
						|
								            offset_h = int(overlap_h/2)
							 | 
						|
								            out[SIZE*2+offset_h:SIZE*4-overlap_h+offset_h, SIZE*2+offset_w: SIZE*4-overlap_w+offset_w] = merge
							 | 
						|
								            '''
							 | 
						|
								            # offset = int(overlap2/2)
							 | 
						|
								            # tmp = np.zeros((SIZE, SIZE*2-overlap2), dtype=np.uint16)
							 | 
						|
								            # tmp[:, :SIZE] = img
							 | 
						|
								            # tmp[:, -SIZE:] += img2
							 | 
						|
								            # tmp[:, (SIZE-overlap2): SIZE] = tmp[:, (SIZE-overlap2): SIZE]/2
							 | 
						|
								            # tmp = exponential(tmp, EXPONENTAL_VALUE)
							 | 
						|
								            # out[SIZE*2:, offset: SIZE*2-overlap2+offset] = tmp
							 | 
						|
								            
							 | 
						|
								            
							 | 
						|
								            out = out.astype(np.uint8)
							 | 
						|
								            out = exponential(out, EXPONENTAL_VALUE)
							 | 
						|
								            
							 | 
						|
								            out = cv2.cvtColor(out,cv2.COLOR_GRAY2BGR)
							 | 
						|
								            if False and maxProduct > PRODUCTION_THRESHOLD:
							 | 
						|
								                print ('XDDDD',maxProduct)
							 | 
						|
								                position = [0,0]
							 | 
						|
								                rows,cols = merge.shape
							 | 
						|
								                position[0] = sum(sum(H_ARRAY[:rows,:cols]*merge))/sum(sum(merge))
							 | 
						|
								                position[1] = sum(sum(W_ARRAY[:rows,:cols]*merge))/sum(sum(merge))
							 | 
						|
								                pos_w = distanceBetweenSensors_w/(SIZE-overlap_w)*position[0]
							 | 
						|
								                pos_h = distanceBetweenSensors_h/(SIZE-overlap_h)*position[1]
							 | 
						|
								                cv2.circle(out, (SIZE*2+offset_w+int(position[1]), SIZE*2+offset_h+int(position[0])), 10, (255,0,0), 5)
							 | 
						|
								                if not hasPos:
							 | 
						|
								                    startPos = [pos_w, pos_h]
							 | 
						|
								                    startTime = frames[0].time
							 | 
						|
								                    hasPos = True
							 | 
						|
								                endPos = [pos_w, pos_h]
							 | 
						|
								                endTime = frames[0].time
							 | 
						|
								            elif hasPos:
							 | 
						|
								                if endTime - startTime > MIN_EXIST_TIME:
							 | 
						|
								                    print (startPos, endPos)
							 | 
						|
								                    print ('speed:', ((endPos[0]-startPos[0])**2+(endPos[1]-startPos[1])**2)**0.5/(endTime - startTime))
							 | 
						|
								                    print ('time:', endTime-startTime)
							 | 
						|
								                hasPos = False
							 | 
						|
								            if endTime - startTime > MIN_EXIST_TIME:
							 | 
						|
								                speed = ((endPos[0]-startPos[0])**2+(endPos[1]-startPos[1])**2)**0.5/(endTime - startTime)
							 | 
						|
								                cv2.putText(out, f'{speed:.2f}',
							 | 
						|
								                        (0, SIZE*2),cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2, cv2.LINE_AA)
							 | 
						|
								                
							 | 
						|
								            cv2.imshow('sample', out)
							 | 
						|
								            videoWriter.write(out)
							 | 
						|
								        key = cv2.waitKey(1)
							 | 
						|
								        if key == ord('q'):
							 | 
						|
								            break
							 | 
						|
								        elif key == ord('c'):
							 | 
						|
								            cv2.imwrite('out.jpg', out)
							 | 
						|
								            with open('log_captured.txt', 'a') as f:
							 | 
						|
								                f.write(json.dumps(frames[0].time)+'\n')
							 | 
						|
								                for frame in frames:
							 | 
						|
								                    f.write(json.dumps(frame.data)+'\n')
							 | 
						|
								        time.sleep(0.001)
							 | 
						|
								    grideye.stop()
							 | 
						|
								    videoWriter.release()
							 | 
						|
								    siftVideoWriter.release()
							 | 
						|
								    cv2.destroyAllWindows()
							 | 
						|
								    
							 |