def match_hist(image, cdf, bin_centers, nbins=256): '''Modify pixels of input image so that its histogram matches target image histogram, specified by: cdf, bin_centers = cumulative_distribution(target_image) Parameters ---------- image : array Image to be transformed. cdf : 1D array Values of cumulative distribution function of the target histogram. bin_centers ; 1D array Centers of bins of the target histogram. nbins : int, optional Number of bins for image histogram. Returns ------- out : float array Image array after histogram matching. References ---------- [1] Matlab implementation histoMatch(MTX, N, X) by Simoncelli, 7/96. ''' image = img_as_float(image) old_cdf, old_bin = exposure.cumulative_distribution(image, nbins) # Unlike [1], we didn't add small positive number to the histogram new_bin = np.interp(old_cdf, cdf, bin_centers) out = np.interp(image.ravel(), old_bin, new_bin) return out.reshape(image.shape)
def test_equalize_ubyte(): with expected_warnings(['precision loss']): img = skimage.img_as_ubyte(test_img) img_eq = exposure.equalize_hist(img) cdf, bin_edges = exposure.cumulative_distribution(img_eq) check_cdf_slope(cdf)
def plot_img_and_hist(img, axes, bins=256): """Plot an image along with its histogram and cumulative histogram. """ img = img_as_float(img) ax_img, ax_hist = axes ax_cdf = ax_hist.twinx() # Display image ax_img.imshow(img, cmap=plt.cm.gray) ax_img.set_axis_off() ax_img.set_adjustable('box-forced') # Display histogram ax_hist.hist(img.ravel(), bins=bins, histtype='step', color='black') ax_hist.ticklabel_format(axis='y', style='scientific', scilimits=(0, 0)) ax_hist.set_xlabel('Pixel intensity') ax_hist.set_xlim(0, 1) ax_hist.set_yticks([]) # Display cumulative distribution img_cdf, bins = exposure.cumulative_distribution(img, bins) ax_cdf.plot(bins, img_cdf, 'r') ax_cdf.set_yticks([]) return ax_img, ax_hist, ax_cdf
def plithist(im, nbins=256): f = plt.figure(figsize=(6, 6)) plt.hist(im.ravel(), bins=nbins, histtype='step', color='black') img_cdf, bins = exposure.cumulative_distribution(im, nbins) plt.plot(bins, img_cdf, 'r') plt.ticklabel_format(axis='y', style='scientific', scilimits=(0, 0)) plt.xlabel('Pixel intensity') plt.xlim(0, 1) plt.yticks([])
def test_equalize_masked(): img = skimage.img_as_float(test_img) mask = np.zeros(test_img.shape) mask[50:150, 50:250] = 1 img_mask_eq = exposure.equalize_hist(img, mask=mask) img_eq = exposure.equalize_hist(img) cdf, bin_edges = exposure.cumulative_distribution(img_mask_eq) check_cdf_slope(cdf) assert not (img_eq == img_mask_eq).all()
def plot_hist(img, bins=256): """Plot histogram and cumulative histogram for image""" img_cdf, bins = exposure.cumulative_distribution(img, bins) plt.hist(img.ravel(), bins=bins) plt.ylabel('Number of pixels') plt.xlabel('Pixel intensiy') ax_cdf = plt.twinx() ax_cdf.plot(bins, img_cdf, 'r') xmin, xmax = dtype_range[img.dtype.type] plt.xlim(xmin, xmax) ax_cdf.set_ylabel('Fraction of total intensity')
def plot_img_and_hist(img, axes, bins=256): img = img_as_float(img) ax_img, ax_hist = axes ax_cdf = ax_hist.twinx() ax_img.imshow(img, cmap=plt.cm.gray) ax_img.set_axis_off() ax_hist.hist(img.ravel(), bins=bins, histtype='step', color='black') ax_hist.ticklabel_format(axis='y', style='scientific', scilimits=(0, 0)) ax_hist.set_xlabel('Pixel intensity') ax_hist.set_xlim(0, 1) ax_hist.set_yticks([]) img_cdf, bins = exposure.cumulative_distribution(img, bins) ax_cdf.plot(bins, img_cdf, 'r') ax_cdf.set_yticks([]) return ax_img, ax_hist, ax_cdf
def RFshow(data,ax=None,cmap='RdYlBu',cmap_norm='equalize',hs=True, zf=10,azdeg=45,altdeg=45,dx=1,dy=1,fraction=1.5,blend_mode='alpha', alpha=0.7,contours=False,levels=32,colorbar=True,cb_contours=False, cb_ticks='linear',nSigma=1,fRange=None,FFTbins=512,**kwargs): # equalize the colormap: cdf, bins = exposure.cumulative_distribution(data[~np.isnan(data)].flatten(),nbins=256) my_cmap = equalizeColormap(cmap,bins,cdf) # convert input data to masked array data = np.ma.masked_array(data, np.isnan(data)) fig = ax.get_figure() im = ax.imshow(data,cmap=my_cmap,**kwargs) # time axis: ax.xaxis_date() xxstart, xxend = ax.get_xlim() # we want 11 ticks: ax.xaxis.set_ticks(np.linspace(xxstart, xxend, 11, endpoint=True)) #ax.set_xticklabels(np.linspace(xxstart, xxend, 11, endpoint=True)) date_format = mdates.DateFormatter('%H:%M:%S') ax.xaxis.set_major_formatter(date_format) # fig.autofmt_xdate() for tick in ax.get_xticklabels(): tick.set_rotation(90) # frequencies axis: # we want 11 ticks: plt.yticks(np.linspace(fRange[0], fRange[1], 11, endpoint=True)) yformatter = FuncFormatter(fmtMHz) ax.yaxis.set_major_formatter(yformatter) plt.xlabel('UTC time', labelpad=10) plt.ylabel('FFT frequencies in MHz (over %d bins)' % (FFTbins) ) # colorbar: newTicks = stats_boundaries(data,nSigma,nSigma) cb1 = fig.colorbar(im,ticks=newTicks) cb1.ax.set_xlabel('relative\npower', labelpad=10) cb1.update_normal(im)
def histogramEqualize(image, maxIntensity): width, height = image.shape # Get cdf from image. cdf, binCenters = exposure.cumulative_distribution(image, maxIntensity) binCenters = binCenters.tolist() # Intensity transformation: Each pixel becomes the cumulative probability # that its intensity will show up, multiplied by the intended maximum # intensity. for i in range(width): for j in range(height): try: probability = cdf[binCenters.index(image[i][j])] except: probability = 1 image[i][j] = int(probability * maxIntensity) return image, binCenters, cdf
def plot_img_and_hist(img, axes, bins=256): ax_img, ax_hist = axes ax_cdf = ax_hist.twinx() # Display image ax_img.imshow(img, cmap='gray') ax_img.set_axis_off() # Display histogram ax_hist.hist(img.ravel() * 255, bins=bins) ax_hist.ticklabel_format(axis='y', style='scientific', scilimits=(0, 0)) ax_hist.set_xlabel('Pixel intensity') ax_hist.set_xlim(0, 255) # Display cumulative distribution img_cdf, bins = exposure.cumulative_distribution(img*255, bins) ax_cdf.plot(bins, img_cdf, 'r') return ax_img, ax_hist, ax_cdf
def EMD(saliency_map1, saliency_map2, sub_sample=1/32.0): ''' Earth Mover's Distance measures the distance between two probability distributions by how much transformation one distribution would need to undergo to match another (EMD=0 for identical distributions). Parameters ---------- saliency_map1 : real-valued matrix If the two maps are different in shape, saliency_map1 will be resized to match saliency_map2. saliency_map2 : real-valued matrix Returns ------- EMD : float, positive ''' map2 = np.array(saliency_map2, copy=False) # Reduce image size for efficiency of calculation map2 = resize(map2, np.round(np.array(map2.shape)*sub_sample), order=3, mode='nearest') map1 = resize(saliency_map1, map2.shape, order=3, mode='nearest') # Histogram match the images so they have the same mass map1 = match_hist(map1, *exposure.cumulative_distribution(map2)) # Normalize the two maps to sum up to 1, # so that the score is independent of the starting amount of mass / spread of fixations of the fixation map map1 = normalize(map1, method='sum') map2 = normalize(map2, method='sum') # Compute EMD with OpenCV # - http://docs.opencv.org/modules/imgproc/doc/histograms.html#emd # - http://stackoverflow.com/questions/5101004/python-code-for-earth-movers-distance # - http://stackoverflow.com/questions/12535715/set-type-for-fromarray-in-opencv-for-python r, c = map2.shape x, y = np.meshgrid(range(c), range(r)) signature1 = cv.CreateMat(r*c, 3, cv.CV_32FC1) signature2 = cv.CreateMat(r*c, 3, cv.CV_32FC1) cv.Convert(cv.fromarray(np.c_[map1.ravel(), x.ravel(), y.ravel()]), signature1) cv.Convert(cv.fromarray(np.c_[map2.ravel(), x.ravel(), y.ravel()]), signature2) return cv.CalcEMD2(signature2, signature1, cv.CV_DIST_L2)
def plot_img_and_hist(img, axes, bins=256): """Plot an image along with its histogram and cumulative histogram. """ ax_img, ax_hist = axes ax_cdf = ax_hist.twinx() # Display image ax_img.imshow(img, cmap=plt.cm.gray) ax_img.set_axis_off() # Display histogram ax_hist.hist(img.ravel(), bins=bins) ax_hist.ticklabel_format(axis="y", style="scientific", scilimits=(0, 0)) ax_hist.set_xlabel("Pixel intensity") xmin, xmax = dtype_range[img.dtype.type] ax_hist.set_xlim(xmin, xmax) # Display cumulative distribution img_cdf, bins = exposure.cumulative_distribution(img, bins) ax_cdf.plot(bins, img_cdf, "r") return ax_img, ax_hist, ax_cdf
def match(im_source, im_target): dist_source, bins = cumulative_distribution(im_source) dist_target, bins = cumulative_distribution(im_target) transfo = rechercher_transformation(dist_source, dist_target) return appliquer_transformation(im_source, transfo)
def plot_cdf(image, ax=None): img_cdf, bins = exposure.cumulative_distribution(image) ax.plot(bins, img_cdf, 'r') ax.set_ylabel("Fraction of pixels below intensity")
def grayhist(img, *args, **histkwargs): """Plot an image along with its histogram and cumulative histogram. ADAPTED FROM SCIKIT IMAGE GALLERY http://scikit-image.org/docs/dev/auto_examples/plot_local_equalize.html Parameters ---------- bins : (Number bins, defaults to 256) cdf : bool(False) or str(color) Plot cumulative distribution function over histogram. If cdf = color, interpreted as line color eg (cdf = 'r') plots a red line for CDF. lw / ls : CDF Line styles xlim : set (xs, xf) or "auto" Return cropped histogram between x-limits. If "auto", min and max brigntess of image are used. Returns ------- tuple : (n, bins, patches) or ([n0, n1, ...], bins, [patches0, patches1,...]) Notes ----- Unlike standard histogram, this returns axes rather than the histogram parameters. Because this method changes api for xlim, IE user can prescribe xlimits through call signature, it is easier to just crop the image instead of changing the plot limits to account for the various cases. Therefore, it would return output for cropped image histogram, which could lead to confusion. See matplotlib hist API for all plt.hist() parameters. http://matplotlib.org/api/pyplot_api.html """ if img.ndim == 3: img = rgb2uint(img, warnmsg=True) # Histogram plotting kwargs bins = histkwargs.pop('bins', 256) #used several places cdf = histkwargs.pop('cdf', False) title = histkwargs.pop('title', None) histkwargs.setdefault('color', 'black') histkwargs.setdefault('alpha', 0.5) histkwargs.setdefault('orientation', 'vertical') # CDF line plotting kwargs lw = histkwargs.pop('lw', 2) ls = histkwargs.pop('ls', '-') xlim = histkwargs.pop('xlim', None) # Set the range based on scikit image dtype range # (not quite right for rgb) xmin, xmax = pp_dtype_range(img) if xlim: # ALSO SET VLIM FROM AUTO! if xlim == 'auto': xlim = img.min(), img.max() rmin, rmax = xlim if rmin < xmin or rmax > xmax: raise UtilsError("Range %s out of bounds (%s, %s)" % (xlim, xmin, xmax)) else: xmin, xmax = xlim raveled_img = img[(img >= xmin) & (img <= xmax)] if histkwargs['orientation'] == 'horizontal': raise UtilsError("horizontal orientation not supported.") axes, kwargs = _parse_ax(*args, **histkwargs) # Matplotlib if not axes: fig, axes = plt.subplots() # Display histogram histout = axes.hist(raveled_img, bins=bins, **histkwargs) axes.ticklabel_format(axis='y', style='scientific', scilimits=(0, 0)) axes.set_xlabel('Pixel intensity') # Display cumulative distribution if cdf: if cdf is not True: lcolor = cdf else: lcolor = 'r' ax_cdf = axes.twinx() img_cdf, bins = exposure.cumulative_distribution(img, bins) ax_cdf.plot(bins, img_cdf, color=lcolor, lw=lw, ls=ls) axes.set_xlim(xmin, xmax) #is necessary if title: axes.set_title(title) return axes
def egalisation(image): dist_image, bins = cumulative_distribution(image) nb = len(dist_image) transfo = rechercher_transformation(dist_image, [k / nb for k in range(nb)]) return appliquer_transformation(image, transfo)
img2 = np.copy(img) for i in range(rows): for j in range(columns): value = img[i][j] value = np.clip(pow((value / 255.0), gamma) * 255.0, 0, 255) img2[i][j] = value return img2 img1 = cv2.imread('image1.jpg') plt.subplot(221) plt.imshow(img1) img2 = cv2.imread('image2.jpg') plt.subplot(222) plt.imshow(img2) c, _ = cumulative_distribution(img1) c_t, _ = cumulative_distribution(img2) img3 = hist_matching(c, c_t, img1) c_new, _ = cumulative_distribution(img3) plt.subplot(223) plt.plot(c, '-b', label='image1') plt.plot(c_t, label='image2') plt.plot(c_new, label='new') plt.subplot(224) plt.imshow(img3) plt.show() plt.subplot(221) plt.imshow(gammatrans(img3, 1.5)) plt.subplot(222) plt.imshow(gammatrans(img3, 2)) plt.subplot(223)
def show_comparison(im1, im2, title1, title2, xmin, xmax, ymin, ymax, hist1=False, hist2=False, cmap1=plt.cm.gray, cmap2=plt.cm.gray): bins = 100 if hist1 or hist2: fig, ax = plt.subplots(3, 2, figsize=(20, 15)) ax1, ax2, ax3, ax4, ax5, ax6 = ax.ravel() else: fig, ax = plt.subplots(2, 2, figsize=(20, 10)) ax1, ax2, ax3, ax4 = ax.ravel() ax1.imshow(im1, cmap=cmap1, interpolation='nearest') ax1.set_title(title1) ax1.axis('off') ax2.imshow(im2, cmap=cmap2, interpolation='nearest') ax2.set_title(title2) ax2.axis('off') ax3.imshow(im1[xmin:xmax, ymin:ymax], cmap1, interpolation='nearest') ax3.axis('off') ax4.imshow(im2[xmin:xmax, ymin:ymax], cmap2, interpolation='nearest') ax4.axis('off') if hist1: # Display histogram ax5.hist(im1.ravel(), bins=bins, histtype='step', color='black') ax5.ticklabel_format(axis='y', style='scientific', scilimits=(0, 0)) ax5.set_xlabel('Pixel intensity') ax5.set_xlim(0, 1) ax5.set_yticks([]) # Display cumulative distribution ax5_cdf = ax5.twinx() img_cdf, bins = exposure.cumulative_distribution(im1, bins) ax5_cdf.plot(bins, img_cdf, 'r') ax5_cdf.set_yticks([]) if hist2: # Display histogram ax6.hist(im2.ravel(), bins=bins, histtype='step', color='black') ax6.ticklabel_format(axis='y', style='scientific', scilimits=(0, 0)) ax6.set_xlabel('Pixel intensity') ax6.set_xlim(0, 1) ax6.set_yticks([]) # Display cumulative distribution ax6_cdf = ax6.twinx() img_cdf, bins = exposure.cumulative_distribution(im2, bins) ax6_cdf.plot(bins, img_cdf, 'r') ax6_cdf.set_yticks([]) fig.subplots_adjust(hspace=0.02, wspace=0.02, top=1, bottom=0, left=0, right=1)
def test_equalize_ubyte(): img_eq = exposure.equalize(test_img) cdf, bin_edges = exposure.cumulative_distribution(img_eq) check_cdf_slope(cdf)
ax[1][1].imshow(img_adapteq, cmap='gray') # ax[2].imshow(img, cmap='jet') # ax[2].set_title(f'Labelled Objects', fontsize=12) # for a in ax.flat: # a.axis('off') bins = 256 # ax_img, ax_hist = axes[:, 0] ax_hist = ax[1][2] ax_cdf = ax_hist.twinx() #overlay graphs # Display histogram ax_hist.hist(img_adapteq.ravel(), bins=bins, histtype='step', color='black') ax_hist.ticklabel_format(axis='y', style='scientific', scilimits=(0, 0)) ax_hist.set_xlabel('Pixel intensity') ax_hist.set_xlim(0, 1) ax_hist.set_yticks([]) # Display cumulative distribution img_cdf, bins = exposure.cumulative_distribution(image, bins) ax_cdf.plot(bins, img_cdf, 'r') ax_cdf.set_yticks([]) y_min, y_max = ax_hist.get_ylim() ax_hist.set_ylabel('Number of pixels') ax_hist.set_yticks(np.linspace(0, y_max, 5)) ax_cdf.set_ylabel('Fraction of total intensity') ax_cdf.set_yticks(np.linspace(0, 1, 5)) plt.tight_layout() # plt.savefig('09_image-processing-1_four-circles-layers.png', dpi=150) plt.show()
from skimage import data, exposure, img_as_float, img_as_ubyte import matplotlib.pyplot as plt image = img_as_float(data.camera()) image_uint8 = img_as_ubyte(data.camera()) hi = exposure.histogram(image_uint8) cdf = exposure.cumulative_distribution(image_uint8) plt.figure(1) plt.subplot(1, 2, 1) plt.imshow(image_uint8, cmap='gray') plt.title('Sample Image') plt.subplot(1, 2, 2) plt.bar(hi[1], hi[0]) plt.hold(True) plt.plot(cdf[1], cdf[0] * 6400, 'r') plt.hold(False) plt.title('Histogram and CDF') plt.xlabel('Pixel Intensity') plt.show()
# construct a figure to display the histogram plots for each channel # before and after histogram matching was applied (fig, axs) = plt.subplots(nrows=3, ncols=3, figsize=(8, 8)) # loop over our source image, reference image, and output matched # image for (i, image) in enumerate((scr, ref, matched)): # convert the image from BGR to RGB channel ordering image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) # loop over the names of the channels in RGB order for (j, color) in enumerate(("red", "green", "blue")): # compute a histogram for the current channel and plot it (hist, bins) = exposure.histogram(image[..., j], source_range="dtype") axs[j, i].plot(bins, hist / hist.max()) # compute the cumulative distribution function for the # current channel and plot it (cdf, bins) = exposure.cumulative_distribution(image[..., j]) axs[j, i].plot(bins, cdf) # set the y-axis label of the current plot to be the name # of the current color channel axs[j, 0].set_ylabel(color) # set the axes titles axs[0, 0].set_title("Source") axs[0, 1].set_title("Reference") axs[0, 2].set_title("Matched") cv2.waitKey(0) cv2.destroyAllWindow()
def imshow_hs(data, ax=None, cmap='geosoft', cmap_norm='equalize', hs=True, zf=10, azdeg=45, altdeg=45, dx=1, dy=1, fraction=1.5, blend_mode='alpha', alpha=0.7, contours=False, levels=32, colorbar=True, cb_contours=False, cb_ticks='linear', nSigma=1, **kwargs): ''' Display an array with optional hillshading and contours. The colormap can be normalised by equalisation or by clipping extremes (autolevels). Parameters ---------- data : 2D array Grid to plot. Arrays with NaNs and masked arrays are supported. ax : matplotlib axes instance This indicates where to draw the figure. Create new figure if absent. cmap : string Name of the colormap to use to display the array. The default 'geosoft' is the blue to pink clra colormap from Geosoft Oasis Montaj. cmap_norm : string Type of normalisation of the colormap. Possible values are: 'equalize' (or 'equalization') Increases contrast by distributing intensities across all the possible colours. With this option, it is not the data that is normalised but the colormap, based on the data. 'auto' (or 'autolevels') Stretches the histogram of the colormap so that dark colours become darker and the bright colours become brighter. Two extra parameters control the amount of clipping at the extremes: minPercent (default to 10%) and maxPercent (default to 90%) hs : boolean If True, the array is displayed in colours over a grey hillshaded version of the data. zf : number Vertical exaggeration (Z factor) for hillshading. azdeg : number The azimuth (0-360, degrees clockwise from North) of the light source. altdeg : number The altitude (0-90, degrees up from horizontal) of the light source. dx : number, optional cell size in the x direction dy : number, optional cell size in the y direction fraction : number Increases or decreases the contrast of the hillshade. blend_mode : {'alpha', 'hsv', 'overlay', 'soft'} The type of blending used to combine the colormapped data values with the illumination intensity. Default is 'alpha' and the effect is controlled by the alpha parameter. alpha : float Controls the transparency of the data overlaid over the hillshade. 1.0 is fully opaque while 0.0 is fully transparent. contours : Boolean If True, adds contours to the map. The number of calculated contours is defined by: levels : integer Number of contour levels. colorbar : Boolean If True, draw a colorbar on the right-hand side of the map. The colorbar shows the distribution of colors, as modified by the normalization algorithm. cb_ticks : string If left as default ('linear') the ticks and labels on the colorbar are spaced linearly in the standard way. Otherwise (any other keyword, for example 'stats'), the mean and two ticks at + and - nSigma*(standard deviation) are shown instead. nSigma : integer (default is 1) Size of the interval to show between ticks on the colorbar. cb_contours : Boolean Add lines corresponding to contours on the colorbar. kwargs : other optional arguments Can be used to pass other arguments to imshow, such as 'origin' and 'extent'. Notes ----- This function exploits the hillshading capabilities implemented in matplotlib.colors.LightSource. It adds additional blending mode (alpha compositing, see https://en.wikipedia.org/wiki/Alpha_compositing) and normalising functions for the data (equalization). ''' # modify colormap if required if cmap_norm in ['equalize', 'equalization']: # histogram equalization cdf, bins = exposure.cumulative_distribution( data[~np.isnan(data)].flatten(), nbins=256) my_cmap = equalizeColormap(cmap, bins, cdf) elif cmap_norm in ['auto', 'autolevels']: # autolevels minP = kwargs.pop('minPercent', 10) # also removes the key from the dictionary maxP = kwargs.pop('maxPercent', 90) my_cmap = normalizeColormap(cmap, norm='autolevels', minPercent=minP, maxPercent=maxP) elif cmap in plt.colormaps(): # colormap defined as string (recognised name) my_cmap = plt.get_cmap(cmap) else: # colormap is one of the extra ones added by the colors module my_cmap = load_cmap(cmap) # raises error if not recognised # create figure or retrieve the one already there if ax: fig = ax.get_figure() else: fig, ax = plt.subplots(figsize=(8, 8)) # convert input data to masked array data = np.ma.masked_array(data, np.isnan(data)) # add array to figure with hillshade or not if hs: # flip azimuth upside down if grid is also flipped if 'origin' in kwargs: if kwargs['origin'] == 'lower': azdeg = 180 - azdeg # extract keyword arguments that can be passed to ls.shade kwargs_norm = {} kwargs_norm['norm'] = kwargs.get('norm') kwargs_norm['vmin'] = kwargs.get('vmin') kwargs_norm['vmax'] = kwargs.get('vmax') # create light source ls = mcolors.LightSource(azdeg, altdeg) # calculate hillshade and combine the colormapped data with the intensity if alpha == 0: # special case when only the shaded relief is needed without blending rgb = ls.hillshade(data, vert_exag=zf, dx=dx, dy=dy, fraction=fraction) kwargs['cmap'] = 'gray' elif blend_mode == 'alpha': # transparency blending rgb = ls.shade(data, cmap=my_cmap, blend_mode=alpha_blend, vert_exag=zf, dx=dx, dy=dy, fraction=fraction, alpha=alpha, **kwargs_norm) else: # other blending modes from matplotlib function rgb = ls.shade(data, cmap=my_cmap, blend_mode=blend_mode, vert_exag=zf, dx=dx, dy=dy, fraction=fraction, **kwargs_norm) ax.imshow(rgb, **kwargs) else: # display data without hillshading im = ax.imshow(data, cmap=my_cmap, **kwargs) # add contours if contours: ct = plt.contour(data, levels, linewidths=0.5, colors='k', linestyles='solid', **kwargs) # add colorbar if colorbar and alpha != 0: if hs: # Use a proxy artist for the colorbar im = ax.imshow(data, cmap=my_cmap, **kwargs) im.remove() if cb_ticks == 'linear': # normal equidistant ticks on a linear scale cb1 = fig.colorbar(im, shrink=0.8) else: # show ticks at min, max, mean and standard deviation interval newTicks = stats_boundaries(data, nSigma, nSigma) cb1 = fig.colorbar(im, shrink=0.8, ticks=newTicks) # add optional contour lines on colorbar if contours and cb_contours: cb1.add_lines(ct) cb1.update_normal(im) # final show plt.show()
##################################################################### # As before, if we have a Jupyter kernel running, we can explore the above # slices interactively. explore_slices(equalized_data) ##################################################################### # Let us now plot the image histogram before and after histogram equalization. # Below, we plot the respective cumulative distribution functions (CDF). _, ((a, b), (c, d)) = plt.subplots(nrows=2, ncols=2, figsize=(16, 8)) plot_hist(a, data, title="Original histogram") plot_hist(b, equalized_data, title="Equalized histogram") cdf, bins = exposure.cumulative_distribution(data.ravel()) c.plot(bins, cdf, "r") c.set_title("Original CDF") cdf, bins = exposure.cumulative_distribution(equalized_data.ravel()) d.plot(bins, cdf, "r") d.set_title("Histogram equalization CDF") ##################################################################### # Most experimental images are affected by salt and pepper noise. A few bright # artifacts can decrease the relative intensity of the pixels of interest. A # simple way to improve contrast is to clip the pixel values on the lowest and # highest extremes. Clipping the darkest and brightest 0.5% of pixels will # increase the overall contrast of the image. vmin, vmax = np.percentile(data, q=(0.5, 99.5))
def grayhist(img, *args, **histkwargs): """Plot an image along with its histogram and cumulative histogram. ADAPTED FROM SCIKIT IMAGE GALLERY http://scikit-image.org/docs/dev/auto_examples/plot_local_equalize.html Parameters ---------- bins : (Number bins, defaults to 256) cdf : bool(False) or str(color) Plot cumulative distribution function over histogram. If cdf = color, interpreted as line color eg (cdf = 'r') plots a red line for CDF. lw / ls : CDF Line styles xlim : set (xs, xf) or "auto" Return cropped histogram between x-limits. If "auto", min and max brigntess of image are used. Returns ------- tuple : (n, bins, patches) or ([n0, n1, ...], bins, [patches0, patches1,...]) Notes ----- Unlike standard histogram, this returns axes rather than the histogram parameters. Because this method changes api for xlim, IE user can prescribe xlimits through call signature, it is easier to just crop the image instead of changing the plot limits to account for the various cases. Therefore, it would return output for cropped image histogram, which could lead to confusion. See matplotlib hist API for all plt.hist() parameters. http://matplotlib.org/api/pyplot_api.html """ if img.ndim == 3: img = rgb2uint(img, warnmsg = True) # Histogram plotting kwargs bins = histkwargs.pop('bins', 256) #used several places cdf = histkwargs.pop('cdf', False) title = histkwargs.pop('title', None) histkwargs.setdefault('color', 'black') histkwargs.setdefault('alpha', 0.5) histkwargs.setdefault('orientation', 'vertical') # CDF line plotting kwargs lw = histkwargs.pop('lw', 2) ls = histkwargs.pop('ls', '-') xlim = histkwargs.pop('xlim', None) # Set the range based on scikit image dtype range # (not quite right for rgb) xmin, xmax = pp_dtype_range(img) if xlim: # ALSO SET VLIM FROM AUTO! if xlim =='auto': xlim = img.min(), img.max() rmin, rmax = xlim if rmin < xmin or rmax > xmax: raise UtilsError("Range %s out of bounds (%s, %s)" % (xlim, xmin, xmax)) else: xmin, xmax = xlim raveled_img = img[(img >= xmin) & (img <= xmax)] if histkwargs['orientation'] == 'horizontal': raise UtilsError("horizontal orientation not supported.") axes, kwargs = _parse_ax(*args, **histkwargs) # Matplotlib if not axes: fig, axes = plt.subplots() # Display histogram histout = axes.hist(raveled_img, bins=bins, **histkwargs) axes.ticklabel_format(axis='y', style='scientific', scilimits=(0, 0)) axes.set_xlabel('Pixel intensity') # Display cumulative distribution if cdf: if cdf is not True: lcolor = cdf else: lcolor = 'r' ax_cdf = axes.twinx() img_cdf, bins = exposure.cumulative_distribution(img, bins) ax_cdf.plot(bins, img_cdf, color=lcolor, lw=lw, ls=ls) axes.set_xlim(xmin, xmax) #is necessary if title: axes.set_title(title) return axes
def test_equalize_ubyte(): img = skimage.img_as_ubyte(test_img) img_eq = exposure.equalize_hist(img) cdf, bin_edges = exposure.cumulative_distribution(img_eq) check_cdf_slope(cdf)
def histogram_equalize(img): """ Apply histogram equalization into an image (not used) """ img_cdf, bin_centers = exposure.cumulative_distribution(img) return np.interp(img, bin_centers, img_cdf)
ax3.imshow(matched) ax3.set_title('Matched') plt.tight_layout() plt.show() ###################################################################### # To illustrate the effect of the histogram matching, we plot for each # RGB channel, the histogram and the cumulative histogram. Clearly, # the matched image has the same cumulative histogram as the reference # image for each channel. fig, axes = plt.subplots(nrows=3, ncols=3, figsize=(8, 8)) for i, img in enumerate((image, reference, matched)): for c, c_color in enumerate(('red', 'green', 'blue')): img_hist, bins = exposure.histogram(img[..., c], source_range='dtype') axes[c, i].plot(bins, img_hist / img_hist.max()) img_cdf, bins = exposure.cumulative_distribution(img[..., c]) axes[c, i].plot(bins, img_cdf) axes[c, 0].set_ylabel(c_color) axes[0, 0].set_title('Source') axes[0, 1].set_title('Reference') axes[0, 2].set_title('Matched') plt.tight_layout() plt.show()
#histr = exposure.cumulative_distribution(imr)[0] ref_hist, ref_cum = get_mean_histogram(file_list) for n, f in enumerate(file_list): print "%d/%d %s" % (n + 1, len(file_list), f) imi = io.imread(f, as_grey=True) if imi.dtype == 'uint8': imi = imi / 255. imo = histogram_matching(ref_cum, imi) io.imsave(os.path.join(sys.argv[2], os.path.basename(f)), img_as_uint(imo)) if option["verbose"]: plt.figure("image in"), plt.imshow(imi, cmap="gray") plt.figure("image out"), plt.imshow(imo, cmap="gray") plt.figure("Histogram") plt.plot(ref_hist, label="reference") plt.plot(exposure.histogram(imi)[0], label="hist in") plt.plot(exposure.histogram(imo)[0], label="hist out") plt.legend() plt.figure("Cumulative") plt.plot(ref_cum, label="reference") plt.plot(exposure.cumulative_distribution(imi)[0], label="cum in") plt.plot(exposure.cumulative_distribution(imo)[0], label="cum out") plt.legend() plt.show()
def test_equalize_float(): img = util.img_as_float(test_img) img_eq = exposure.equalize_hist(img) cdf, bin_edges = exposure.cumulative_distribution(img_eq) check_cdf_slope(cdf)
def valid_img(self): from skimage import exposure cdf = exposure.cumulative_distribution(self.img) watershed = cdf[1][cdf[0] >= self.percent][0] return np.clip(self.img, self.img.min(), watershed)
from skimage.data import camera, moon from skimage.exposure import cumulative_distribution, equalize_hist from skimage.io import imshow, show from numpy import vectorize im_camera = camera() im_moon = moon() dist_camera, bins = cumulative_distribution(im_camera) dist_moon, bins = cumulative_distribution(im_moon) # def rechercher_transformation(dist_source, dist_target): # nb_source = len(dist_source) # nb_target = len(dist_target) # transformation = [nb_source - 1] * nb_source # i, j = 0, 0 # while j < nb_target: # while i < nb_source and dist_source[i] < dist_target[j]: # transformation[i] = j # i += 1 # j += 1 # return transformation def rechercher_transformation(dist_source, dist_target): nb_source = len(dist_source) nb_target = len(dist_target) transformation = [nb_source - 1] * nb_source i, j = 0, 0 ind0, val0 = 0, 0 while j < nb_target:
sharey=True) for aa in (ax1, ax2, ax3): aa.set_axis_off() ax1.imshow(image) ax1.set_title('Source') ax2.imshow(reference) ax2.set_title('Reference') ax3.imshow(matched) ax3.set_title('Matched') plt.tight_layout() plt.show() fig, axes = plt.subplots(nrows=3, ncols=3, figsize=(8, 8)) for i, img in enumerate((image, reference, matched)): for c, c_color in enumerate(('red', 'green', 'blue')): img_hist, bins = exposure.histogram(img[..., c], source_range='dtype') axes[c, i].plot(bins, img_hist / img_hist.max()) img_cdf, bins = exposure.cumulative_distribution(img[..., c]) axes[c, i].plot(bins, img_cdf) axes[c, 0].set_ylabel(c_color) axes[0, 0].set_title('Source') axes[0, 1].set_title('Reference') axes[0, 2].set_title('Matched') plt.tight_layout() plt.show()
def imshow_hs(data,ax=None,cmap='geosoft',cmap_norm='equalize',hs=True, zf=10,azdeg=45,altdeg=45,dx=1,dy=1,fraction=1.5,blend_mode='alpha', alpha=0.7,contours=False,levels=32,colorbar=True,cb_contours=False, cb_ticks='linear',nSigma=1,**kwargs): ''' Display an array with optional hillshading and contours. The colormap can be normalised by equalisation or by clipping extremes (autolevels). Parameters ---------- data : 2D array Grid to plot. Arrays with NaNs and masked arrays are supported. ax : matplotlib axes instance This indicates where to draw the figure. Create new figure if absent. cmap : string Name of the colormap to use to display the array. The default 'geosoft' is the blue to pink clra colormap from Geosoft Oasis Montaj. cmap_norm : string Type of normalisation of the colormap. Possible values are: 'equalize' (or 'equalization') Increases contrast by distributing intensities across all the possible colours. With this option, it is not the data that is normalised but the colormap, based on the data. 'auto' (or 'autolevels') Stretches the histogram of the colormap so that dark colours become darker and the bright colours become brighter. Two extra parameters control the amount of clipping at the extremes: minPercent (default to 10%) and maxPercent (default to 90%) hs : boolean If True, the array is displayed in colours over a grey hillshaded version of the data. zf : number Vertical exaggeration (Z factor) for hillshading. azdeg : number The azimuth (0-360, degrees clockwise from North) of the light source. altdeg : number The altitude (0-90, degrees up from horizontal) of the light source. dx : number, optional cell size in the x direction dy : number, optional cell size in the y direction fraction : number Increases or decreases the contrast of the hillshade. blend_mode : {'alpha', 'hsv', 'overlay', 'soft'} The type of blending used to combine the colormapped data values with the illumination intensity. Default is 'alpha' and the effect is controlled by the alpha parameter. alpha : float Controls the transparency of the data overlaid over the hillshade. 1.0 is fully opaque while 0.0 is fully transparent. contours : Boolean If True, adds contours to the map. The number of calculated contours is defined by: levels : integer Number of contour levels. colorbar : Boolean If True, draw a colorbar on the right-hand side of the map. The colorbar shows the distribution of colors, as modified by the normalization algorithm. cb_ticks : string If left as default ('linear') the ticks and labels on the colorbar are spaced linearly in the standard way. Otherwise (any other keyword, for example 'stats'), the mean and two ticks at + and - nSigma*(standard deviation) are shown instead. nSigma : integer (default is 1) Size of the interval to show between ticks on the colorbar. cb_contours : Boolean Add lines corresponding to contours on the colorbar. kwargs : other optional arguments Can be used to pass other arguments to imshow, such as 'origin' and 'extent'. Notes ----- This function exploits the hillshading capabilities implemented in matplotlib.colors.LightSource. It adds additional blending mode (alpha compositing, see https://en.wikipedia.org/wiki/Alpha_compositing) and normalising functions for the data (equalization). ''' # modify colormap if required if cmap_norm in ['equalize','equalization']: # histogram equalization cdf, bins = exposure.cumulative_distribution(data[~np.isnan(data)].flatten(),nbins=256) my_cmap = equalizeColormap(cmap,bins,cdf) elif cmap_norm in ['auto','autolevels']: # autolevels minP = kwargs.pop('minPercent',10) # also removes the key from the dictionary maxP = kwargs.pop('maxPercent',90) my_cmap = normalizeColormap(cmap,norm='autolevels',minPercent=minP,maxPercent=maxP) elif cmap in plt.colormaps(): # colormap defined as string (recognised name) my_cmap = plt.get_cmap(cmap) else: # colormap is one of the extra ones added by the colors module my_cmap = load_cmap(cmap) # raises error if not recognised # create figure or retrieve the one already there if ax: fig = ax.get_figure() else: fig,ax = plt.subplots(figsize=(8,8)) # convert input data to masked array data = np.ma.masked_array(data, np.isnan(data)) # add array to figure with hillshade or not if hs: # flip azimuth upside down if grid is also flipped if 'origin' in kwargs: if kwargs['origin'] == 'lower': azdeg = 180 - azdeg # extract keyword arguments that can be passed to ls.shade kwargs_norm = {} kwargs_norm['norm'] = kwargs.get('norm') kwargs_norm['vmin'] = kwargs.get('vmin') kwargs_norm['vmax'] = kwargs.get('vmax') # create light source ls = mcolors.LightSource(azdeg, altdeg) # calculate hillshade and combine the colormapped data with the intensity if alpha == 0: # special case when only the shaded relief is needed without blending rgb = ls.hillshade(data,vert_exag=zf,dx=dx,dy=dy,fraction=fraction) kwargs['cmap'] = 'gray' elif blend_mode == 'alpha': # transparency blending rgb = ls.shade(data,cmap=my_cmap,blend_mode=alpha_blend,vert_exag=zf,dx=dx,dy=dy, fraction=fraction,alpha=alpha,**kwargs_norm) else: # other blending modes from matplotlib function rgb = ls.shade(data,cmap=my_cmap,blend_mode=blend_mode,vert_exag=zf,dx=dx,dy=dy, fraction=fraction,**kwargs_norm) ax.imshow(rgb,**kwargs) else: # display data without hillshading im = ax.imshow(data,cmap=my_cmap,**kwargs) # add contours if contours: ct = plt.contour(data,levels,linewidths=0.5,colors='k',linestyles='solid',**kwargs) # add colorbar if colorbar and alpha != 0: if hs: # Use a proxy artist for the colorbar im = ax.imshow(data,cmap=my_cmap,**kwargs) im.remove() if cb_ticks=='linear': # normal equidistant ticks on a linear scale cb1 = fig.colorbar(im,shrink=0.8) else: # show ticks at min, max, mean and standard deviation interval newTicks = stats_boundaries(data,nSigma,nSigma) cb1 = fig.colorbar(im,shrink=0.8,ticks=newTicks) # add optional contour lines on colorbar if contours and cb_contours: cb1.add_lines(ct) cb1.update_normal(im) # final show plt.show()
def test_equalize_float(): img = skimage.img_as_float(test_img) img_eq = exposure.equalize_hist(img) cdf, bin_edges = exposure.cumulative_distribution(img_eq) check_cdf_slope(cdf)
def segment_histo(image_path, colour1, colour2): image = io.imread(image_path) image_hed = rgb2hed(image) cmap_custom = LinearSegmentedColormap.from_list('mycmap', [colour1, colour2]) final_seg = image_hed[:, :, 0] fig, image_original = plt.subplots(figsize=(4, 3)) image_original.imshow(image) image_original.set_title('Original Image') image_original.axis('off') fig, human_seperation = plt.subplots(figsize=(4, 3)) human_seperation.imshow(final_seg, cmap=cmap_custom) human_seperation.set_title('colour deconvolution') human_seperation.axis('off') #return histogram of segmented image split between RGB channels final_seg_rgb = hed2rgb(final_seg) fig, rgb_histo = plt.subplots(nrows=3, ncols=1, figsize=(5, 8)) #plotting the histogram and cummulative histogram across each colour channel for c, c_color in enumerate(('red', 'green', 'blue')): img_hist, bins = exposure.histogram(image[..., c]) rgb_histo[c].plot(bins, img_hist / img_hist.max()) img_cdf, bins = exposure.cumulative_distribution(image[..., c]) rgb_histo[c].plot(bins, img_cdf) rgb_histo[c].set_ylabel(c_color) rgb_histo[0].set_title('Histogram of RGB channels (original image)') #saving the image onto machine, not crucial #massive precision loss look into conservation io.imsave('./images/' + image_path[9:17] + '_seg.jpg', final_seg_rgb) #derive heat level based on thermaml image, this will be the FLC input #this is happens only when human is detected, else the radiator power % #is set to 0 human_threshold = -0.5681 if final_seg.max() > human_threshold: controller_input = flc_input(image.mean()) flc_input_file = open( '../fuzzyLogic/Juzzy/Project/Juzzy_V2_Source/src/radiatorFLC/FLCinput.txt', 'w+') flc_input_file.write(str(controller_input)) flc_input_file.close() print(controller_input) else: controller_input = 10 flc_input_file = open( '../fuzzyLogic/Juzzy/Project/Juzzy_V2_Source/src/radiatorFLC/FLCinput.txt', 'w+') flc_input_file.write(str(controller_input)) flc_input_file.close() print(controller_input) print('NO HUMAN DETECTED IN ROOM \nHEATING DEACTIVATED') exit() return human_seperation, final_seg, rgb_histo
def histogram_equalize(img): img_cdf, bin_centers = exposure.cumulative_distribution(img) return np.interp(img, bin_centers, img_cdf)
def _hist_eq(img): from skimage import exposure img_cdf, bin_centers = exposure.cumulative_distribution(img) return np.interp(img, bin_centers, img_cdf)