Example #1
0
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
Example #2
0
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