Example #1
0
 def test_get_virtual_electron_diffraction_no_intensities(
         self, vdf_segments: VDFSegment, signal_data):
     vdf_segments.intensities = None
     vdf_segments.get_virtual_electron_diffraction(
         calibration=1,
         sigma=1,
         shape=signal_data.axes_manager.signal_shape)
Example #2
0
 def test_get_virtual_electron_diffraction_no_intensities(
     self, vdf_segments: VDFSegment, signal_data
 ):
     vdf_segments.intensities = None
     with pytest.raises(
         ValueError,
         match="VDFSegment does not have the attribute intensities, required for this method",
     ):
         vdf_segments.get_virtual_electron_diffraction(
             calibration=1, sigma=1, shape=signal_data.axes_manager.signal_shape
         )
Example #3
0
 def test_get_virtual_electron_diffraction(self, vdf_segments: VDFSegment,
                                           signal_data):
     corrsegs = vdf_segments.correlate_vdf_segments(0.1, 1, 1)
     vs = corrsegs.get_virtual_electron_diffraction(
         calibration=1, sigma=1,
         shape=signal_data.axes_manager.signal_shape)
     assert isinstance(vs, ElectronDiffraction2D)
Example #4
0
 def test_get_virtual_electron_diffraction_for_single_vectors(
     self, vdf_segments: VDFSegment, signal_data
 ):
     vs = vdf_segments.get_virtual_electron_diffraction(
         calibration=1, sigma=1, shape=signal_data.axes_manager.signal_shape
     )
     assert isinstance(vs, ElectronDiffraction2D)
Example #5
0
 def test_correlate_segments(self, vdf_segments: VDFSegment,
                             corr_threshold, vector_threshold,
                             segment_threshold):
     corrsegs = vdf_segments.correlate_vdf_segments(
         corr_threshold, vector_threshold, segment_threshold)
     assert isinstance(corrsegs.segments, Signal2D)
     assert isinstance(corrsegs.vectors_of_segments, DiffractionVectors)
     assert isinstance(corrsegs.intensities, np.ndarray)
Example #6
0
 def test_correlate_segments_bad_thresholds(self, vdf_segments: VDFSegment):
     with pytest.raises(
         ValueError,
         match="segment_threshold must be smaller than or equal to vector_threshold",
     ):
         corrsegs = vdf_segments.correlate_vdf_segments(
             vector_threshold=4, segment_threshold=5
         )
