test_gaussian_mix.py 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. #!/usr/bin/env python
  2. # Python 2/3 compatibility
  3. from __future__ import print_function
  4. import sys
  5. PY3 = sys.version_info[0] == 3
  6. if PY3:
  7. xrange = range
  8. import numpy as np
  9. from numpy import random
  10. import cv2 as cv
  11. def make_gaussians(cluster_n, img_size):
  12. points = []
  13. ref_distrs = []
  14. for _ in xrange(cluster_n):
  15. mean = (0.1 + 0.8*random.rand(2)) * img_size
  16. a = (random.rand(2, 2)-0.5)*img_size*0.1
  17. cov = np.dot(a.T, a) + img_size*0.05*np.eye(2)
  18. n = 100 + random.randint(900)
  19. pts = random.multivariate_normal(mean, cov, n)
  20. points.append( pts )
  21. ref_distrs.append( (mean, cov) )
  22. points = np.float32( np.vstack(points) )
  23. return points, ref_distrs
  24. from tests_common import NewOpenCVTests
  25. class gaussian_mix_test(NewOpenCVTests):
  26. def test_gaussian_mix(self):
  27. np.random.seed(10)
  28. cluster_n = 5
  29. img_size = 512
  30. points, ref_distrs = make_gaussians(cluster_n, img_size)
  31. em = cv.ml.EM_create()
  32. em.setClustersNumber(cluster_n)
  33. em.setCovarianceMatrixType(cv.ml.EM_COV_MAT_GENERIC)
  34. em.trainEM(points)
  35. means = em.getMeans()
  36. covs = em.getCovs() # Known bug: https://github.com/opencv/opencv/pull/4232
  37. #found_distrs = zip(means, covs)
  38. matches_count = 0
  39. meanEps = 0.05
  40. covEps = 0.1
  41. for i in range(cluster_n):
  42. for j in range(cluster_n):
  43. if (cv.norm(means[i] - ref_distrs[j][0], cv.NORM_L2) / cv.norm(ref_distrs[j][0], cv.NORM_L2) < meanEps and
  44. cv.norm(covs[i] - ref_distrs[j][1], cv.NORM_L2) / cv.norm(ref_distrs[j][1], cv.NORM_L2) < covEps):
  45. matches_count += 1
  46. self.assertEqual(matches_count, cluster_n)
  47. if __name__ == '__main__':
  48. NewOpenCVTests.bootstrap()