def test_convolution2(self):
     # corresponds to convolution_test02 in C++
     sampling.set_focus_coordinates(0, 0)
     vector_field = np.array(
         [[[0., 0.], [0., 0.], [-0.35937524, -0.18750024],
           [-0.13125, -0.17500037]],
          [[0., 0.], [-0.4062504, -0.4062496], [-0.09375, -0.1874992],
           [-0.04375001, -0.17499907]],
          [[0., 0.], [-0.65624946, -0.21874908], [-0.09375, -0.1499992],
           [-0.04375001, -0.21874908]],
          [[0., 0.], [-0.5312497, -0.18750025], [-0.09374999, -0.15000032],
           [-0.13125001, -0.2625004]]],
         dtype=np.float32)
     kernel = np.array([0.06742075, 0.99544406, 0.06742075],
                       dtype=np.float32)
     expected_output = np.array(
         [[[0., 0.], [0., 0.], [-0.37140754, -0.21091977],
           [-0.1575381, -0.19859035]],
          [[0., 0.], [-0.45495197, -0.43135524], [-0.1572882, -0.25023922],
           [-0.06344876, -0.21395193]],
          [[0., 0.], [-0.7203466, -0.2682102], [-0.15751791, -0.20533603],
           [-0.06224134, -0.2577237]],
          [[0., 0.], [-0.57718134, -0.2112256], [-0.14683421, -0.19089346],
           [-0.13971105, -0.2855439]]],
         dtype=np.float32)
     mc.convolve_with_kernel_preserve_zeros(vector_field, np.flip(kernel))
     self.assertTrue(np.allclose(vector_field, expected_output, rtol=0.0))
    def test_convolve_with_kernel_preserve_zeros01(self):
        sampling.set_focus_coordinates(0, 0)
        field = np.array([1, 4, 7, 2, 5, 8, 3, 6, 9], dtype=np.float32).reshape(3, 3)
        vector_field = np.dstack([field] * 2)
        kernel = np.array([1, 2, 3])
        mc.convolve_with_kernel_preserve_zeros(vector_field, np.flip(kernel))
        expected_output = np.dstack([np.array([[85, 168, 99],
                                               [124, 228, 132],
                                               [67, 120, 69]], dtype=np.float32)] * 2)

        self.assertTrue(np.allclose(vector_field, expected_output))
Example #3
0
    def __optimization_iteration_direct(self,
                                        warped_live_field,
                                        canonical_field,
                                        warp_field,
                                        data_component_field=None,
                                        smoothing_component_field=None,
                                        level_set_component_field=None,
                                        band_union_only=True):

        self.total_data_energy = 0.
        self.total_smoothing_energy = 0.
        self.total_level_set_energy = 0.

        field_size = warp_field.shape[0]

        live_gradient_y, live_gradient_x = np.gradient(warped_live_field)

        for y in range(0, field_size):
            for x in range(0, field_size):
                if focus_coordinates_match(x, y):
                    print("Point: ", x, ",", y, sep='', end='')

                gradient = 0.0

                live_sdf = warped_live_field[y, x]

                live_is_truncated = value_outside_narrow_band(live_sdf)

                if band_union_only and voxel_is_outside_narrow_band_union(
                        warped_live_field, canonical_field, x, y):
                    continue

                data_gradient, local_data_energy = \
                    dt.compute_local_data_term(warped_live_field, canonical_field, x, y, live_gradient_x,
                                               live_gradient_y, method=self.data_term_method)
                scaled_data_gradient = self.data_term_weight * data_gradient
                self.total_data_energy += self.data_term_weight * local_data_energy
                gradient += scaled_data_gradient
                if focus_coordinates_match(x, y):
                    print(" Data grad: ",
                          BOLD_GREEN,
                          -data_gradient,
                          RESET,
                          sep='',
                          end='')
                if data_component_field is not None:
                    data_component_field[y, x] = data_gradient
                if self.level_set_term_enabled and not live_is_truncated:
                    level_set_gradient, local_level_set_energy = \
                        level_set_term_at_location(warped_live_field, x, y)
                    scaled_level_set_gradient = self.level_set_term_weight * level_set_gradient
                    self.total_level_set_energy += self.level_set_term_weight * local_level_set_energy
                    gradient += scaled_level_set_gradient
                    if level_set_component_field is not None:
                        level_set_component_field[y, x] = level_set_gradient
                    if focus_coordinates_match(x, y):
                        print(" Level-set grad (scaled): ",
                              BOLD_GREEN,
                              -scaled_level_set_gradient,
                              RESET,
                              sep='',
                              end='')

                smoothing_gradient, local_smoothing_energy = \
                    st.compute_local_smoothing_term_gradient(warp_field, x, y, method=self.smoothing_term_method,
                                                             copy_if_zero=False,
                                                             isomorphic_enforcement_factor=
                                                             self.isomorphic_enforcement_factor)
                scaled_smoothing_gradient = self.smoothing_term_weight * smoothing_gradient
                self.total_smoothing_energy += self.smoothing_term_weight * local_smoothing_energy
                gradient += scaled_smoothing_gradient
                if smoothing_component_field is not None:
                    smoothing_component_field[y, x] = smoothing_gradient
                if focus_coordinates_match(x, y):
                    print(" Smoothing grad (scaled): ",
                          BOLD_GREEN,
                          -scaled_smoothing_gradient,
                          RESET,
                          sep='',
                          end='')

                self.gradient_field[y, x] = gradient

        if self.sobolev_smoothing_enabled:
            convolve_with_kernel_preserve_zeros(self.gradient_field,
                                                self.sobolev_kernel, True)

        max_warp = 0.0
        max_warp_location = -1

        # update the warp field based on the gradient
        for y in range(0, field_size):
            for x in range(0, field_size):
                warp_field[y, x] = -self.gradient_field[
                    y, x] * self.gradient_descent_rate
                if focus_coordinates_match(x, y):
                    print(" Warp: ",
                          BOLD_GREEN,
                          warp_field[y, x],
                          RESET,
                          " Warp length: ",
                          BOLD_GREEN,
                          np.linalg.norm(warp_field[y, x]),
                          RESET,
                          sep='')
                warp_length = np.linalg.norm(warp_field[y, x])
                if warp_length > max_warp:
                    max_warp = warp_length
                    max_warp_location = Point2d(x, y)
                if (x, y) in self.focus_neighborhood_log:
                    log = self.focus_neighborhood_log[(x, y)]
                    log.warp_magnitudes.append(warp_length)
                    log.sdf_values.append(warped_live_field[y, x])

        new_warped_live_field = resample_warped_live(canonical_field,
                                                     warped_live_field,
                                                     warp_field,
                                                     self.gradient_field,
                                                     band_union_only=False,
                                                     known_values_only=False,
                                                     substitute_original=False)
        np.copyto(warped_live_field, new_warped_live_field)

        return max_warp, max_warp_location
