_contingency_table.py 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. import scipy.sparse as sparse
  2. import numpy as np
  3. __all__ = ['contingency_table']
  4. def contingency_table(
  5. im_true, im_test, *, ignore_labels=None, normalize=False, sparse_type="matrix"
  6. ):
  7. """
  8. Return the contingency table for all regions in matched segmentations.
  9. Parameters
  10. ----------
  11. im_true : ndarray of int
  12. Ground-truth label image, same shape as im_test.
  13. im_test : ndarray of int
  14. Test image.
  15. ignore_labels : sequence of int, optional
  16. Labels to ignore. Any part of the true image labeled with any of these
  17. values will not be counted in the score.
  18. normalize : bool
  19. Determines if the contingency table is normalized by pixel count.
  20. sparse_type : {"matrix", "array"}, optional
  21. The return type of `cont`, either `scipy.sparse.csr_array` or
  22. `scipy.sparse.csr_matrix` (default).
  23. Returns
  24. -------
  25. cont : scipy.sparse.csr_matrix or scipy.sparse.csr_array
  26. A contingency table. `cont[i, j]` will equal the number of voxels
  27. labeled `i` in `im_true` and `j` in `im_test`. Depending on `sparse_type`,
  28. this can be returned as a `scipy.sparse.csr_array`.
  29. """
  30. if ignore_labels is None:
  31. ignore_labels = []
  32. im_test_r = im_test.reshape(-1)
  33. im_true_r = im_true.reshape(-1)
  34. data = np.isin(im_true_r, ignore_labels, invert=True).astype(float)
  35. if normalize:
  36. data /= np.count_nonzero(data)
  37. cont = sparse.csr_array((data, (im_true_r, im_test_r)))
  38. if sparse_type == "matrix":
  39. cont = sparse.csr_matrix(cont)
  40. elif sparse_type != "array":
  41. msg = f"`sparse_type` must be 'array' or 'matrix', got {sparse_type}"
  42. raise ValueError(msg)
  43. return cont