Skip to content

Instantly share code, notes, and snippets.

@RodrigoCMoraes
Created February 5, 2019 19:43
Show Gist options
  • Save RodrigoCMoraes/629ab53207077b502dac7d6ec8b61c7e to your computer and use it in GitHub Desktop.
Save RodrigoCMoraes/629ab53207077b502dac7d6ec8b61c7e to your computer and use it in GitHub Desktop.
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import ImageGrid
import numpy as np
import PIL
import cv2
import glob
import os
def apply_plot_style(xlim, ylim, xlabel, ylabel, grid):
plt.clf()
plt.xlim(xlim)
plt.ylim(ylim)
plt.xlabel(xlabel)
plt.ylabel(ylabel)
plt.grid(grid)
def save_histogram(hist, xlim, ylim, fname_out, title, xlabel, ylabel, grid=True, color='k'):
apply_plot_style(xlim, ylim, xlabel, ylabel, grid)
plt.title(title)
hist_size = len(np.array(hist).shape)
if hist_size == 2:
colors = {'b': 'r', 'g': 'g', 'r': 'b'}
plt.plot(hist, color=colors[color[0]] if color in ['blue', 'green', 'red'] else 'k')
elif hist_size == 3:
for c, h in zip(list(color), hist):
plt.plot(h, color=c)
else:
raise 'ERROR: hist shape must be equals to 2 or 3'
plt.savefig(fname_out, dpi=300)
def thumb_grid(im_list, grid_shape, fname_out, scale=1.0, axes_pad=0.07, figsize=(7, 7), dpi=900):
assert len(grid_shape) == 2 # Grid must be 2D:
assert np.prod(grid_shape) >= len(im_list) # Make sure all images can fit in grid:
plt.figure(figsize=figsize, dpi=dpi)
grid = ImageGrid(plt.gcf(), 111, grid_shape, axes_pad=axes_pad)
shape_index = np.argmin([np.prod(np.array(im.shape)) for im in im_list])
thumb_shape = np.array(np.array(im_list[shape_index]).shape) * scale
for i, im in enumerate(im_list):
data_orig = im.copy()
# Scale image:
im = PIL.Image.fromarray(data_orig)
im.thumbnail(thumb_shape, PIL.Image.ANTIALIAS)
data_thumb = np.array(im)
grid[i].imshow(data_thumb)
# Turn off axes:
grid[i].axes.get_xaxis().set_visible(False)
grid[i].axes.get_yaxis().set_visible(False)
plt.gca().set_axis_off()
plt.subplots_adjust(top = 1, bottom = 0, right = 1, left = 0, hspace = 0, wspace = 0)
plt.margins(0,0)
plt.gca().xaxis.set_major_locator(plt.NullLocator())
plt.gca().yaxis.set_major_locator(plt.NullLocator())
plt.savefig(fname_out, bbox_inches = 'tight', pad_inches = 0.06)
def get_histogram(fname_in, color, normalized=True):
image = cv2.imread(fname_in)
channel_index = ['red', 'green', 'blue', 'gray', 'bgr'].index(color)
if channel_index < 3: # color
channel = cv2.split(image)[channel_index]
hist = cv2.calcHist(channel, [channel_index], None, [256], [0, 256])
elif channel_index == 3: # gray
image_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
hist = cv2.calcHist(image_gray, [0], None, [256], [0, 256])
elif channel_index == 4: # bgr
hist = []
channels = cv2.split(image)
for i, ch in enumerate(channels):
h = cv2.calcHist(ch, [i], None, [256], [0, 256])
hist.append(h)
else:
raise 'ERROR: color values must be one of: red, green, blue, gray or bgr'
if normalized:
if channel_index == 4:
for i in range(len(hist)):
hist[i] = hist[i] / np.linalg.norm(hist[i])
else:
hist = hist / np.linalg.norm(hist)
return hist
if __name__ == '__main__':
base_path = 'histograms'
try:
os.system(f'cd {base_path}/; mv 0* ../; rm *; mv ../0* .')
except:
os.system(f'cd {base_path}/; mv 0* ../; rm *; mv ../0* .')
filename = f'{base_path}/original_image.jpeg'
for i, color in enumerate(['bgr', 'gray', 'blue', 'green', 'red']):
hist = get_histogram(filename, color)
save_histogram(
hist,
xlim=[0, 256],
ylim=[0, 1],
fname_out=f'{base_path}/{i + 1}_{color}.jpeg',
title=f'Histogram - Channel {color.capitalize()}',
xlabel='Pixel Value',
ylabel='Density',
color=color
)
filenames = glob.glob(f'{base_path}/*.jpeg')
filenames = sorted(filenames)
images = [cv2.imread(f'{f}') for f in filenames for d in f if d.isdigit()]
thumb_grid(images, (2, 3), f'{base_path}/histograms.jpeg')
# files
# histogram_analyser.py
# histograms/original_image.jpeg
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment