Unverified Commit 3567ee1c authored by AustinSanders's avatar AustinSanders Committed by GitHub
Browse files

Adjusted parameters and added image_diff_squared (#462)



* Added blob_detector

* fixed image_array declaration

* Changed nearest neighbors to points instead of indices

* import atan2

* import pi

* Working prototype blob_detection.

* Demo change_detection.blob_detector functionality

* Updated documentation n_sigma -> num_sigma

* Addressed PR reviews.

Added returns to docstring.
Added configurable additive / subtractive change detection + docstring
Moved nested function to top.

* Added function description + citation to docstring

* Added new diff function, modified default parameters

* Removed unused num_sigma

* Added additional blob_log parameters

Co-authored-by: default avatarAustin Sanders <arsanders@ugs.gov>
parent 0d861576
Loading
Loading
Loading
Loading
+44 −14
Original line number Diff line number Diff line
@@ -24,6 +24,10 @@ def image_diff(arr1, arr2):
     return diff


def image_diff_sq(arr1, arr2):
     return image_diff(arr1, arr2)**2


def okubogar_detector(image1, image2, nbins=50, extractor_method="orb", image_func=image_diff,
                      extractor_kwargs={"nfeatures": 2000, "scaleFactor": 1.1, "nlevels": 1}):
     """
@@ -219,9 +223,10 @@ def okbm_detector(image1, image2, nbins=50, extractor_method="orb", image_func=
     return polys, weights, bdiff


def blob_detector(image1, image2, sub_solar_azimuth, image_func=image_diff,
                  subtractive=False, max_sigma=30, num_sigma=10, threshold=.075,
                  n_neighbors=3, dist_upper_bound=5, angle_tolerance=10):
def blob_detector(image1, image2, sub_solar_azimuth, image_func=image_diff_sq,
                  subtractive=False,  min_sigma=.45, max_sigma=30, num_sigma=10,
                  threshold=.25, overlap=.5, log_scale=False, exclude_border=False,
                  n_neighbors=3, dist_upper_bound=5, angle_tolerance=3):
     """
     Blob based change detection.

@@ -272,6 +277,13 @@ def blob_detector(image1, image2, sub_solar_azimuth, image_func=image_diff,
                   words, find locations in which a feature "used to be present"
                   but has since moved.

     min_sigma : scalar or sequence of scalars
                 The minimum standard deviation for Gaussian kernel. Keep this
                 low to detect smaller blobs. The standard deviations of the
                 Gaussian filter are given for each axis as a sequence, or as a
                 single number, in which case it is equal for all axes.


     max_sigma : scalar or sequence of scalars
                 The maximum standard deviation for Gaussian kernel. Keep this
                 high to detect larger blobs. The standard deviations of the
@@ -280,13 +292,31 @@ def blob_detector(image1, image2, sub_solar_azimuth, image_func=image_diff,

     num_sigma : int
                 The number of intermediate values of standard deviations to
               consider.
                 consider between min_sigma and max_sigma.

     threshold : float
                 The absolute lower bound for scale space maxima.
                 Local maxima smaller than thresh are ignored.
                 Reduce this to detect blobs with less intensities.

     overlap : float
               A value between 0 and 1. If the area of two blobs overlaps by a
               fraction greater than threshold, the smaller blob is eliminated.

     log_scale : bool
                 If set intermediate values of standard deviations are
                 interpolated using a logarithmic scale to the base 10. If not,
                 linear interpolation is used.

     exclude_border: tuple of ints, int, or False
                 If tuple of ints, the length of the tuple must match the input
                 array’s dimensionality. Each element of the tuple will exclude
                 peaks from within exclude_border-pixels of the border of the
                 image along that dimension. If nonzero int, exclude_border
                 excludes peaks from within exclude_border-pixels of the border
                 of the image. If zero or False, peaks are identified regardless
                 of their distance from the border.

     n_neighbors : int
                   Number of closest neighbors (blobs) to search.

@@ -331,21 +361,21 @@ def blob_detector(image1, image2, sub_solar_azimuth, image_func=image_diff,
     if isinstance(image2, GeoDataset):
         image2 = image2.read_array()

     image1[image1 == image1.min()] = 0
     image2[image2 == image2.min()] = 0
     arr1 = bytescale(image1)
     arr2 = bytescale(image2)

     bdiff = image_func(arr1, arr2)
     bdiff = image_func(image1,image2)
     bdiff = bytescale(bdiff)

     # Laplacian of Gaussian only finds light blobs on a dark image.  In order to
     #  find dark blobs on a light image, we invert.
     inv = 255-bdiff
     inv = bdiff.max()-bdiff

     # Laplacian of Gaussian of diff image (light on dark)
     blobs_log = blob_log(bdiff, max_sigma=max_sigma, num_sigma=num_sigma, threshold=threshold)
     blobs_log = blob_log(bdiff, min_sigma=min_sigma, max_sigma=max_sigma,
                          num_sigma=num_sigma, threshold=threshold, overlap=overlap,
                          log_scale=log_scale, exclude_border=exclude_border)
     # Laplacian of Gaussian on diff image (inverse -- dark on light)
     blobs_log_inv = blob_log(inv, max_sigma=max_sigma, num_sigma=num_sigma, threshold=threshold)
     blobs_log_inv = blob_log(inv, min_sigma=min_sigma, max_sigma=max_sigma,
                              num_sigma=num_sigma, threshold=threshold, overlap=overlap,
                              log_scale=log_scale, exclude_border=exclude_border)
     # Compute radii in the 3rd column.  Radii are appx equal to sqrt2 * sigma
     blobs_log[:, 2] = blobs_log[:, 2] * sqrt(2)
     blobs_log_inv[:, 2] = blobs_log_inv[:, 2] * sqrt(2)