Guest User

Untitled

a guest
Mar 21st, 2018
97
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.21 KB | None | 0 0
  1. '''Utilities to deploy a model as detector in a fully-convolutional fashion.
  2.  
  3. Author: Markus Rempfler
  4. '''
  5. import numpy as np
  6.  
  7.  
  8. def get_input_shape(model):
  9. '''
  10. '''
  11. return model.layers[0].input_shape
  12.  
  13.  
  14. def get_batch_size(model):
  15. '''
  16. '''
  17. return get_input_shape(model)[0]
  18.  
  19.  
  20. def get_output_shape(model):
  21. '''
  22. '''
  23. return model.layers[-1].output_shape
  24.  
  25.  
  26. def normalize(img_patch, eps=1e-9):
  27. '''normalize given image to zero mean and unit standard deviation.
  28.  
  29. Parameters
  30. ----------
  31. img_patch : Image type
  32. Image to be normalized.
  33. eps : float
  34. standard deviation regularizer.
  35.  
  36. '''
  37. return (img_patch - img_patch.mean()) / (img_patch.std() + eps)
  38.  
  39.  
  40. def predict_complete(model, image, border_size=None, step_size=None):
  41. '''applies a model to an entire image by stitching.
  42.  
  43. Parameters
  44. ----------
  45. model : Model type
  46. Model that is applied in an FCN fashion. Needs to provide
  47. model.predict() and be compatible to get_input_shape()
  48. image : Image type
  49. Image to be processed.
  50. border_size : int
  51. Size of border of processable image patches.
  52. step_size : tuple of (int, int)
  53. Step size for slicing. Either border_size or step_size
  54. need to be defined.
  55.  
  56. Returns
  57. -------
  58. prediction : Image type
  59. Prediction of given model for the provided image.
  60.  
  61. Notes
  62. -----
  63. Currently only working with single channel response models.
  64.  
  65. '''
  66. image_shape = image.shape
  67. input_shape = get_input_shape(model)
  68. batch_size = input_shape[0]
  69. patch_size = input_shape[1:]
  70.  
  71. if step_size is None and border_size is not None:
  72. step_size = (patch_size[0] - 2 * border_size,
  73. patch_size[1] - 2 * border_size)
  74. elif step_size is not None and border_size is None:
  75. border_size = (patch_size[0] - step_size[0]) / 2
  76. elif step_size is None and border_size is None:
  77. raise ValueError('Either border_size or step_size need to be defined')
  78.  
  79. # corners of patches.
  80. x = range(0, image_shape[0] - patch_size[0], step_size[0])
  81. y = range(0, image_shape[1] - patch_size[1], step_size[1])
  82. x.append(image_shape[0] - patch_size[0])
  83. y.append(image_shape[1] - patch_size[1])
  84. xy = [(i, j) for i in x for j in y]
  85.  
  86. def patch_generator(batch_size):
  87. img_batch = []
  88. while True:
  89. for i, j in xy:
  90. img_patch = image[i:i + patch_size[0], j:j + patch_size[1]]
  91. img_patch = normalize(img_patch)
  92. img_batch.append(img_patch)
  93.  
  94. if len(img_batch) == batch_size:
  95. yield np.asarray(img_batch)
  96. img_batch = []
  97.  
  98. if len(img_batch) > 0:
  99. last = img_batch[-1]
  100. for _ in xrange(batch_size - len(img_batch)):
  101. img_batch.append(last)
  102. yield np.asarray(img_batch)
  103. break
  104.  
  105. # predict on each patch.
  106. # TODO consider stitching and prediction concurrently.
  107. # NOTE The squeeze this is only compatible with single channel responses.
  108. responses = []
  109. for batch in patch_generator(batch_size):
  110. for rmap in model.predict(batch, batch_size=batch_size):
  111. responses.append(np.squeeze(rmap, axis=-1))
  112.  
  113. # re-assemble.
  114. # NOTE this assumes that input and output have the same shape.
  115. response_map = np.zeros([image_shape[0], image_shape[1]])
  116. for idx, (i, j) in enumerate(xy):
  117. offsetx = border_size if i > 0 else 0
  118. offsety = border_size if j > 0 else 0
  119.  
  120. response_map[i + offsetx:i + patch_size[0],
  121. j + offsety:j + patch_size[1]] = \
  122. responses[idx][offsetx:, offsety:]
  123.  
  124. return response_map
  125.  
  126.  
  127. class Detector(object):
  128. '''Wrapper class around detection models for usage in
  129. a fully convolutional setting.
  130.  
  131. '''
  132.  
  133. def __init__(self, model, **kwargs):
  134. '''
  135. '''
  136. self.model = model
  137. self.pred_kwargs = kwargs
  138.  
  139. def predict_complete(self, input_img):
  140. '''
  141. '''
  142. return predict_complete(self.model, input_img, **self.pred_kwargs)
  143.  
  144.  
  145. def make_detector(model, **kwargs):
  146. '''creates a convolutional detector from a given model.
  147. '''
  148. return Detector(model, **kwargs)
Add Comment
Please, Sign In to add comment