Skip to content

Commit

Permalink
Merge pull request #296 from nanli-emory/num_tissues
Browse files Browse the repository at this point in the history
get num tissues
  • Loading branch information
jacksonjacobs1 authored Jul 22, 2024
2 parents 6f0bacd + 222c372 commit 26a98cb
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 55 deletions.
28 changes: 24 additions & 4 deletions histoqc/BaseImage.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from typing import Union, Tuple
#os.environ['PATH'] = 'C:\\research\\openslide\\bin' + ';' + os.environ['PATH'] #can either specify openslide bin path in PATH, or add it dynamically
from histoqc.import_wrapper.openslide import openslide

from skimage import measure, morphology
# there is no branch reset group in re
# compatible with the previous definition of valid input: leading zero and leading decimals are supported
_REGEX_MAG = r"^(\d?\.?\d*X?)"
Expand Down Expand Up @@ -206,6 +206,9 @@ def getImgThumb(self, size: str):
self[key] = getBestThumb(self, bx, by, target_dims, target_sampling_factor)
return self[key]

'''
the following are helper functions
'''
def getBestThumb(s: BaseImage, x: int, y: int, dims: Tuple[int, int], target_sampling_factor: float):
osh = s["os_handle"]

Expand All @@ -224,9 +227,7 @@ def getBestThumb(s: BaseImage, x: int, y: int, dims: Tuple[int, int], target_sam
else:
return resizeTileDownward(s, target_sampling_factor, level)

'''
the followings are helper functions
'''

def resizeTileDownward(self, target_downsampling_factor, level):
osh = self["os_handle"]
(bx, by, bwidth, bheight) = self["img_bbox"]
Expand Down Expand Up @@ -341,3 +342,22 @@ def getDimensionsByOneDim(s: BaseImage, dim: int) -> Tuple[int, int]:
else:
w = int(dim * width / height)
return w, dim


def getMaskRegionsStats(img)-> dict:

rps = measure.regionprops(morphology.label(img))
if rps:
areas = np.asarray([rp.area for rp in rps])
num = len(rps)
area_min = areas.min()
area_max = areas.max()
area_mean = areas.mean()
else:
num = area_min = area_max = area_mean = 0
return {
'num': num,
'area_min': area_min,
'area_max': area_max,
'area_mean': area_mean
}
8 changes: 7 additions & 1 deletion histoqc/BasicModule.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import logging
import os
from histoqc.BaseImage import printMaskHelper
from histoqc.BaseImage import printMaskHelper, getMaskRegionsStats
from skimage.morphology import remove_small_objects, binary_opening, disk
from skimage import io, color, img_as_ubyte

Expand Down Expand Up @@ -69,3 +69,9 @@ def finalProcessingArea(s, params):
f"{s['filename']} - After BasicModule.finalProcessingArea NO tissue remains detectable! Downstream modules likely to be incorrect/fail")
s["warnings"].append(
f"After BasicModule.finalProcessingArea NO tissue remains detectable! Downstream modules likely to be incorrect/fail")


def countTissuePieces(s):
mask = s["img_mask_use"]
stats = getMaskRegionsStats(mask)
s.addToPrintList("#pieces_of_tissue", str(stats.get('num', 0)))
29 changes: 15 additions & 14 deletions histoqc/BlurDetectionModule.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import os

import skimage
from histoqc.BaseImage import printMaskHelper
from histoqc.BaseImage import printMaskHelper, getMaskRegionsStats
from skimage import io, img_as_ubyte, morphology, measure
from skimage.color import rgb2gray
from skimage.filters import rank
Expand Down Expand Up @@ -37,19 +37,20 @@ def identifyBlurryRegions(s, params):
prev_mask = s["img_mask_use"]
s["img_mask_use"] = s["img_mask_use"] & ~s["img_mask_blurry"]

rps = measure.regionprops(morphology.label(mask))
if rps:
areas = np.asarray([rp.area for rp in rps])
nobj = len(rps)
area_max = areas.max()
area_mean = areas.mean()
else:
nobj = area_max = area_mean = 0


s.addToPrintList("blurry_removed_num_regions", str(nobj))
s.addToPrintList("blurry_removed_mean_area", str(area_mean))
s.addToPrintList("blurry_removed_max_area", str(area_max))
# rps = measure.regionprops(morphology.label(mask))
# if rps:
# areas = np.asarray([rp.area for rp in rps])
# nobj = len(rps)
# area_max = areas.max()
# area_mean = areas.mean()
# else:
# nobj = area_max = area_mean = 0
stat_rs = getMaskRegionsStats(mask)


s.addToPrintList("blurry_removed_num_regions", str(stat_rs.get('num', 0)))
s.addToPrintList("blurry_removed_mean_area", str(stat_rs.get('area_mean',0)))
s.addToPrintList("blurry_removed_max_area", str(stat_rs.get('area_max',0)))


