fromitertoolsimportcombinations_with_replacementimportitertoolsimportnumpyasnpfromskimageimportfilters,featurefromskimage.util.dtypeimportimg_as_float32from.._shared._dependency_checksimportis_wasmifnotis_wasm:fromconcurrent.futuresimportThreadPoolExecutorasPoolExecutorelse:fromcontextlibimportAbstractContextManager# Threading isn't supported on WASM, mock ThreadPoolExecutor as a fallbackclassPoolExecutor(AbstractContextManager):def__init__(self,*_,**__):passdef__exit__(self,exc_type,exc_val,exc_tb):passdefmap(self,fn,iterables):returnmap(fn,iterables)def_texture_filter(gaussian_filtered):H_elems=[np.gradient(np.gradient(gaussian_filtered)[ax0],axis=ax1)forax0,ax1incombinations_with_replacement(range(gaussian_filtered.ndim),2)]eigvals=feature.hessian_matrix_eigvals(H_elems)returneigvalsdef_singlescale_basic_features_singlechannel(img,sigma,intensity=True,edges=True,texture=True):results=()gaussian_filtered=filters.gaussian(img,sigma=sigma,preserve_range=False)ifintensity:results+=(gaussian_filtered,)ifedges:results+=(filters.sobel(gaussian_filtered),)iftexture:results+=(*_texture_filter(gaussian_filtered),)returnresultsdef_mutiscale_basic_features_singlechannel(img,intensity=True,edges=True,texture=True,sigma_min=0.5,sigma_max=16,num_sigma=None,num_workers=None,):"""Features for a single channel nd image. Parameters ---------- img : ndarray Input image, which can be grayscale or multichannel. intensity : bool, default True If True, pixel intensities averaged over the different scales are added to the feature set. edges : bool, default True If True, intensities of local gradients averaged over the different scales are added to the feature set. texture : bool, default True If True, eigenvalues of the Hessian matrix after Gaussian blurring at different scales are added to the feature set. sigma_min : float, optional Smallest value of the Gaussian kernel used to average local neighborhoods before extracting features. sigma_max : float, optional Largest value of the Gaussian kernel used to average local neighborhoods before extracting features. num_sigma : int, optional Number of values of the Gaussian kernel between sigma_min and sigma_max. If None, sigma_min multiplied by powers of 2 are used. num_workers : int or None, optional The number of parallel threads to use. If set to ``None``, the full set of available cores are used. Returns ------- features : list List of features, each element of the list is an array of shape as img. """# computations are faster as float32img=np.ascontiguousarray(img_as_float32(img))ifnum_sigmaisNone:num_sigma=int(np.log2(sigma_max)-np.log2(sigma_min)+1)sigmas=np.logspace(np.log2(sigma_min),np.log2(sigma_max),num=num_sigma,base=2,endpoint=True,)withPoolExecutor(max_workers=num_workers)asex:out_sigmas=list(ex.map(lambdas:_singlescale_basic_features_singlechannel(img,s,intensity=intensity,edges=edges,texture=texture),sigmas,))features=itertools.chain.from_iterable(out_sigmas)returnfeatures
[文档]defmultiscale_basic_features(image,intensity=True,edges=True,texture=True,sigma_min=0.5,sigma_max=16,num_sigma=None,num_workers=None,*,channel_axis=None,):"""Local features for a single- or multi-channel nd image. Intensity, gradient intensity and local structure are computed at different scales thanks to Gaussian blurring. Parameters ---------- image : ndarray Input image, which can be grayscale or multichannel. intensity : bool, default True If True, pixel intensities averaged over the different scales are added to the feature set. edges : bool, default True If True, intensities of local gradients averaged over the different scales are added to the feature set. texture : bool, default True If True, eigenvalues of the Hessian matrix after Gaussian blurring at different scales are added to the feature set. sigma_min : float, optional Smallest value of the Gaussian kernel used to average local neighborhoods before extracting features. sigma_max : float, optional Largest value of the Gaussian kernel used to average local neighborhoods before extracting features. num_sigma : int, optional Number of values of the Gaussian kernel between sigma_min and sigma_max. If None, sigma_min multiplied by powers of 2 are used. num_workers : int or None, optional The number of parallel threads to use. If set to ``None``, the full set of available cores are used. channel_axis : int or None, optional If None, the image is assumed to be a grayscale (single channel) image. Otherwise, this parameter indicates which axis of the array corresponds to channels. .. versionadded:: 0.19 ``channel_axis`` was added in 0.19. Returns ------- features : np.ndarray Array of shape ``image.shape + (n_features,)``. When `channel_axis` is not None, all channels are concatenated along the features dimension. (i.e. ``n_features == n_features_singlechannel * n_channels``) """ifnotany([intensity,edges,texture]):raiseValueError("At least one of `intensity`, `edges` or `textures`""must be True for features to be computed.")ifchannel_axisisNone:image=image[...,np.newaxis]channel_axis=-1elifchannel_axis!=-1:image=np.moveaxis(image,channel_axis,-1)all_results=(_mutiscale_basic_features_singlechannel(image[...,dim],intensity=intensity,edges=edges,texture=texture,sigma_min=sigma_min,sigma_max=sigma_max,num_sigma=num_sigma,num_workers=num_workers,)fordiminrange(image.shape[-1]))features=list(itertools.chain.from_iterable(all_results))out=np.stack(features,axis=-1)returnout