예제 #1
0
    def test_match_detection_to_ref(self):
        """Match detection to reference (sortgrid)"""
        xyz_input = np.array([(10, 10, 10), (200, 200, 200), (600, 800, 100),
                              (20, 10, 2000), (30, 30, 30)],
                             dtype=float)
        coords_count = len(xyz_input)

        xy_img_pts_metric = image_coordinates(
            xyz_input, self.calibration, self.control.get_multimedia_params())
        xy_img_pts_pixel = convert_arr_metric_to_pixel(xy_img_pts_metric,
                                                       control=self.control)

        # convert to TargetArray object
        target_array = TargetArray(coords_count)

        for i in range(coords_count):
            target_array[i].set_pnr(i)
            target_array[i].set_pos(
                (xy_img_pts_pixel[i][0], xy_img_pts_pixel[i][1]))

        # create randomized target array
        indices = range(coords_count)
        shuffled_indices = range(coords_count)

        while indices == shuffled_indices:
            random.shuffle(shuffled_indices)

        rand_targ_array = TargetArray(coords_count)
        for i in range(coords_count):
            rand_targ_array[shuffled_indices[i]].set_pos(target_array[i].pos())
            rand_targ_array[shuffled_indices[i]].set_pnr(target_array[i].pnr())

        # match detection to reference
        matched_target_array = match_detection_to_ref(cal=self.calibration,
                                                      ref_pts=xyz_input,
                                                      img_pts=rand_targ_array,
                                                      cparam=self.control)

        # assert target array is as before
        for i in range(coords_count):
            if matched_target_array[i].pos() != target_array[i].pos() \
                    or matched_target_array[i].pnr() != target_array[i].pnr():
                self.fail()

        # pass ref_pts and img_pts with non-equal lengths
        with self.assertRaises(ValueError):
            match_detection_to_ref(cal=self.calibration,
                                   ref_pts=xyz_input,
                                   img_pts=TargetArray(coords_count - 1),
                                   cparam=self.control)
예제 #2
0
    def test_full_calibration(self):
        ref_pts = np.array([
            a.flatten() for a in np.meshgrid(np.r_[-60:-30:4j], np.r_[0:15:4j],
                                             np.r_[0:15:4j])
        ]).T

        # Fake the image points by back-projection
        targets = convert_arr_metric_to_pixel(
            image_coordinates(ref_pts, self.cal,
                              self.control.get_multimedia_params()),
            self.control)

        # Full calibration works with TargetArray objects, not NumPy.
        target_array = TargetArray(len(targets))
        for i in xrange(len(targets)):
            target_array[i].set_pnr(i)
            target_array[i].set_pos(targets[i])

        # Perturb the calibration object, then compore result to original.
        self.cal.set_pos(self.cal.get_pos() + np.r_[15., -15., 15.])
        self.cal.set_angles(self.cal.get_angles() + np.r_[-.5, .5, -.5])

        ret, used, err_est = full_calibration(self.cal, ref_pts, target_array,
                                              self.control)

        np.testing.assert_array_almost_equal(self.cal.get_angles(),
                                             self.orig_cal.get_angles(),
                                             decimal=4)
        np.testing.assert_array_almost_equal(self.cal.get_pos(),
                                             self.orig_cal.get_pos(),
                                             decimal=3)
예제 #3
0
    def test_fill_target_array(self):
        tarr = TargetArray(2)
        tarr[0].set_pos((1.5, 2.5))
        tarr[1].set_pos((3.5, 4.5))

        self.assertEqual(tarr[0].pos(), (1.5, 2.5))
        self.assertEqual(tarr[1].pos(), (3.5, 4.5))
예제 #4
0
    def test_full_corresp(self):
        """Full scene correspondences"""
        cpar = ControlParams(4)
        cpar.read_control_par(r"testing_fodder/corresp/control.par")
        vpar = VolumeParams()
        vpar.read_volume_par(r"testing_fodder/corresp/criteria.par")

        # Cameras are at so high angles that opposing cameras don't see each
        # other in the normal air-glass-water setting.
        cpar.get_multimedia_params().set_layers([1.0001], [1.])
        cpar.get_multimedia_params().set_n3(1.0001)

        cals = []
        img_pts = []
        corrected = []
        for c in xrange(4):
            cal = Calibration()
            cal.from_file(
                "testing_fodder/calibration/sym_cam%d.tif.ori" % (c + 1),
                "testing_fodder/calibration/cam1.tif.addpar")
            cals.append(cal)

            # Generate test targets.
            targs = TargetArray(16)
            for row, col in np.ndindex(4, 4):
                targ_ix = row * 4 + col
                # Avoid symmetric case:
                if (c % 2):
                    targ_ix = 15 - targ_ix
                targ = targs[targ_ix]

                pos3d = 10 * np.array([[col, row, 0]], dtype=np.float64)
                pos2d = image_coordinates(pos3d, cal,
                                          cpar.get_multimedia_params())
                targ.set_pos(convert_arr_metric_to_pixel(pos2d, cpar)[0])

                targ.set_pnr(targ_ix)
                targ.set_pixel_counts(25, 5, 5)
                targ.set_sum_grey_value(10)

            img_pts.append(targs)
            mc = MatchedCoords(targs, cpar, cal)
            corrected.append(mc)

        sorted_pos, sorted_corresp, num_targs = correspondences(
            img_pts, corrected, cals, vpar, cpar)

        self.failUnlessEqual(num_targs, 16)
