test_norm.py 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. #!/usr/bin/env python
  2. from itertools import product
  3. from functools import reduce
  4. import numpy as np
  5. import cv2 as cv
  6. from tests_common import NewOpenCVTests
  7. def norm_inf(x, y=None):
  8. def norm(vec):
  9. return np.linalg.norm(vec.flatten(), np.inf)
  10. x = x.astype(np.float64)
  11. return norm(x) if y is None else norm(x - y.astype(np.float64))
  12. def norm_l1(x, y=None):
  13. def norm(vec):
  14. return np.linalg.norm(vec.flatten(), 1)
  15. x = x.astype(np.float64)
  16. return norm(x) if y is None else norm(x - y.astype(np.float64))
  17. def norm_l2(x, y=None):
  18. def norm(vec):
  19. return np.linalg.norm(vec.flatten())
  20. x = x.astype(np.float64)
  21. return norm(x) if y is None else norm(x - y.astype(np.float64))
  22. def norm_l2sqr(x, y=None):
  23. def norm(vec):
  24. return np.square(vec).sum()
  25. x = x.astype(np.float64)
  26. return norm(x) if y is None else norm(x - y.astype(np.float64))
  27. def norm_hamming(x, y=None):
  28. def norm(vec):
  29. return sum(bin(i).count('1') for i in vec.flatten())
  30. return norm(x) if y is None else norm(np.bitwise_xor(x, y))
  31. def norm_hamming2(x, y=None):
  32. def norm(vec):
  33. def element_norm(element):
  34. binary_str = bin(element).split('b')[-1]
  35. if len(binary_str) % 2 == 1:
  36. binary_str = '0' + binary_str
  37. gen = filter(lambda p: p != '00',
  38. (binary_str[i:i+2]
  39. for i in range(0, len(binary_str), 2)))
  40. return sum(1 for _ in gen)
  41. return sum(element_norm(element) for element in vec.flatten())
  42. return norm(x) if y is None else norm(np.bitwise_xor(x, y))
  43. norm_type_under_test = {
  44. cv.NORM_INF: norm_inf,
  45. cv.NORM_L1: norm_l1,
  46. cv.NORM_L2: norm_l2,
  47. cv.NORM_L2SQR: norm_l2sqr,
  48. cv.NORM_HAMMING: norm_hamming,
  49. cv.NORM_HAMMING2: norm_hamming2
  50. }
  51. norm_name = {
  52. cv.NORM_INF: 'inf',
  53. cv.NORM_L1: 'L1',
  54. cv.NORM_L2: 'L2',
  55. cv.NORM_L2SQR: 'L2SQR',
  56. cv.NORM_HAMMING: 'Hamming',
  57. cv.NORM_HAMMING2: 'Hamming2'
  58. }
  59. def get_element_types(norm_type):
  60. if norm_type in (cv.NORM_HAMMING, cv.NORM_HAMMING2):
  61. return (np.uint8,)
  62. else:
  63. return (np.uint8, np.int8, np.uint16, np.int16, np.int32, np.float32,
  64. np.float64)
  65. def generate_vector(shape, dtype):
  66. if np.issubdtype(dtype, np.integer):
  67. return np.random.randint(0, 100, shape).astype(dtype)
  68. else:
  69. return np.random.normal(10., 12.5, shape).astype(dtype)
  70. shapes = (1, 2, 3, 5, 7, 16, (1, 1), (2, 2), (3, 5), (1, 7))
  71. class norm_test(NewOpenCVTests):
  72. def test_norm_for_one_array(self):
  73. np.random.seed(123)
  74. for norm_type, norm in norm_type_under_test.items():
  75. element_types = get_element_types(norm_type)
  76. for shape, element_type in product(shapes, element_types):
  77. array = generate_vector(shape, element_type)
  78. expected = norm(array)
  79. actual = cv.norm(array, norm_type)
  80. self.assertAlmostEqual(
  81. expected, actual, places=2,
  82. msg='Array {0} of {1} and norm {2}'.format(
  83. array, element_type.__name__, norm_name[norm_type]
  84. )
  85. )
  86. def test_norm_for_two_arrays(self):
  87. np.random.seed(456)
  88. for norm_type, norm in norm_type_under_test.items():
  89. element_types = get_element_types(norm_type)
  90. for shape, element_type in product(shapes, element_types):
  91. first = generate_vector(shape, element_type)
  92. second = generate_vector(shape, element_type)
  93. expected = norm(first, second)
  94. actual = cv.norm(first, second, norm_type)
  95. self.assertAlmostEqual(
  96. expected, actual, places=2,
  97. msg='Arrays {0} {1} of type {2} and norm {3}'.format(
  98. first, second, element_type.__name__,
  99. norm_name[norm_type]
  100. )
  101. )
  102. def test_norm_fails_for_wrong_type(self):
  103. for norm_type in (cv.NORM_HAMMING, cv.NORM_HAMMING2):
  104. with self.assertRaises(Exception,
  105. msg='Type is not checked {0}'.format(
  106. norm_name[norm_type]
  107. )):
  108. cv.norm(np.array([1, 2], dtype=np.int32), norm_type)
  109. def test_norm_fails_for_array_and_scalar(self):
  110. for norm_type in norm_type_under_test:
  111. with self.assertRaises(Exception,
  112. msg='Exception is not thrown for {0}'.format(
  113. norm_name[norm_type]
  114. )):
  115. cv.norm(np.array([1, 2], dtype=np.uint8), 123, norm_type)
  116. def test_norm_fails_for_scalar_and_array(self):
  117. for norm_type in norm_type_under_test:
  118. with self.assertRaises(Exception,
  119. msg='Exception is not thrown for {0}'.format(
  120. norm_name[norm_type]
  121. )):
  122. cv.norm(4, np.array([1, 2], dtype=np.uint8), norm_type)
  123. def test_norm_fails_for_array_and_norm_type_as_scalar(self):
  124. for norm_type in norm_type_under_test:
  125. with self.assertRaises(Exception,
  126. msg='Exception is not thrown for {0}'.format(
  127. norm_name[norm_type]
  128. )):
  129. cv.norm(np.array([3, 4, 5], dtype=np.uint8),
  130. norm_type, normType=norm_type)
  131. if __name__ == '__main__':
  132. NewOpenCVTests.bootstrap()