Skip to content

Commit 615d7f8

Browse files
committed
feat: implement image statistical comparison methods
New methods: - Shannon cross-entropy [ratio] - Shannon entropy ratio - Retained variance - Structural similarity index ratio
1 parent 73b65fd commit 615d7f8

File tree

1 file changed

+57
-4
lines changed

1 file changed

+57
-4
lines changed

boiling_learning/preprocessing/image.py

+57-4
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,25 @@
55
import tensorflow as tf
66
from scipy.stats import entropy
77
from skimage.color import rgb2gray
8+
from skimage.exposure import histogram
9+
from skimage.measure import shannon_entropy
10+
from skimage.metrics import structural_similarity as ssim
811
from skimage.transform import AffineTransform, resize, warp
912

1013
T = TypeVar('T')
1114
ImageType = Any # something convertible to tf.Tensor
1215

1316

17+
def reshape_to_largest(
18+
image0: np.ndarray, image1: np.ndarray
19+
) -> Tuple[np.ndarray, np.ndarray]:
20+
if image0.shape != image1.shape:
21+
max_shape = np.maximum(image0.shape, image1.shape)
22+
image0 = resize(image0, max_shape)
23+
image1 = resize(image1, max_shape)
24+
return image0, image1
25+
26+
1427
def _ratio_to_size(
1528
image: ImageType, x: Optional[Union[int, float]], axis: int
1629
) -> Optional[int]:
@@ -242,10 +255,7 @@ def normalized_mutual_information(
242255
f'Got {image0.ndim}D for `image0` and {image1.ndim}D for `image1`.'
243256
)
244257

245-
if image0.shape != image1.shape:
246-
max_shape = np.maximum(image0.shape, image1.shape)
247-
image0 = resize(image0, max_shape)
248-
image1 = resize(image1, max_shape)
258+
image0, image1 = reshape_to_largest(image0, image1)
249259

250260
hist, _ = np.histogramdd(
251261
[np.reshape(image0, -1), np.reshape(image1, -1)],
@@ -258,3 +268,46 @@ def normalized_mutual_information(
258268
H01 = entropy(np.reshape(hist, -1))
259269

260270
return (H0 + H1) / H01 - 1
271+
272+
273+
def structural_similarity_ratio(ref: np.ndarray, image: np.ndarray) -> float:
274+
# see
275+
# <https://www.wikiwand.com/en/Structural_similarity#/Application_of_the_formula>
276+
WINDOW_SIZE: int = 11
277+
278+
ref, image = reshape_to_largest(ref, image)
279+
ref = np.squeeze(ref)
280+
image = np.squeeze(image)
281+
282+
return ssim(ref, image, win_size=WINDOW_SIZE) / ssim(
283+
ref, ref, win_size=WINDOW_SIZE
284+
)
285+
286+
287+
def _image_variance(image: np.ndarray) -> float:
288+
return float(np.var(image, axis=(0, 1)))
289+
290+
291+
def retained_variance(ref: np.ndarray, image: np.ndarray) -> float:
292+
return _image_variance(image) / _image_variance(ref)
293+
294+
295+
def shannon_cross_entropy(
296+
ref: np.ndarray, image: np.ndarray, nbins: int = 100
297+
) -> float:
298+
ref_histogram, _ = histogram(ref, nbins=nbins)
299+
img_histogram, _ = histogram(image, nbins=nbins)
300+
301+
return -float(np.sum(ref_histogram * np.log(img_histogram)))
302+
303+
304+
def shannon_cross_entropy_ratio(
305+
ref: np.ndarray, image: np.ndarray, nbins: int = 100
306+
) -> float:
307+
return shannon_cross_entropy(
308+
ref, image, nbins=nbins
309+
) / shannon_cross_entropy(ref, ref, nbins=nbins)
310+
311+
312+
def shannon_entropy_ratio(ref: np.ndarray, image: np.ndarray) -> float:
313+
return shannon_entropy(image) / shannon_entropy(ref)

0 commit comments

Comments
 (0)