DaSE-Computer-Vision-2021
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

150 lines
5.1 KiB

  1. from __future__ import print_function
  2. from builtins import zip
  3. from builtins import range
  4. from past.builtins import xrange
  5. import matplotlib
  6. import numpy as np
  7. from scipy.ndimage import uniform_filter
  8. def extract_features(imgs, feature_fns, verbose=False):
  9. """
  10. Given pixel data for images and several feature functions that can operate on
  11. single images, apply all feature functions to all images, concatenating the
  12. feature vectors for each image and storing the features for all images in
  13. a single matrix.
  14. Inputs:
  15. - imgs: N x H X W X C array of pixel data for N images.
  16. - feature_fns: List of k feature functions. The ith feature function should
  17. take as input an H x W x D array and return a (one-dimensional) array of
  18. length F_i.
  19. - verbose: Boolean; if true, print progress.
  20. Returns:
  21. An array of shape (N, F_1 + ... + F_k) where each column is the concatenation
  22. of all features for a single image.
  23. """
  24. num_images = imgs.shape[0]
  25. if num_images == 0:
  26. return np.array([])
  27. # Use the first image to determine feature dimensions
  28. feature_dims = []
  29. first_image_features = []
  30. for feature_fn in feature_fns:
  31. feats = feature_fn(imgs[0].squeeze())
  32. assert len(feats.shape) == 1, 'Feature functions must be one-dimensional'
  33. feature_dims.append(feats.size)
  34. first_image_features.append(feats)
  35. # Now that we know the dimensions of the features, we can allocate a single
  36. # big array to store all features as columns.
  37. total_feature_dim = sum(feature_dims)
  38. imgs_features = np.zeros((num_images, total_feature_dim))
  39. imgs_features[0] = np.hstack(first_image_features).T
  40. # Extract features for the rest of the images.
  41. for i in range(1, num_images):
  42. idx = 0
  43. for feature_fn, feature_dim in zip(feature_fns, feature_dims):
  44. next_idx = idx + feature_dim
  45. imgs_features[i, idx:next_idx] = feature_fn(imgs[i].squeeze())
  46. idx = next_idx
  47. if verbose and i % 1000 == 999:
  48. print('Done extracting features for %d / %d images' % (i+1, num_images))
  49. return imgs_features
  50. def rgb2gray(rgb):
  51. """Convert RGB image to grayscale
  52. Parameters:
  53. rgb : RGB image
  54. Returns:
  55. gray : grayscale image
  56. """
  57. return np.dot(rgb[...,:3], [0.299, 0.587, 0.144])
  58. def hog_feature(im):
  59. """Compute Histogram of Gradient (HOG) feature for an image
  60. Modified from skimage.feature.hog
  61. http://pydoc.net/Python/scikits-image/0.4.2/skimage.feature.hog
  62. Reference:
  63. Histograms of Oriented Gradients for Human Detection
  64. Navneet Dalal and Bill Triggs, CVPR 2005
  65. Parameters:
  66. im : an input grayscale or rgb image
  67. Returns:
  68. feat: Histogram of Gradient (HOG) feature
  69. """
  70. # convert rgb to grayscale if needed
  71. if im.ndim == 3:
  72. image = rgb2gray(im)
  73. else:
  74. image = np.at_least_2d(im)
  75. sx, sy = image.shape # image size
  76. orientations = 9 # number of gradient bins
  77. cx, cy = (8, 8) # pixels per cell
  78. gx = np.zeros(image.shape)
  79. gy = np.zeros(image.shape)
  80. gx[:, :-1] = np.diff(image, n=1, axis=1) # compute gradient on x-direction
  81. gy[:-1, :] = np.diff(image, n=1, axis=0) # compute gradient on y-direction
  82. grad_mag = np.sqrt(gx ** 2 + gy ** 2) # gradient magnitude
  83. grad_ori = np.arctan2(gy, (gx + 1e-15)) * (180 / np.pi) + 90 # gradient orientation
  84. n_cellsx = int(np.floor(sx / cx)) # number of cells in x
  85. n_cellsy = int(np.floor(sy / cy)) # number of cells in y
  86. # compute orientations integral images
  87. orientation_histogram = np.zeros((n_cellsx, n_cellsy, orientations))
  88. for i in range(orientations):
  89. # create new integral image for this orientation
  90. # isolate orientations in this range
  91. temp_ori = np.where(grad_ori < 180 / orientations * (i + 1),
  92. grad_ori, 0)
  93. temp_ori = np.where(grad_ori >= 180 / orientations * i,
  94. temp_ori, 0)
  95. # select magnitudes for those orientations
  96. cond2 = temp_ori > 0
  97. temp_mag = np.where(cond2, grad_mag, 0)
  98. orientation_histogram[:,:,i] = uniform_filter(temp_mag, size=(cx, cy))[round(cx/2)::cx, round(cy/2)::cy].T
  99. return orientation_histogram.ravel()
  100. def color_histogram_hsv(im, nbin=10, xmin=0, xmax=255, normalized=True):
  101. """
  102. Compute color histogram for an image using hue.
  103. Inputs:
  104. - im: H x W x C array of pixel data for an RGB image.
  105. - nbin: Number of histogram bins. (default: 10)
  106. - xmin: Minimum pixel value (default: 0)
  107. - xmax: Maximum pixel value (default: 255)
  108. - normalized: Whether to normalize the histogram (default: True)
  109. Returns:
  110. 1D vector of length nbin giving the color histogram over the hue of the
  111. input image.
  112. """
  113. ndim = im.ndim
  114. bins = np.linspace(xmin, xmax, nbin+1)
  115. hsv = matplotlib.colors.rgb_to_hsv(im/xmax) * xmax
  116. imhist, bin_edges = np.histogram(hsv[:,:,0], bins=bins, density=normalized)
  117. imhist = imhist * np.diff(bin_edges)
  118. # return histogram
  119. return imhist