Example #4
0
    def __optimization_iteration_vectorized(self,
                                            warped_live_field,
                                            canonical_field,
                                            warp_field,
                                            band_union_only=True):

        live_gradient_y, live_gradient_x = np.gradient(warped_live_field)
        data_gradient_field = dt.compute_data_term_gradient_vectorized(
            warped_live_field, canonical_field, live_gradient_x,
            live_gradient_y)
        set_zeros_for_values_outside_narrow_band_union(warped_live_field,
                                                       canonical_field,
                                                       data_gradient_field)
        self.total_data_energy = \
            dt.compute_data_term_energy_contribution(warped_live_field, canonical_field) * self.data_term_weight
        smoothing_gradient_field = st.compute_smoothing_term_gradient_vectorized(
            warp_field)
        self.total_smoothing_energy = \
            st.compute_smoothing_term_energy(warp_field, warped_live_field,
                                             canonical_field) * self.smoothing_term_weight

        if self.visualizer.data_component_field is not None:
            np.copyto(self.visualizer.data_component_field,
                      data_gradient_field)
        if self.visualizer.smoothing_component_field is not None:
            np.copyto(self.visualizer.smoothing_component_field,
                      smoothing_gradient_field)
        if self.visualizer.level_set_component_field is not None:
            frame_info = getframeinfo(currentframe())
            print(
                "Warning: level set term not implemented in vectorized version, "
                "passed level_set_component_field is not None, {:s} : {:d}".
                format(frame_info.filename, frame_info.lineno))

        self.gradient_field = self.data_term_weight * data_gradient_field + \
                              self.smoothing_term_weight * smoothing_gradient_field

        if band_union_only:
            set_zeros_for_values_outside_narrow_band_union(
                warped_live_field, canonical_field, self.gradient_field)

        # *** Print information at focus voxel
        focus_x, focus_y = get_focus_coordinates()
        focus = (focus_y, focus_x)
        print("Point: ", focus_x, ",", focus_y, sep='', end='')
        dt.compute_local_data_term(warped_live_field,
                                   canonical_field,
                                   focus_x,
                                   focus_y,
                                   live_gradient_x,
                                   live_gradient_y,
                                   method=dt.DataTermMethod.BASIC)
        focus_data_gradient = data_gradient_field[focus]
        print(" Data grad: ",
              BOLD_GREEN,
              -focus_data_gradient,
              RESET,
              sep='',
              end='')

        st.compute_local_smoothing_term_gradient(
            warp_field,
            focus_x,
            focus_y,
            method=self.smoothing_term_method,
            copy_if_zero=False,
            isomorphic_enforcement_factor=self.isomorphic_enforcement_factor)
        focus_smoothing_gradient = smoothing_gradient_field[
            focus] * self.smoothing_term_weight
        print(" Smoothing grad (scaled): ",
              BOLD_GREEN,
              -focus_smoothing_gradient,
              RESET,
              sep='',
              end='')

        # ***
        if self.sobolev_smoothing_enabled:
            convolve_with_kernel_preserve_zeros(self.gradient_field,
                                                self.sobolev_kernel, True)

        np.copyto(warp_field,
                  -self.gradient_field * self.gradient_descent_rate)
        warp_lengths = np.linalg.norm(warp_field, axis=2)
        maximum_warp_length_at = np.unravel_index(np.argmax(warp_lengths),
                                                  warp_lengths.shape)
        maximum_warp_length = warp_lengths[maximum_warp_length_at]

        # ***
        print(" Warp: ",
              BOLD_GREEN,
              warp_field[focus],
              RESET,
              " Warp length: ",
              BOLD_GREEN,
              np.linalg.norm(warp_field[focus]),
              RESET,
              sep='')
        # ***

        get_and_print_interpolation_data(canonical_field, warped_live_field,
                                         warp_field, focus_x, focus_y)

        u_vectors = warp_field[:, :, 0].copy()
        v_vectors = warp_field[:, :, 1].copy()

        out_warped_live_field, (out_u_vectors, out_v_vectors) = \
            cpp_extension.resample(warped_live_field, canonical_field, u_vectors, v_vectors)

        np.copyto(warped_live_field, out_warped_live_field)

        # some entries might have been erased due to things in the live sdf becoming truncated
        warp_field[:, :, 0] = out_u_vectors
        warp_field[:, :, 1] = out_v_vectors

        return maximum_warp_length, Point2d(maximum_warp_length_at[1],
                                            maximum_warp_length_at[0])