kernels.py 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. """
  2. Kernel to apply on images using convolution
  3. """
  4. # main imports
  5. import numpy as np
  6. import sys
  7. def plane_mean(window):
  8. """Plane mean kernel to use with convolution process on image
  9. Args:
  10. window: the window part to use from image
  11. Returns:
  12. Normalized residual error from mean plane
  13. Example:
  14. >>> from ipfml.filters.kernels import plane_mean
  15. >>> import numpy as np
  16. >>> window = np.arange(9).reshape([3, 3])
  17. >>> result = plane_mean(window)
  18. >>> (result < 0.0001)
  19. True
  20. """
  21. window = np.array(window)
  22. width, height = window.shape
  23. # prepare data
  24. nb_elem = width * height
  25. xs = [int(i / height) for i in range(nb_elem)]
  26. ys = [i % height for i in range(nb_elem)]
  27. zs = np.array(window).flatten().tolist()
  28. # get residual (error) from mean plane computed
  29. tmp_A = []
  30. tmp_b = []
  31. for i in range(len(xs)):
  32. tmp_A.append([xs[i], ys[i], 1])
  33. tmp_b.append(zs[i])
  34. b = np.matrix(tmp_b).T
  35. A = np.matrix(tmp_A)
  36. fit = (A.T * A).I * A.T * b
  37. errors = b - A * fit
  38. residual = np.linalg.norm(errors)
  39. return residual
  40. # return difference between min and max errors
  41. def plane_max_error(window):
  42. """Plane max error kernel to use with convolution process on image
  43. Args:
  44. window: the window part to use from image
  45. Returns:
  46. Difference between max and min error from mean plane
  47. Example:
  48. >>> from ipfml.filters.kernels import plane_max_error
  49. >>> import numpy as np
  50. >>> window = np.arange(9).reshape([3, 3])
  51. >>> result = plane_max_error(window)
  52. >>> (result < 0.0001)
  53. True
  54. """
  55. window = np.array(window)
  56. width, height = window.shape
  57. # prepare data
  58. nb_elem = width * height
  59. xs = [int(i / height) for i in range(nb_elem)]
  60. ys = [i % height for i in range(nb_elem)]
  61. zs = np.array(window).flatten().tolist()
  62. # get residual (error) from mean plane computed
  63. tmp_A = []
  64. tmp_b = []
  65. for i in range(len(xs)):
  66. tmp_A.append([xs[i], ys[i], 1])
  67. tmp_b.append(zs[i])
  68. b = np.matrix(tmp_b).T
  69. A = np.matrix(tmp_A)
  70. fit = (A.T * A).I * A.T * b
  71. errors = b - A * fit
  72. # get absolute values from errors
  73. errors = abs(np.array(errors))
  74. return (errors.max() - errors.min())
  75. def _bilateral_diff(window, func):
  76. """Main bilateral difference kernel to use with convolution process on image
  77. Apply difference pixel to pixel and keep max on min difference before applying mean
  78. Args:
  79. window: the window part to use from image
  80. func: max or min function to get difference between pixels
  81. Returns:
  82. mean of max or min difference of pixels
  83. """
  84. window = np.array(window)
  85. width, height = window.shape
  86. total_row_diff_list = []
  87. total_col_diff_list = []
  88. for i in range(width):
  89. row_diff_list = []
  90. col_diff_list = []
  91. for j in range(height):
  92. diff_row = 0
  93. if i == 0:
  94. diff_row = abs(window[i][j] - window[i + 1][j])
  95. elif i == width - 1:
  96. diff_row = abs(window[i][j] - window[i - 1][j])
  97. else:
  98. diff1 = abs(window[i][j] - window[i - 1][j])
  99. diff2 = abs(window[i][j] - window[i + 1][j])
  100. diff_row = func(diff1, diff2)
  101. if j == 0:
  102. diff_col = abs(window[i][j] - window[i][j + 1])
  103. elif j == height - 1:
  104. diff_col = abs(window[i][j] - window[i][j - 1])
  105. else:
  106. diff1 = abs(window[i][j] - window[i][j - 1])
  107. diff2 = abs(window[i][j] - window[i][j + 1])
  108. diff_col = func(diff1, diff2)
  109. row_diff_list.append(diff_row)
  110. col_diff_list.append(diff_col)
  111. total_row_diff_list.append(sum(row_diff_list) / len(row_diff_list))
  112. total_col_diff_list.append(sum(col_diff_list) / len(col_diff_list))
  113. row_diff = sum(total_row_diff_list) / len(total_row_diff_list)
  114. col_diff = sum(total_col_diff_list) / len(total_col_diff_list)
  115. return func(row_diff, col_diff)
  116. def max_bilateral_diff(window):
  117. """Bilateral difference kernel to use with convolution process on image
  118. Apply difference pixel to pixel and keep max difference before applying mean
  119. Args:
  120. window: the window part to use from image
  121. Returns:
  122. mean of max difference of pixels
  123. Example:
  124. >>> from ipfml.filters.kernels import max_bilateral_diff
  125. >>> import numpy as np
  126. >>> window = np.arange(9).reshape([3, 3])
  127. >>> result = max_bilateral_diff(window)
  128. >>> result
  129. 3.0
  130. """
  131. return _bilateral_diff(window, max)
  132. def min_bilateral_diff(window):
  133. """Bilateral difference kernel to use with convolution process on image
  134. Apply difference pixel to pixel and keep min difference before applying mean
  135. Args:
  136. window: the window part to use from image
  137. Returns:
  138. mean of min difference of pixels
  139. Example:
  140. >>> from ipfml.filters.kernels import min_bilateral_diff
  141. >>> import numpy as np
  142. >>> window = np.arange(9).reshape([3, 3])
  143. >>> result = min_bilateral_diff(window)
  144. >>> result
  145. 1.0
  146. """
  147. return _bilateral_diff(window, min)