s.addToPrintList("blurry_removed_percent",
Expand Down
82 changes: 47 additions & 35 deletions histoqc/MorphologyModule.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import logging
import os
import numpy as np
from histoqc.BaseImage import printMaskHelper
from histoqc.BaseImage import printMaskHelper, getMaskRegionsStats
from skimage import io, morphology, img_as_ubyte, measure

from scipy import ndimage as ndi
Expand All @@ -23,19 +23,23 @@ def removeSmallObjects(s, params):
s["img_mask_use"] = img_reduced


rps = measure.regionprops(morphology.label(img_small))
if rps:
areas = np.asarray([rp.area for rp in rps])
nobj = len(rps)
area_max = areas.max()
area_mean = areas.mean()
else:
nobj = area_max = area_mean = 0
# rps = measure.regionprops(morphology.label(img_small))
# if rps:
# areas = np.asarray([rp.area for rp in rps])
# nobj = len(rps)
# area_max = areas.max()
# area_mean = areas.mean()
# else:
# nobj = area_max = area_mean = 0
stats = getMaskRegionsStats(img_small)

s.addToPrintList("small_tissue_removed_num_regions", str(nobj))
s.addToPrintList("small_tissue_removed_mean_area", str(area_mean))
s.addToPrintList("small_tissue_removed_max_area", str(area_max))

# s.addToPrintList("small_tissue_removed_num_regions", str(nobj))
# s.addToPrintList("small_tissue_removed_mean_area", str(area_mean))
# s.addToPrintList("small_tissue_removed_max_area", str(area_max))
s.addToPrintList("small_tissue_removed_num_regions", str(stats.get('num',0)))
s.addToPrintList("small_tissue_removed_mean_area", str(stats.get('area_mean',0)))
s.addToPrintList("small_tissue_removed_max_area", str(stats.get('area_max',0)))



Expand Down Expand Up @@ -87,18 +91,22 @@ def removeFatlikeTissue(s, params):
prev_mask = s["img_mask_use"]
s["img_mask_use"] = prev_mask & ~mask_fat

rps = measure.regionprops(morphology.label(mask_fat))
if rps:
areas = np.asarray([rp.area for rp in rps])
nobj = len(rps)
area_max = areas.max()
area_mean = areas.mean()
else:
nobj = area_max = area_mean = 0
# rps = measure.regionprops(morphology.label(mask_fat))
# if rps:
# areas = np.asarray([rp.area for rp in rps])
# nobj = len(rps)
# area_max = areas.max()
# area_mean = areas.mean()
# else:
# nobj = area_max = area_mean = 0
stats = getMaskRegionsStats(mask_fat)

s.addToPrintList("fatlike_tissue_removed_num_regions", str(nobj))
s.addToPrintList("fatlike_tissue_removed_mean_area", str(area_mean))
s.addToPrintList("fatlike_tissue_removed_max_area", str(area_max))
# s.addToPrintList("fatlike_tissue_removed_num_regions", str(nobj))
# s.addToPrintList("fatlike_tissue_removed_mean_area", str(area_mean))
# s.addToPrintList("fatlike_tissue_removed_max_area", str(area_max))
s.addToPrintList("fatlike_tissue_removed_num_regions", str(stats.get('num',0)))
s.addToPrintList("fatlike_tissue_removed_mean_area", str(stats.get('area_mean',0)))
s.addToPrintList("fatlike_tissue_removed_max_area", str(stats.get('area_max',0)))



Expand All @@ -125,18 +133,22 @@ def fillSmallHoles(s, params):
prev_mask = s["img_mask_use"]
s["img_mask_use"] = img_reduced

rps = measure.regionprops(morphology.label(img_small))
if rps:
areas = np.asarray([rp.area for rp in rps])
nobj = len(rps)
area_max = areas.max()
area_mean = areas.mean()
else:
nobj = area_max = area_mean = 0

s.addToPrintList("small_tissue_filled_num_regions", str(nobj))
s.addToPrintList("small_tissue_filled_mean_area", str(area_mean))
s.addToPrintList("small_tissue_filled_max_area", str(area_max))
# rps = measure.regionprops(morphology.label(img_small))
# if rps:
# areas = np.asarray([rp.area for rp in rps])
# nobj = len(rps)
# area_max = areas.max()
# area_mean = areas.mean()
# else:
# nobj = area_max = area_mean = 0
stats = getMaskRegionsStats(img_small)

# s.addToPrintList("small_tissue_filled_num_regions", str(nobj))
# s.addToPrintList("small_tissue_filled_mean_area", str(area_mean))
# s.addToPrintList("small_tissue_filled_max_area", str(area_max))
s.addToPrintList("small_tissue_filled_num_regions", str(stats.get('num', 0)))
s.addToPrintList("small_tissue_filled_mean_area", str(stats.get('area_mean', 0)))
s.addToPrintList("small_tissue_filled_max_area", str(stats.get('area_max', 0)))

s.addToPrintList("small_tissue_filled_percent",
printMaskHelper(params.get("mask_statistics", s["mask_statistics"]), prev_mask, s["img_mask_use"]))
Expand Down
5 changes: 4 additions & 1 deletion histoqc/config/config_v2.1.ini
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,9 @@ steps= BasicModule.getBasicStats
SaveModule.saveFinalMask
SaveModule.saveMacro
SaveModule.saveThumbnails
BasicModule.countTissuePieces
BasicModule.finalComputations


[BaseImage.BaseImage]
image_work_size = 1.25x
Expand Down Expand Up @@ -252,3 +253,5 @@ mask_name: img_mask_use
disk_size: 5
upper_threshold: 210
invert: True

[BasicModule.countTissuePieces]

0 comments on commit 26a98cb

Please sign in to comment.