예제 #5
0
    def test_single_cam_corresp(self):
        """Single camera correspondence"""
        cpar = ControlParams(1)
        cpar.read_control_par("testing_fodder/single_cam/parameters/ptv.par")
        vpar = VolumeParams()
        vpar.read_volume_par(
            "testing_fodder/single_cam/parameters/criteria.par")

        # Cameras are at so high angles that opposing cameras don't see each
        # other in the normal air-glass-water setting.
        cpar.get_multimedia_params().set_layers([1.], [1.])
        cpar.get_multimedia_params().set_n3(1.)

        cals = []
        img_pts = []
        corrected = []
        cal = Calibration()
        cal.from_file(
            "testing_fodder/single_cam/calibration/cam_1.tif.ori",
            "testing_fodder/single_cam/calibration/cam_1.tif.addpar")
        cals.append(cal)

        # Generate test targets.
        targs = TargetArray(9)
        for row, col in np.ndindex(3, 3):
            targ_ix = row * 3 + col
            targ = targs[targ_ix]

            pos3d = 10 * np.array([[col, row, 0]], dtype=np.float64)
            pos2d = image_coordinates(pos3d, cal, cpar.get_multimedia_params())
            targ.set_pos(convert_arr_metric_to_pixel(pos2d, cpar)[0])

            targ.set_pnr(targ_ix)
            targ.set_pixel_counts(25, 5, 5)
            targ.set_sum_grey_value(10)

            img_pts.append(targs)
            mc = MatchedCoords(targs, cpar, cal)
            corrected.append(mc)

        sorted_pos, sorted_corresp, num_targs = correspondences(
            img_pts, corrected, cals, vpar, cpar)

        self.failUnlessEqual(num_targs, 9)
예제 #6
0
    def _button_fine_orient_fired(self):
        """
        fine tuning of ORI and ADDPAR

        """
        scale = 5000

        if self.need_reset:
            self.reset_show_images()
            self.need_reset = 0

        # backup the ORI/ADDPAR files first
        self.backup_ori_files()

        op = par.OrientParams()
        op.read()

        # recognized names for the flags:
        names = [
            'cc', 'xh', 'yh', 'k1', 'k2', 'k3', 'p1', 'p2', 'scale', 'shear'
        ]
        op_names = [
            op.cc, op.xh, op.yh, op.k1, op.k2, op.k3, op.p1, op.p2, op.scale,
            op.shear
        ]

        flags = []
        for name, op_name in zip(names, op_names):
            if (op_name == 1):
                flags.append(name)

        for i_cam in range(self.n_cams):  # iterate over all cameras

            if self.epar.Combine_Flag:

                self.status_text = "Multiplane calibration."
                """ Performs multiplane calibration, in which for all cameras the 
                pre-processed planes in multi_plane.par combined.
                Overwrites the ori and addpar files of the cameras specified 
                in cal_ori.par of the multiplane parameter folder
                """

                all_known = []
                all_detected = []

                for i in range(self.MultiParams.n_planes
                               ):  # combine all single planes

                    # c = self.calParams.img_ori[i_cam][-9] # Get camera id
                    c = re.findall('\\d+', self.calParams.img_ori[i_cam])[
                        0]  # not all ends with a number

                    file_known = self.MultiParams.plane_name[i] + c + '.tif.fix'
                    file_detected = self.MultiParams.plane_name[
                        i] + c + '.tif.crd'

                    # Load calibration point information from plane i
                    try:
                        known = np.loadtxt(file_known)
                        detected = np.loadtxt(file_detected)
                    except:
                        raise IOError("reading {} or {} failed".format(
                            file_known, file_detected))

                    if np.any(detected == -999):
                        raise ValueError(
                            ("Using undetected points in {} will cause " +
                             "silliness. Quitting.").format(file_detected))

                    num_known = len(known)
                    num_detect = len(detected)

                    if num_known != num_detect:
                        raise ValueError("Number of detected points (%d) does not match" +\
                        " number of known points (%d) for %s, %s" % \
                        (num_known, num_detect, file_known, file_detected))

                    if len(all_known) > 0:
                        detected[:,
                                 0] = all_detected[-1][-1, 0] + 1 + np.arange(
                                     len(detected))

                    # Append to list of total known and detected points
                    all_known.append(known)
                    all_detected.append(detected)

                # Make into the format needed for full_calibration.
                all_known = np.vstack(all_known)[:, 1:]
                all_detected = np.vstack(all_detected)

                # this is the main difference in the multiplane mode
                # that we fill the targs and cal_points by the
                # combined information

                targs = TargetArray(len(all_detected))
                for tix in range(len(all_detected)):
                    targ = targs[tix]
                    det = all_detected[tix]

                    targ.set_pnr(tix)
                    targ.set_pos(det[1:])

                self.cal_points = np.empty(
                    (all_known.shape[0], )).astype(dtype=[('id',
                                                           'i4'), ('pos',
                                                                   '3f8')])
                self.cal_points['pos'] = all_known
            else:
                targs = self.sorted_targs[i_cam]

            try:
                residuals, targ_ix, err_est = full_calibration(self.cals[i_cam], self.cal_points['pos'], \
                                                           targs, self.cpar, flags)
            except:
                raise ValueError("full calibration failed\n")
            # save the results
            self._write_ori(i_cam, addpar_flag=True)

            # Plot the output
            # self.reset_plots()

            x, y = [], []
            for r, t in zip(residuals, targ_ix):
                if t != -999:
                    pos = targs[t].pos()
                    x.append(pos[0])
                    y.append(pos[1])

            self.camera[i_cam]._plot.overlays = []
            self.drawcross("orient_x",
                           "orient_y",
                           x,
                           y,
                           'orange',
                           5,
                           i_cam=i_cam)

            # self.camera[i]._plot_data.set_data(
            #     'imagedata', self.ori_img[i].astype(np.float))
            # self.camera[i]._img_plot = self.camera[
            #     i]._plot.img_plot('imagedata', colormap=gray)[0]
            self.camera[i_cam].drawquiver(x, y,
                                          x + scale * residuals[:len(x), 0],
                                          y + scale * residuals[:len(x), 1],
                                          "red")
            # self.camera[i]._plot.index_mapper.range.set_bounds(0, self.h_pixel)
            # self.camera[i]._plot.value_mapper.range.set_bounds(0, self.v_pixel)

        self.status_text = "Orientation finished."