Example #7
0
    def get_vdf_segments(
        self,
        min_distance=1,
        min_size=1,
        max_size=np.inf,
        max_number_of_grains=np.inf,
        marker_radius=1,
        threshold=False,
        exclude_border=False,
    ):
        """Separate segments from each of the VDF images using
        edge-detection by the Sobel transform and the watershed
        segmentation method implemented in scikit-image [1,2]. Obtain a
        VDFSegment, similar to VDFImage, but where each image is a
        segment of a VDF and the vectors correspond to each segment and
        are not necessarily unique.

        Parameters
        ----------
        min_distance: int
            Minimum distance (in pixels) between grains required for
            them to be considered as separate grains.
        min_size : float
            Grains with size (i.e. total number of pixels) below
            min_size are discarded.
        max_size : float
            Grains with size (i.e. total number of pixels) above
            max_size are discarded.
        max_number_of_grains : int
            Maximum number of grains included in the returned separated
            grains. If it is exceeded, those with highest peak
            intensities will be returned.
        marker_radius : float
            If 1 or larger, each marker for watershed is expanded to a disk
            of radius marker_radius. marker_radius should not exceed
            2*min_distance.
        threshold: bool
            If True, a mask is calculated by thresholding the VDF image
            by the Li threshold method in scikit-image. If False
            (default), the mask is the boolean VDF image.
        exclude_border : int or True, optional
            If non-zero integer, peaks within a distance of
            exclude_border from the boarder will be discarded. If True,
            peaks at or closer than min_distance of the boarder, will be
            discarded.

        References
        ----------
        [1] http://scikit-image.org/docs/dev/auto_examples/segmentation/
            plot_watershed.html
        [2] http://scikit-image.org/docs/dev/auto_examples/xx_applications/
            plot_coins_segmentation.html#sphx-glr-auto-examples-xx-
            applications-plot-coins-segmentation-py

        Returns
        -------
        vdfsegs : VDFSegment
            VDFSegment object containing segments (i.e. grains) of
            single virtual dark field images with corresponding vectors.
        """
        vdfs = self.copy()
        vectors = self.vectors.data

        # TODO : Add aperture radius as an attribute of VDFImage?

        # Create an array of length equal to the number of vectors where each
        # element is a np.object with shape (n: number of segments for this
        # VDFImage, VDFImage size x, VDFImage size y).
        vdfsegs = np.array(
            vdfs.map(
                separate_watershed,
                show_progressbar=True,
                inplace=False,
                min_distance=min_distance,
                min_size=min_size,
                max_size=max_size,
                max_number_of_grains=max_number_of_grains,
                marker_radius=marker_radius,
                threshold=threshold,
                exclude_border=exclude_border,
            ),
            dtype=np.object,
        )

        segments, vectors_of_segments = [], []
        for i, vector in zip(np.arange(vectors.size), vectors):
            segments = np.append(segments, vdfsegs[i])
            num_segs = np.shape(vdfsegs[i])[0]
            vectors_of_segments = np.append(
                vectors_of_segments, np.broadcast_to(vector, (num_segs, 2))
            )

        vectors_of_segments = vectors_of_segments.reshape((-1, 2))
        segments = segments.reshape(
            (
                np.shape(vectors_of_segments)[0],
                vdfs.axes_manager.signal_shape[0],
                vdfs.axes_manager.signal_shape[1],
            )
        )
        # Calculate the total intensities of each segment
        segment_intensities = np.array(
            [[np.sum(x, axis=(0, 1))] for x in segments], dtype="object"
        )

        # if TraitError is raised, it is likely no segments were found
        segments = Signal2D(segments).transpose(navigation_axes=[0], signal_axes=[2, 1])
        # Create VDFSegment and transfer axes calibrations
        vdfsegs = VDFSegment(
            segments, DiffractionVectors(vectors_of_segments), segment_intensities
        )
        vdfsegs.segments = transfer_signal_axes(vdfsegs.segments, vdfs)
        n = vdfsegs.segments.axes_manager.navigation_axes[0]
        n.name = "n"
        n.units = "number"
        vdfsegs.vectors_of_segments.axes_manager.set_signal_dimension(1)
        vdfsegs.vectors_of_segments = transfer_signal_axes(
            vdfsegs.vectors_of_segments, self.vectors
        )
        n = vdfsegs.vectors_of_segments.axes_manager.navigation_axes[0]
        n.name = "n"
        n.units = "number"

        return vdfsegs
Example #8
0
 def test_corelate_segments_bad_thresholds(self, vdf_segments: VDFSegment):
     corrsegs = vdf_segments.correlate_vdf_segments(vector_threshold=4,
                                                    segment_threshold=5)
Example #9
0
 def test_correlate_segments_small_vector_threshold(self, vdf_segments: VDFSegment):
     corrsegs = vdf_segments.correlate_vdf_segments(
         corr_threshold=0.7, vector_threshold=0, segment_threshold=-1)
Example #10
0
 def test_correlate_segments_cropped(self, vdf_segments_cropped: VDFSegment):
     corrsegs = vdf_segments_cropped.correlate_vdf_segments(0.9, 1, 0)
     assert isinstance(corrsegs.segments, Signal2D)
     assert isinstance(corrsegs.vectors_of_segments, DiffractionVectors)
     assert isinstance(corrsegs.intensities, np.ndarray)
Example #11
0
def vdf_segments_cropped(vdf_segments):
    return VDFSegment(vdf_segments.segments.inav[:4],
                      vdf_segments.vectors_of_segments.inav[:4])