Advertisement
MARSHAL327

features

Dec 26th, 2023 (edited)
784
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 9.14 KB | None | 0 0
  1. from __future__ import print_function
  2.  
  3. import matplotlib
  4. import numpy as np
  5. from scipy.ndimage import uniform_filter
  6.  
  7.  
  8. def extract_features(imgs, feature_fns, verbose=False):
  9.   """
  10. Данный код выполняет применение нескольких функций признаков к пиксельным данным изображений и объединяет векторы признаков для каждого изображения, сохраняя признаки всех изображений в одной матрице.
  11.  
  12. Входные данные:
  13.  
  14. imgs: массив размерности N x H x W x C, содержащий пиксельные данные для N изображений. Здесь N - количество изображений, H - высота изображений, W - ширина изображений, C - количество каналов цвета.
  15. feature_fns: список из k функций признаков. i-я функция признаков должна принимать на вход массив размерности H x W x D и возвращать одномерный массив длины F_i.
  16. verbose: логическое значение; если значение равно True, то выводить прогресс выполнения.
  17.  
  18. Возвращаемое значение:
  19. Массив размерности (N, F_1 + ... + F_k), где каждый столбец представляет собой объединение всех признаков для одного изображения.
  20.  """
  21.   # Количество изображений в наборе
  22.   num_images = imgs.shape[0]
  23.   if num_images == 0:
  24.     return np.array([])
  25.  
  26.   # Используем первое изображение, чтобы определить размеры объекта.
  27.   feature_dims = [] # размерность признаков
  28.   first_image_features = [] # признаки первого изображения
  29.  
  30.   # определяем общую размерность признаков и выделяем память для хранения всех признаков всех изображений в одной матрице.
  31.   for feature_fn in feature_fns:
  32.     feats = feature_fn(imgs[0].squeeze()) # imgs[0].squeeze() используется для удаления измерения с размерностью 1 (если оно существует), чтобы получить двумерное изображение.
  33.     assert len(feats.shape) == 1, 'Feature functions must be one-dimensional' # выбрасываем исключение если размерность является одномерной
  34.     feature_dims.append(feats.size) # размерность признаков
  35.     first_image_features.append(feats) # Добавление признаков feats первого изображения
  36.  
  37.   # Теперь, когда мы знаем размеры объектов, мы можем выделить один
  38.   # большой массив для хранения всех функций в виде столбцов.
  39.   total_feature_dim = sum(feature_dims) # Вычисление общей размерности признаков путем       суммирования элементов
  40.   imgs_features = np.zeros((num_images, total_feature_dim)) # Создание нулевого массива в котором будут храниться признаки всех изображений. Каждое изображение будет представлено в виде строки этой матрицы
  41.   imgs_features[0] = np.hstack(first_image_features).T # Заполнение первой строки массива imgs_features признаками первого изображения. np.hstack(first_image_features) используется для горизонтальной конкатенации признаков первого изображения в одну строку, а .T используется для транспонирования этой строки в столбец.
  42.  
  43.   # Извлечение функций для остальных изображений.
  44.   for i in range(1, num_images):
  45.     idx = 0
  46.     for feature_fn, feature_dim in zip(feature_fns, feature_dims):
  47.       next_idx = idx + feature_dim # Вычисление индекса конца блока признаков для imgs_features[i]
  48.       imgs_features[i, idx:next_idx] = feature_fn(imgs[i].squeeze()) # Извлечение признаков из изображения imgs[i] и их присвоение соответствующему блоку признаков в строке imgs_features[i].
  49.       idx = next_idx # Обновление переменной idx для следующего блока признаков
  50.     if verbose and i % 1000 == 0:
  51.       print('Выполнено извлечение признаков для %d / %d изображений' % (i, num_images))
  52.  
  53.   return imgs_features
  54.  
  55.  
  56. def rgb2gray(rgb):
  57.   """Convert RGB image to grayscale
  58.  
  59.    Parameters:
  60.      rgb : RGB image
  61.  
  62.    Returns:
  63.      gray : grayscale image
  64.  
  65.  """
  66.   return np.dot(rgb[...,:3], [0.299, 0.587, 0.144])
  67.  
  68.  
  69. def hog_feature(im):
  70.   """Вычисление признака Histogram of Gradient (HOG) для изображения
  71.  
  72.       Modified from skimage.feature.hog
  73.       http://pydoc.net/Python/scikits-image/0.4.2/skimage.feature.hog
  74.    
  75.     Reference:
  76.       Histograms of Oriented Gradients for Human Detection
  77.       Navneet Dalal and Bill Triggs, CVPR 2005
  78.    
  79.    Параметры:
  80.    im: входное изображение в оттенках серого или RGB
  81.      
  82.    Возвращает:
  83.    feat: признак Histogram of Gradient (HOG)
  84.    
  85.  """
  86.  
  87.   # Если размерность im равна 3, то выполняется преобразование изображения в оттенки серого
  88.   if im.ndim == 3:
  89.     image = rgb2gray(im)
  90.   else:
  91.     image = np.at_least_2d(im) # преобразование im в массив с размерностью не менее 2
  92.  
  93.   sx, sy = image.shape # размеры изображения
  94.   orientations = 9 # количество ориентаций. ориентация означает направление градиента яркости в каждой точке изображения
  95.   cx, cy = (8, 8) # количество пикселей в ячейке
  96.  
  97.   # Вычисляем градиенты по x и по y
  98.   gx = np.zeros(image.shape)
  99.   gy = np.zeros(image.shape)
  100.   gx[:, :-1] = np.diff(image, n=1, axis=1)
  101.   gy[:-1, :] = np.diff(image, n=1, axis=0)
  102.    
  103.   grad_mag = np.sqrt(gx ** 2 + gy ** 2) # величина градиента
  104.   grad_ori = np.arctan2(gy, (gx + 1e-15)) * (180 / np.pi) + 90 # ориентация градиента. Для предотвращения деления на ноль, к gx добавляется небольшое значение 1e-15.
  105.  
  106.   n_cellsx = int(np.floor(sx / cx))  # количество ячеек по x
  107.   n_cellsy = int(np.floor(sy / cy))  # количество ячеек по y
  108.    
  109.   # инициализация ориентации гистограмм
  110.   orientation_histogram = np.zeros((n_cellsx, n_cellsy, orientations))
  111.   for i in range(orientations):
  112.     temp_ori = np.where(grad_ori < 180 / orientations * (i + 1), grad_ori, 0)
  113.     temp_ori = np.where(grad_ori >= 180 / orientations * i, temp_ori, 0)
  114.     # Выбираем величины для текущей ориентации
  115.     temp_mag = np.where(temp_ori > 0, grad_mag, 0)
  116.     # Используется функция uniform_filter для применения фильтра усреднения на temp_mag с размером (cx, cy). Результат этой операции сохраняется в orientation_histogram[:,:,i]. Затем выбираются значения из полученного массива с шагом int(cx/2) по оси x и шагом int(cy/2) по оси y.
  117.     orientation_histogram[:,:,i] = uniform_filter(temp_mag, size=(cx, cy))[int(cx/2)::cx, int(cy/2)::cy].T
  118.  
  119.   return orientation_histogram.ravel() # Возвращаем одномерный массив
  120.  
  121.  
  122. def color_histogram_hsv(im, nbin=10, xmin=0, xmax=255, normalized=True):
  123.   """
  124.  Compute color histogram for an image using hue.
  125.  
  126.  Inputs:
  127.  - im: H x W x C array of pixel data for an RGB image.
  128.  - nbin: Number of histogram bins. (default: 10)
  129.  - xmin: Minimum pixel value (default: 0)
  130.  - xmax: Maximum pixel value (default: 255)
  131.  - normalized: Whether to normalize the histogram (default: True)
  132.  
  133.  Returns:
  134.    1D vector of length nbin giving the color histogram over the hue of the
  135.    input image.
  136.  """
  137.   ndim = im.ndim
  138.   bins = np.linspace(xmin, xmax, nbin+1)
  139.   hsv = matplotlib.colors.rgb_to_hsv(im/xmax) * xmax
  140.   imhist, bin_edges = np.histogram(hsv[:,:,0], bins=bins, density=normalized)
  141.   imhist = imhist * np.diff(bin_edges)
  142.  
  143.   # return histogram
  144.   return imhist
  145.  
  146.  
  147. pass
  148.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement