class BoardCalibrator(object): imgpoints = [] def __init__(self, input=0, camera=None, imgpts=None, board=None): if not isinstance(camera, Camera): camera = Camera(device=input) self.camera = camera self.frame,reseted = self.camera.get_image() if board is None: self.board = Board() else: self.board = board allobj = self.board._get_configs() [i.append(0) for i in allobj] nobj = np.array(allobj, np.float64) if imgpts is None: cv2.namedWindow("Calibration Window", cv2.WINDOW_NORMAL) cv2.namedWindow("Calibration Hint", cv2.WINDOW_NORMAL) cv2.imshow("Calibration Window", self.frame) cv2.waitKey(1) config_points = nobj cv2.setMouseCallback("Calibration Window", self.click) pos = 0 for i in config_points: print ("Select field %s please. Accept with any key." % str(i)) hintim = self.board.get_config_hint(pos) cv2.imshow("Calibration Hint", hintim) k = cv2.waitKey(-1) & 0xFF self.imgpoints.append(self.imgpoint) if k == 27: print("Escaped and closing.") break else: print("Thank you") pos += 1 else: self.imgpoints = imgpts print("Imagepoints %s" % self.imgpoints) print("Objp %s" % nobj) print(self.camera.config['dist']) print(np.array(self.camera.config['mtx'])) _, rvec, tvec = cv2.solvePnP(nobj, np.array(self.imgpoints, np.float64), np.array(self.camera.config['mtx']), np.array(self.camera.config['dist']), None,None, False, cv2.SOLVEPNP_ITERATIVE) mean_error = 0 imgpoints2, _ = cv2.projectPoints(nobj, rvec, tvec, self.camera.cameramatrix, self.camera.config['dist']) impoints = np.array([[x] for x in self.imgpoints], np.float64) error = cv2.norm(impoints, imgpoints2, cv2.NORM_L2) / len(imgpoints2) mean_error += error print "total error: ", mean_error outers = self.board.get_radius() def calcy(x,r): return np.sqrt(np.power(r,2)-np.power(x,2)) points = [] for outer in outers: xs = [i*0.1 for i in range(0,int(outer*10))] xs += [i*-0.1 for i in range(0,int(outer*10))] for i in xs: y = calcy(i,int(outer)) points.append([[i],[y],[0]]) points.append([[i], [-y], [0]]) points = np.array(points) # points = np.array([[[0],[0],[0]], [[outer],[0],[0]]]) imp, jac = cv2.projectPoints(points, rvec,tvec, np.array(self.camera.config['mtx']), np.array(self.camera.config['dist'])) rot, _ = cv2.Rodrigues(rvec) rev = projectReverse(self.imgpoints,rot, tvec, self.camera.config['mtx']) self.rot = rot self.tvec = tvec # b.draw_board_to_frame(frame2) print("Imagepoints %s" % self.imgpoints) print("Objecpoints %s" % rev) cv2.destroyAllWindows() self.imp = imp # cv2.setMouseCallback("Calibration Window", self._calcObj) # while True: # self.frame,reseted = self.camera.get_image() # self.frame = self.camera.undistort_image(self.frame) # for i in imp: # try: # self.frame[i[0][1], i[0][0]] = [0,0,255] # except IndexError: # pass # # self.frame = cv2.circle(self.frame,(int(np.round(imp[0][0][0])), int(np.round(imp[0][0][1]))),int(np.round(dist)),[0,0,255],1) # cv2.imshow("Calibration Window", self.frame) # k = cv2.waitKey(1) & 0xFF # if k == 27: # break # # k = cv2.waitKey(-1) & 0xFF def calculate_points(self, point): x,y = point objp = projectReverse(np.array([[[x],[y]]]), self.rot, self.tvec,self.camera.config['mtx']) return self.board.calculate_field(objp[0][:2]) def _calcObj(self, event, x, y, flags, param): if event == cv2.EVENT_LBUTTONDOWN: print("Clicked %s: %s" % (x, y)) objp = projectReverse(np.array([[[x],[y]]]), self.rot, self.tvec, self.camera.config['mtx']) print "Object Point %s"%objp print "Field: %s" %self.board.calculate_field(objp[0][:2]) def click(self, event, x, y, flags, param): if event == cv2.EVENT_LBUTTONDOWN: print("Clicked %s: %s" % (x, y)) self.imgpoint = [x,y] # self.imgpoints.append([x, y]) def _get_line_in_pic(self, points): x_coords, y_coords = zip(*points) # print (x_coords) # print (y_coords) A = vstack([x_coords, ones(len(x_coords))]).T m, c = lstsq(A, y_coords)[0] x1 = (0 - c) / m # print ("x: %s , y: %s" % (x1, 0)) x2 = (height - c) / m # print("x: %s , y: %s" % (x2, height)) return x1, x2 def _make_rotation_transformation(self, angle, origin=(0, 0)): cos_theta, sin_theta = math.cos(angle), math.sin(angle) x0, y0 = origin def xform(point): x, y = point[0] - x0, point[1] - y0 return (x * cos_theta - y * sin_theta + x0, x * sin_theta + y * cos_theta + y0) return xform def _rotate_point(self, point, rangle): b = point[1] # hieght # print("a: %s" % b) a = point[0] # # print("b %s" % a) angle = math.atan(a / b) # print("angle %s" % math.degrees(angle)) dangle = math.degrees(angle) c = b / math.cos(angle) # print ("c %s" % c) ndangle = dangle + rangle nangle = math.radians(ndangle) na = math.sin(nangle) * c # print("New a %s" % na) nb = math.cos(nangle) * c # print("New b %s" % nb) return na, nb
class MainApplikacation(object): detected = [] detected2 = [] detected3 = [] detected4 = [] detected5 = [] real = [] was_covert = [] frame_no = [] Calibrated = None Substractor = None input = None camera = None board_config_load = True date = datetime.now().strftime("%Y-%m-%d-%H-%M") fname = "data%s"%date imgpoint = None boardpoint = None def write_data(self): print "Writing data to file" i = 0 fname = self.fname fname += ".csv" while os.path.isfile(fname): i += 1 fname = self.fname + '-' + str(i)+".csv" with open(fname, 'wb') as csvfile: spamwriter = csv.writer(csvfile, delimiter=',',dialect='excel', quotechar='|', quoting=csv.QUOTE_MINIMAL) spamwriter.writerow(['Detected','Detected2','Detected3','Detected4','Detected5', 'Reality', 'Was Covert', 'Frameno', 'Diff', 'Diff2', 'Diff3', 'Diff4', 'Diff5']) def calc_diff(a,b): i = 0 diff = [] for each in a: try: if each == b[i]: diff.append(True) else: diff.append(False) except: print "For some Reasion there was an error in diff calc" i += 1 percentage = float(len([x for x in diff if x is True])) / float(len(diff)) return diff, percentage diff, percentage = calc_diff(self.detected, self.real) print "Tip Version 1 was %s Percent correct."%(percentage * 100) diff2, percentage = calc_diff(self.detected2, self.real) print "Tip Version 2 was %s Percent correct." % (percentage * 100) diff3, percentage = calc_diff(self.detected3, self.real) print "Tip Version 3 was %s Percent correct." % (percentage * 100) diff4, percentage = calc_diff(self.detected4, self.real) print "Tip Version 4 was %s Percent correct." % (percentage * 100) diff5, percentage = calc_diff(self.detected5, self.real) print "Tip Version 5 was %s Percent correct." % (percentage * 100) datas = zip(self.detected, self.detected2, self.detected3, self.detected4, self.detected5, self.real, self.was_covert, self.frame_no, diff,diff2, diff3, diff4, diff5) for each in datas: entry = list(each) # if each[0] == each[1]: # entry.append(True) # else: # entry.append(False) spamwriter.writerow(entry) def __init__(self, inp): if isinstance(inp,str): self.fname = inp.split('.')[0] self.camera = Camera(device=inp, output=self.fname) self.board = Board() camconf = "camera_config.json" baord_conf = "boardconfig.json" if os.path.isfile(camconf): self.camera.load_config(filename=camconf) else: self.camera.do_calibration(img=True) self.camera.save_config(camconf) if self.board_config_load and os.path.isfile(baord_conf): with open(baord_conf, 'r') as bc: imgps = json.loads(bc.readline()) self.Calibrated = BoardCalibrator(camera=self.camera, imgpts=imgps, board=self.board) else: self.Calibrated = BoardCalibrator(camera=self.camera) with open("boardconfig.json", 'w') as bc: imgps = self.Calibrated.imgpoints bc.write(json.dumps(imgps)) self.Substractor = BackgroundSubtractor(c1=inp,camera=self.camera) plt.ion() self.figure = plt.figure() self.plt1 = self.figure.add_subplot(111) self.line1, = self.plt1.plot(range(200), [0] * 200, 'r.-') self.plt1.axis([0, 200, 0, 10000]) cv2.namedWindow("Current", cv2.WINDOW_NORMAL) cv2.moveWindow("Current", 20,20) cv2.namedWindow("Original", cv2.WINDOW_NORMAL) cv2.moveWindow("Original", 20, 500) cv2.namedWindow("Points", cv2.WINDOW_NORMAL) cv2.moveWindow("Current", 1000, 20) cv2.namedWindow("Blobimg", cv2.WINDOW_NORMAL) cv2.setMouseCallback("Points", self._click) mixer.init() mixer.music.load('beep.mp3') # cv2.namedWindow("FG Substraction", cv2.WINDOW_NORMAL) # cv2.createTrackbar("History", "Current", self.history, 1000, self._set_history) # cv2.createTrackbar("Shadow Treshold", "Current", int(self.shad_tresh * 100), 100, self._set_shad_tresh) # cv2.createTrackbar("VarThreshold", "Current", self.var_tresh, 100, self._set_var_tresh) # cv2.createTrackbar("VarMax", "Current", self.var_max, 100, self._set_var_max) # cv2.createTrackbar("VarMin", "Current", self.var_min, 100, self._set_var_min) self.Substractor.start() realboard = np.zeros((self.camera.height, self.camera.width, 3), np.uint8) # self.frame = self.camera.undistort_image(img) for i in self.Calibrated.imp: try: realboard[i[0][1], i[0][0]] = [0,0,255] except IndexError: pass added = 0 while True: img = self.Substractor.get_image() if img is not None: img = cv2.add(realboard,img) cv2.imshow("Original", img) cv2.imshow("Points", self.board.draw_board()) if self.Substractor.stopped: self.write_data() exit() cv2.imshow("Current", self.Substractor.get_substracted()) storage, unaltered = self.Substractor.get_storage() y = [x[2] for x in storage] y = unaltered self.line1.set_xdata(range(len(y))) self.line1.set_ydata(y) k = cv2.waitKey(1) if k == ord('a'): self.add_dart(frame_no=self.camera.read_frame_no) if k == ord('s'): self.write_data() if k == ord('w'): pass self.figure.savefig(r"thesisimages/plot.jpg") if k == ord('f'): added = 0 self.Substractor.clear_arrows() if k == 27: self.Substractor.stopped = True break if k == 119: print "Pressed w Key so Waiting" cv2.waitKey(-1) arrows = self.Substractor.get_arrows() i = 1 for each in arrows: tip = each.tip frame_no = each.frame_no points = self.Calibrated.calculate_points(tip) if i > added: self.add_dart(arrow=each, detected=points, frame_no=frame_no) added += 1 i += 1 if added >= 3: added = 0 self.Substractor.clear_arrows() self.write_data() def _click(self, event, x, y, flags, param): if event == cv2.EVENT_LBUTTONDOWN: nx = x - self.board.size / 2 ny = self.board.size / 2 - y print("Clicked %s " % self.board.calculate_field([[nx],[ny]])) self.imgpoint = [x, y] self.boardpoint = [[nx],[ny]] # self.imgpoints.append([x, y]) def add_dart(self, arrow=None, detected="N/D", frame_no=0): self.Substractor.paused = True # mixer.music.play() if arrow is not None: print "Ratio is %s"%arrow.ratio print [cv2.contourArea(x) for x in arrow.contours] points = self.Calibrated.calculate_points(arrow.tip) pimg = self.board.draw_field(points) cv2.imshow("Points", pimg) cv2.imshow("Blobimg", arrow.img) k = -1 while k not in [13, 32]or self.boardpoint is None: k = cv2.waitKey(-1) if k == 13: print "Enter" print len(self.detected) self.was_covert.append(False) if k == 32: self.was_covert.append(True) self.real.append(self.board.calculate_field(self.boardpoint)) self.boardpoint = None