- 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()
-
|