예제 #7
0
def py_multiplanecalibration(exp):
    """ Performs multiplane calibration, in which for all cameras the pre-processed plane in multiplane.par al combined.
		Overwrites the ori and addpar files of the cameras specified in cal_ori.par of the multiplane parameter folder
        """

    for i_cam in range(exp.n_cams):  # iterate over all cameras
        all_known = []
        all_detected = []
        for i in range(exp.MultiParams.n_planes):  # combine all single planes

            c = exp.calParams.img_ori[i_cam][-9]  # Get camera id

            file_known = exp.MultiParams.plane_name[i] + str(c) + '.tif.fix'
            file_detected = exp.MultiParams.plane_name[i] + str(c) + '.tif.crd'

            # Load calibration point information from plane i
            known = np.loadtxt(file_known)
            detected = np.loadtxt(file_detected)

            if np.any(detected == -999):
                raise ValueError(
                    ("Using undetected points in {} will cause " +
                     "silliness. Quitting.").format(file_detected))

            num_known = len(known)
            num_detect = len(detected)

            if num_known != num_detect:
                raise ValueError("Number of detected points (%d) does not match" +\
                " number of known points (%d) for %s, %s" % \
                (num_known, num_detect, file_known, file_detected))

            if len(all_known) > 0:
                detected[:, 0] = all_detected[-1][-1, 0] + 1 + np.arange(
                    len(detected))

            # Append to list of total known and detected points
            all_known.append(known)
            all_detected.append(detected)

        # Make into the format needed for full_calibration.
        all_known = np.vstack(all_known)[:, 1:]
        all_detected = np.vstack(all_detected)

        targs = TargetArray(len(all_detected))
        for tix in range(len(all_detected)):
            targ = targs[tix]
            det = all_detected[tix]

            targ.set_pnr(tix)
            targ.set_pos(det[1:])

        # backup the ORI/ADDPAR files first
        exp.backup_ori_files()

        op = par.OrientParams()
        op.read()

        # recognized names for the flags:
        names = [
            'cc', 'xh', 'yh', 'k1', 'k2', 'k3', 'p1', 'p2', 'scale', 'shear'
        ]
        op_names = [
            op.cc, op.xh, op.yh, op.k1, op.k2, op.k3, op.p1, op.p2, op.scale,
            op.shear
        ]

        flags = []
        for name, op_name in zip(names, op_names):
            if (op_name == 1):
                flags.append(name)

        # Run the multiplane calibration
        residuals, targ_ix, err_est = full_calibration(exp.cals[0], all_known,
                                                       targs, exp.cpar, flags)

        #Save the results
        exp._write_ori(i_cam,
                       addpar_flag=True)  # addpar_flag to save addpar file
        print('End multiplane')