Source code for vip_hci.stats.im_stats

#! /usr/bin/env python

"""
Module for image statistics.
"""

__author__ = 'Carlos Alberto Gomez Gonzalez'
__all__ = ['frame_histo_stats',
           'frame_average_radprofile']

import numpy as np
import pandas as pd
from matplotlib import pyplot as plt
from ..var import frame_center, mask_circle
from ..config.utils_conf import check_array, vip_figsize


[docs] def frame_average_radprofile(frame, sep=1, init_rad=None, subtr_profile=False, plot=True): """ Calculates the average radial profile of an image. Parameters ---------- frame : numpy ndarray Input image or 2d array. sep : int, optional The average radial profile is recorded every ``sep`` pixels. init_rad : int, optional Initial radius in pixels from the center of the image to begin calculating the average radial profile. subtr_profile : boolean, optional If True, the average radial profile is subtracted from the frame and returned as a second output. Inner mask is applied if init_rad is provided. plot : bool, optional If True, the profile is plotted. Returns ------- df : dataframe Pandas dataframe with the radial profile and distances. subtr_frame : numpy ndarray, 2d [subtr_profile=True] Frame with the radial profile subtracted. Note ---- https://stackoverflow.com/questions/21242011/most-efficient-way-to-calculate-radial-profile https://stackoverflow.com/questions/48842320/what-is-the-best-way-to-calculate-radial-average-of-the-image-with-python https://github.com/keflavich/image_tools/blob/master/image_tools/radialprofile.py """ check_array(frame, dim=2) cy, cx = frame_center(frame) if init_rad is None: init_rad = 1 x, y = np.indices(frame.shape) r = np.sqrt((x - cx) ** 2 + (y - cy) ** 2) r = r.astype(int) tbin = np.bincount(r.ravel(), frame.ravel()) nr = np.bincount(r.ravel()) radprofile = tbin / nr radists = np.arange(init_rad + 1, int(cy), sep) - 1 radprofile_radists = radprofile[radists] nr_radists = nr[radists] df = pd.DataFrame({'rad': radists, 'radprof': radprofile_radists, 'npx': nr_radists}) if plot: plt.figure(figsize=vip_figsize) plt.plot(radists, radprofile_radists, '.-', alpha=0.6) plt.grid(which='both', alpha=0.4) plt.xlabel('Pixels') plt.ylabel('Counts') plt.minorticks_on() plt.xlim(0) if subtr_profile: radprofile_img = radprofile[r] subtr_frame = frame - radprofile_img if init_rad > 1: subtr_frame = mask_circle(subtr_frame, radius=init_rad) return df, subtr_frame else: return df
[docs] def frame_histo_stats(image_array, plot=True): """Plots a frame with a colorbar, its histogram and some statistics: mean, median, maximum, minimum and standard deviation values. Parameters ---------- image_array : numpy ndarray The input frame. plot : bool, optional If True plots the frame and the histogram with the values. Return ------ mean : float Mean value of array. median : float Median value of array. std : float Standard deviation of array. maxim : int or float Maximum value. minim : int or float Minimum value. """ vector = image_array.flatten() mean = vector.mean() median = np.median(vector) maxim = vector.max() minim = vector.min() std = vector.std() if plot: fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(10, 4)) ax0, ax1 = axes.flat bins = int(np.sqrt(vector.shape[0])) txt = 'Mean = {:.3f}\n'.format(mean) + \ 'Median = {:.3f}\n'.format(median) +\ 'Stddev = {:.3f}\n'.format(std) +\ 'Max = {:.3f}\n'.format(maxim) +\ 'Min = {:.3f}\n\n'.format(minim) ax0.imshow(image_array, interpolation="nearest", origin="lower", cmap='viridis') ax0.set_title('Frame') ax0.grid('off') ax1.hist(vector, bins=bins, label=txt, alpha=0.5, histtype='stepfilled') ax1.set_yscale('log') ax1.set_title('Histogram') ax1.text(0.98, 0.98, txt, transform=ax1.transAxes, fontsize=12, verticalalignment='top', horizontalalignment='right') plt.show() return mean, median, std, maxim, minim