Creates per-pixel and per-image coverage mask of the blur score based on the PIQE algorithm.
Parameters:
| Name |
Type |
Description |
Default |
img
|
RGBImage
|
RGB Image of the tissue, minimum size 10x10 pixels.
|
required
|
pixel_size
|
float
|
Size of a pixel in micrometers. The score is most accurate
at pixel sizes around 0.44 micrometers.
|
0.44
|
foreground_mask
|
BinaryMask | None
|
Binary mask of the tissue, where 1 represents tissue and 0 represents background.
If not provided, foreground mask is computed by simple_foreground_mask function.
foreground_mask is used to nullify blur detections in the background.
The standard tissue mask has proven to be too coarse for this use, especially
for tiles with little or no background.
|
None
|
Returns:
| Type |
Description |
BlurScore
|
Dictionary with the per-pixel and coverage mask
blur_score_per_pixel - binary mask composed of 16x16 px blocks marking blurred areas.
blur_score_coverage - coverage mask of the per_pixel detections. Coverage ranges from 0.0 to 1.0.
|
Note
The returned dictionary contains the following values:
| Key |
Description |
blur_score_per_pixel |
Binary mask of the blur score. |
blur_score_coverage |
Coverage mask of the blur score. |
Examples:
from skimage.data import immunohistochemistry
from rationai.qc.blur import blur_score_piqe
img = immunohistochemistry()
pixel_size = 0.44 # pixel size of img in micrometers
result = blur_score_piqe(img, pixel_size)
# Mask of the blur coverage range from 0.0 to 1.0
coverage_mask = result["blur_score_coverage"]
# Binary mask of the blur detections
blur_score_per_pixel = result["blur_score_per_pixel"]
Source code in rationai/qc/blur/blur_score_piqe.py
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95 | def blur_score_piqe(
img: RGBImage,
pixel_size: float = 0.44,
foreground_mask: BinaryMask | None = None,
) -> BlurScore:
"""Creates per-pixel and per-image coverage mask of the blur score based on the PIQE algorithm.
Args:
img: RGB Image of the tissue, minimum size 10x10 pixels.
pixel_size: Size of a pixel in micrometers. The score is most accurate
at pixel sizes around 0.44 micrometers.
foreground_mask: Binary mask of the tissue, where 1 represents tissue and 0 represents background.
If not provided, foreground mask is computed by `simple_foreground_mask` function.
foreground_mask is used to nullify blur detections in the background.
The standard tissue mask has proven to be too coarse for this use, especially
for tiles with little or no background.
Returns:
Dictionary with the per-pixel and coverage mask
blur_score_per_pixel - binary mask composed of 16x16 px blocks marking blurred areas.
blur_score_coverage - coverage mask of the per_pixel detections. Coverage ranges from 0.0 to 1.0.
Note:
The returned dictionary contains the following values:
| Key | Description |
|-----------------------|---------------------------------|
| `blur_score_per_pixel`| Binary mask of the blur score. |
| `blur_score_coverage` | Coverage mask of the blur score.|
Examples:
```python
from skimage.data import immunohistochemistry
from rationai.qc.blur import blur_score_piqe
img = immunohistochemistry()
pixel_size = 0.44 # pixel size of img in micrometers
result = blur_score_piqe(img, pixel_size)
# Mask of the blur coverage range from 0.0 to 1.0
coverage_mask = result["blur_score_coverage"]
# Binary mask of the blur detections
blur_score_per_pixel = result["blur_score_per_pixel"]
```
"""
# Used for calculating the kernel size
# for the median filter based on the pixel size
optimal_pixel_size = 0.44
kernel_size = 2 * round(1 / pixel_size * optimal_pixel_size + 1e-9) + 1
grayscale_img = median(
rgb2gray(img), footprint=np.ones((kernel_size, kernel_size), dtype=bool)
)
(
_, # Piqe score (not relevant for our purposes)
_, # Noticeable artifacts mask
_, # Noise mask
activity_mask,
) = piqe(
grayscale_img * 255
) # grayscale_img is pixel array with values between 0 and 1, piqe expects values between 0 and 255
# Activity mask is one column shorter for images
# with dimensions that are not divisible by 16
if grayscale_img.shape != activity_mask.shape:
activity_mask = np.pad(activity_mask, ((0, 0), (0, 1)), mode="edge")
if foreground_mask is None:
foreground_mask = simple_foreground_mask(grayscale_img)
# activity_mask is inverted, blurred areas and empty areas (background) are set to 1
activity_mask = ~(activity_mask > 0)
# activity_mask is multiplied by the foreground mask to nullify background pixels
activity_mask = activity_mask * foreground_mask
return {
"blur_score_per_pixel": activity_mask > 0,
"blur_score_coverage": get_coverage_mask(
grayscale_img, activity_mask, foreground_mask
),
}
|