Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- from __future__ import print_function
- import matplotlib
- import numpy as np
- from scipy.ndimage import uniform_filter
- def extract_features(imgs, feature_fns, verbose=False):
- """
- Данный код выполняет применение нескольких функций признаков к пиксельным данным изображений и объединяет векторы признаков для каждого изображения, сохраняя признаки всех изображений в одной матрице.
- Входные данные:
- imgs: массив размерности N x H x W x C, содержащий пиксельные данные для N изображений. Здесь N - количество изображений, H - высота изображений, W - ширина изображений, C - количество каналов цвета.
- feature_fns: список из k функций признаков. i-я функция признаков должна принимать на вход массив размерности H x W x D и возвращать одномерный массив длины F_i.
- verbose: логическое значение; если значение равно True, то выводить прогресс выполнения.
- Возвращаемое значение:
- Массив размерности (N, F_1 + ... + F_k), где каждый столбец представляет собой объединение всех признаков для одного изображения.
- """
- # Количество изображений в наборе
- num_images = imgs.shape[0]
- if num_images == 0:
- return np.array([])
- # Используем первое изображение, чтобы определить размеры объекта.
- feature_dims = [] # размерность признаков
- first_image_features = [] # признаки первого изображения
- # определяем общую размерность признаков и выделяем память для хранения всех признаков всех изображений в одной матрице.
- for feature_fn in feature_fns:
- feats = feature_fn(imgs[0].squeeze()) # imgs[0].squeeze() используется для удаления измерения с размерностью 1 (если оно существует), чтобы получить двумерное изображение.
- assert len(feats.shape) == 1, 'Feature functions must be one-dimensional' # выбрасываем исключение если размерность является одномерной
- feature_dims.append(feats.size) # размерность признаков
- first_image_features.append(feats) # Добавление признаков feats первого изображения
- # Теперь, когда мы знаем размеры объектов, мы можем выделить один
- # большой массив для хранения всех функций в виде столбцов.
- total_feature_dim = sum(feature_dims) # Вычисление общей размерности признаков путем суммирования элементов
- imgs_features = np.zeros((num_images, total_feature_dim)) # Создание нулевого массива в котором будут храниться признаки всех изображений. Каждое изображение будет представлено в виде строки этой матрицы
- imgs_features[0] = np.hstack(first_image_features).T # Заполнение первой строки массива imgs_features признаками первого изображения. np.hstack(first_image_features) используется для горизонтальной конкатенации признаков первого изображения в одну строку, а .T используется для транспонирования этой строки в столбец.
- # Извлечение функций для остальных изображений.
- for i in range(1, num_images):
- idx = 0
- for feature_fn, feature_dim in zip(feature_fns, feature_dims):
- next_idx = idx + feature_dim # Вычисление индекса конца блока признаков для imgs_features[i]
- imgs_features[i, idx:next_idx] = feature_fn(imgs[i].squeeze()) # Извлечение признаков из изображения imgs[i] и их присвоение соответствующему блоку признаков в строке imgs_features[i].
- idx = next_idx # Обновление переменной idx для следующего блока признаков
- if verbose and i % 1000 == 0:
- print('Выполнено извлечение признаков для %d / %d изображений' % (i, num_images))
- return imgs_features
- def rgb2gray(rgb):
- """Convert RGB image to grayscale
- Parameters:
- rgb : RGB image
- Returns:
- gray : grayscale image
- """
- return np.dot(rgb[...,:3], [0.299, 0.587, 0.144])
- def hog_feature(im):
- """Вычисление признака Histogram of Gradient (HOG) для изображения
- Modified from skimage.feature.hog
- http://pydoc.net/Python/scikits-image/0.4.2/skimage.feature.hog
- Reference:
- Histograms of Oriented Gradients for Human Detection
- Navneet Dalal and Bill Triggs, CVPR 2005
- Параметры:
- im: входное изображение в оттенках серого или RGB
- Возвращает:
- feat: признак Histogram of Gradient (HOG)
- """
- # Если размерность im равна 3, то выполняется преобразование изображения в оттенки серого
- if im.ndim == 3:
- image = rgb2gray(im)
- else:
- image = np.at_least_2d(im) # преобразование im в массив с размерностью не менее 2
- sx, sy = image.shape # размеры изображения
- orientations = 9 # количество ориентаций. ориентация означает направление градиента яркости в каждой точке изображения
- cx, cy = (8, 8) # количество пикселей в ячейке
- # Вычисляем градиенты по x и по y
- gx = np.zeros(image.shape)
- gy = np.zeros(image.shape)
- gx[:, :-1] = np.diff(image, n=1, axis=1)
- gy[:-1, :] = np.diff(image, n=1, axis=0)
- grad_mag = np.sqrt(gx ** 2 + gy ** 2) # величина градиента
- grad_ori = np.arctan2(gy, (gx + 1e-15)) * (180 / np.pi) + 90 # ориентация градиента. Для предотвращения деления на ноль, к gx добавляется небольшое значение 1e-15.
- n_cellsx = int(np.floor(sx / cx)) # количество ячеек по x
- n_cellsy = int(np.floor(sy / cy)) # количество ячеек по y
- # инициализация ориентации гистограмм
- orientation_histogram = np.zeros((n_cellsx, n_cellsy, orientations))
- for i in range(orientations):
- temp_ori = np.where(grad_ori < 180 / orientations * (i + 1), grad_ori, 0)
- temp_ori = np.where(grad_ori >= 180 / orientations * i, temp_ori, 0)
- # Выбираем величины для текущей ориентации
- temp_mag = np.where(temp_ori > 0, grad_mag, 0)
- # Используется функция uniform_filter для применения фильтра усреднения на temp_mag с размером (cx, cy). Результат этой операции сохраняется в orientation_histogram[:,:,i]. Затем выбираются значения из полученного массива с шагом int(cx/2) по оси x и шагом int(cy/2) по оси y.
- orientation_histogram[:,:,i] = uniform_filter(temp_mag, size=(cx, cy))[int(cx/2)::cx, int(cy/2)::cy].T
- return orientation_histogram.ravel() # Возвращаем одномерный массив
- def color_histogram_hsv(im, nbin=10, xmin=0, xmax=255, normalized=True):
- """
- Compute color histogram for an image using hue.
- Inputs:
- - im: H x W x C array of pixel data for an RGB image.
- - nbin: Number of histogram bins. (default: 10)
- - xmin: Minimum pixel value (default: 0)
- - xmax: Maximum pixel value (default: 255)
- - normalized: Whether to normalize the histogram (default: True)
- Returns:
- 1D vector of length nbin giving the color histogram over the hue of the
- input image.
- """
- ndim = im.ndim
- bins = np.linspace(xmin, xmax, nbin+1)
- hsv = matplotlib.colors.rgb_to_hsv(im/xmax) * xmax
- imhist, bin_edges = np.histogram(hsv[:,:,0], bins=bins, density=normalized)
- imhist = imhist * np.diff(bin_edges)
- # return histogram
- return imhist
- pass
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement