<!DOCTYPE html>
<!--[if IE 8]><html class="no-js lt-ie9" lang="en" > <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js" lang="en" > <!--<![endif]-->
<head>
<meta charset="utf-8">
<meta name="generator" content="Docutils 0.18.1: http://docutils.sourceforge.net/" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>slideflow.norm — slideflow 3.0.0 documentation</title>
<link rel="stylesheet" href="../_static/css/theme.css" type="text/css" />
<!-- <link rel="stylesheet" href="../_static/pygments.css" type="text/css" /> -->
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<link rel="stylesheet" href="../_static/css/theme.css" type="text/css" />
<link rel="index" title="Index" href="../genindex/" />
<link rel="search" title="Search" href="../search/" />
<link rel="next" title="slideflow.simclr" href="../simclr/" />
<link rel="prev" title="slideflow.model.torch" href="../model_torch/" />
<script src="../_static/js/modernizr.min.js"></script>
<!-- Preload the theme fonts -->
<link rel="preload" href="../_static/fonts/FreightSans/freight-sans-book.woff2" as="font" type="font/woff2" crossorigin="anonymous">
<link rel="preload" href="../_static/fonts/FreightSans/freight-sans-medium.woff2" as="font" type="font/woff2" crossorigin="anonymous">
<link rel="preload" href="../_static/fonts/IBMPlexMono/IBMPlexMono-Medium.woff2" as="font" type="font/woff2" crossorigin="anonymous">
<link rel="preload" href="../_static/fonts/FreightSans/freight-sans-bold.woff2" as="font" type="font/woff2" crossorigin="anonymous">
<link rel="preload" href="../_static/fonts/FreightSans/freight-sans-medium-italic.woff2" as="font" type="font/woff2" crossorigin="anonymous">
<link rel="preload" href="../_static/fonts/IBMPlexMono/IBMPlexMono-SemiBold.woff2" as="font" type="font/woff2" crossorigin="anonymous">
<!-- Preload the katex fonts -->
<link rel="preload" href="https://cdn.jsdelivr.net/npm/katex@0.10.0/dist/fonts/KaTeX_Math-Italic.woff2" as="font" type="font/woff2" crossorigin="anonymous">
<link rel="preload" href="https://cdn.jsdelivr.net/npm/katex@0.10.0/dist/fonts/KaTeX_Main-Regular.woff2" as="font" type="font/woff2" crossorigin="anonymous">
<link rel="preload" href="https://cdn.jsdelivr.net/npm/katex@0.10.0/dist/fonts/KaTeX_Main-Bold.woff2" as="font" type="font/woff2" crossorigin="anonymous">
<link rel="preload" href="https://cdn.jsdelivr.net/npm/katex@0.10.0/dist/fonts/KaTeX_Size1-Regular.woff2" as="font" type="font/woff2" crossorigin="anonymous">
<link rel="preload" href="https://cdn.jsdelivr.net/npm/katex@0.10.0/dist/fonts/KaTeX_Size4-Regular.woff2" as="font" type="font/woff2" crossorigin="anonymous">
<link rel="preload" href="https://cdn.jsdelivr.net/npm/katex@0.10.0/dist/fonts/KaTeX_Size2-Regular.woff2" as="font" type="font/woff2" crossorigin="anonymous">
<link rel="preload" href="https://cdn.jsdelivr.net/npm/katex@0.10.0/dist/fonts/KaTeX_Size3-Regular.woff2" as="font" type="font/woff2" crossorigin="anonymous">
<link rel="preload" href="https://cdn.jsdelivr.net/npm/katex@0.10.0/dist/fonts/KaTeX_Caligraphic-Regular.woff2" as="font" type="font/woff2" crossorigin="anonymous">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.15.2/css/all.css" integrity="sha384-vSIIfh2YWi9wW0r9iZe7RJPrKwp6bG+s9QZMoITbCckVJqGCCRhc+ccxNcdpHuYu" crossorigin="anonymous">
<script defer data-domain="slideflow.dev" src="https://plausible.io/js/script.js"></script>
</head>
<div class="container-fluid header-holder tutorials-header" id="header-holder">
<div class="container">
<div class="header-container">
<a class="header-logo" href="https://slideflow.dev" aria-label="Slideflow"></a>
<div class="main-menu">
<ul>
<li class="active">
<a href="https://slideflow.dev">Docs</a>
</li>
<li>
<a href="https://slideflow.dev/tutorial1/">Tutorials</a>
</li>
<li>
<a href="https://github.com/slideflow/slideflow">GitHub</a>
</li>
</ul>
</div>
<a class="main-menu-open-button" href="#" data-behavior="open-mobile-menu"></a>
</div>
</div>
</div>
<body class="pytorch-body">
<div class="table-of-contents-link-wrapper">
<span>Table of Contents</span>
<a href="#" class="toggle-table-of-contents" data-behavior="toggle-table-of-contents"></a>
</div>
<nav data-toggle="wy-nav-shift" class="pytorch-left-menu" id="pytorch-left-menu">
<div class="pytorch-side-scroll">
<div class="pytorch-menu pytorch-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
<div class="pytorch-left-menu-search">
<div class="version">
3.0
</div>
<div role="search">
<form id="rtd-search-form" class="wy-form" action="../search/" method="get">
<input type="text" name="q" placeholder="Search Docs" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<p class="caption" role="heading"><span class="caption-text">Introduction</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../installation/">Installation</a></li>
<li class="toctree-l1"><a class="reference internal" href="../overview/">Overview</a></li>
<li class="toctree-l1"><a class="reference internal" href="../quickstart/">Quickstart</a></li>
<li class="toctree-l1"><a class="reference internal" href="../project_setup/">Setting up a Project</a></li>
<li class="toctree-l1"><a class="reference internal" href="../datasets_and_val/">Datasets</a></li>
<li class="toctree-l1"><a class="reference internal" href="../slide_processing/">Slide Processing</a></li>
<li class="toctree-l1"><a class="reference internal" href="../training/">Training</a></li>
<li class="toctree-l1"><a class="reference internal" href="../evaluation/">Evaluation</a></li>
<li class="toctree-l1"><a class="reference internal" href="../posthoc/">Layer Activations</a></li>
<li class="toctree-l1"><a class="reference internal" href="../uq/">Uncertainty Quantification</a></li>
<li class="toctree-l1"><a class="reference internal" href="../features/">Generating Features</a></li>
<li class="toctree-l1"><a class="reference internal" href="../mil/">Multiple-Instance Learning (MIL)</a></li>
<li class="toctree-l1"><a class="reference internal" href="../ssl/">Self-Supervised Learning (SSL)</a></li>
<li class="toctree-l1"><a class="reference internal" href="../stylegan/">Generative Networks (GANs)</a></li>
<li class="toctree-l1"><a class="reference internal" href="../saliency/">Saliency Maps</a></li>
<li class="toctree-l1"><a class="reference internal" href="../segmentation/">Tissue Segmentation</a></li>
<li class="toctree-l1"><a class="reference internal" href="../cellseg/">Cell Segmentation</a></li>
<li class="toctree-l1"><a class="reference internal" href="../custom_loops/">Custom Training Loops</a></li>
<li class="toctree-l1"><a class="reference internal" href="../studio/">Slideflow Studio: Live Visualization</a></li>
<li class="toctree-l1"><a class="reference internal" href="../troubleshooting/">Troubleshooting</a></li>
</ul>
<p class="caption" role="heading"><span class="caption-text">Developer Notes</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../tfrecords/">TFRecords: Reading and Writing</a></li>
<li class="toctree-l1"><a class="reference internal" href="../dataloaders/">Dataloaders: Sampling and Augmentation</a></li>
<li class="toctree-l1"><a class="reference internal" href="../custom_extractors/">Custom Feature Extractors</a></li>
<li class="toctree-l1"><a class="reference internal" href="../tile_labels/">Strong Supervision with Tile Labels</a></li>
<li class="toctree-l1"><a class="reference internal" href="../plugins/">Creating a Slideflow Plugin</a></li>
</ul>
<p class="caption" role="heading"><span class="caption-text">API</span></p>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="../slideflow/">slideflow</a></li>
<li class="toctree-l1"><a class="reference internal" href="../project/">slideflow.Project</a></li>
<li class="toctree-l1"><a class="reference internal" href="../dataset/">slideflow.Dataset</a></li>
<li class="toctree-l1"><a class="reference internal" href="../dataset_features/">slideflow.DatasetFeatures</a></li>
<li class="toctree-l1"><a class="reference internal" href="../heatmap/">slideflow.Heatmap</a></li>
<li class="toctree-l1"><a class="reference internal" href="../model_params/">slideflow.ModelParams</a></li>
<li class="toctree-l1"><a class="reference internal" href="../mosaic/">slideflow.Mosaic</a></li>
<li class="toctree-l1"><a class="reference internal" href="../slidemap/">slideflow.SlideMap</a></li>
<li class="toctree-l1"><a class="reference internal" href="../biscuit/">slideflow.biscuit</a></li>
<li class="toctree-l1"><a class="reference internal" href="../slideflow_cellseg/">slideflow.cellseg</a></li>
<li class="toctree-l1"><a class="reference internal" href="../io/">slideflow.io</a></li>
<li class="toctree-l1"><a class="reference internal" href="../io_tensorflow/">slideflow.io.tensorflow</a></li>
<li class="toctree-l1"><a class="reference internal" href="../io_torch/">slideflow.io.torch</a></li>
<li class="toctree-l1"><a class="reference internal" href="../gan/">slideflow.gan</a></li>
<li class="toctree-l1"><a class="reference internal" href="../grad/">slideflow.grad</a></li>
<li class="toctree-l1"><a class="reference internal" href="../mil_module/">slideflow.mil</a></li>
<li class="toctree-l1"><a class="reference internal" href="../model/">slideflow.model</a></li>
<li class="toctree-l1"><a class="reference internal" href="../model_tensorflow/">slideflow.model.tensorflow</a></li>
<li class="toctree-l1"><a class="reference internal" href="../model_torch/">slideflow.model.torch</a></li>
<li class="toctree-l1 current"><a class="current reference internal" href="#">slideflow.norm</a></li>
<li class="toctree-l1"><a class="reference internal" href="../simclr/">slideflow.simclr</a></li>
<li class="toctree-l1"><a class="reference internal" href="../slide/">slideflow.slide</a></li>
<li class="toctree-l1"><a class="reference internal" href="../slide_qc/">slideflow.slide.qc</a></li>
<li class="toctree-l1"><a class="reference internal" href="../stats/">slideflow.stats</a></li>
<li class="toctree-l1"><a class="reference internal" href="../util/">slideflow.util</a></li>
<li class="toctree-l1"><a class="reference internal" href="../studio_module/">slideflow.studio</a></li>
</ul>
<p class="caption" role="heading"><span class="caption-text">Tutorials</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../tutorial1/">Tutorial 1: Model training (simple)</a></li>
<li class="toctree-l1"><a class="reference internal" href="../tutorial2/">Tutorial 2: Model training (advanced)</a></li>
<li class="toctree-l1"><a class="reference internal" href="../tutorial3/">Tutorial 3: Using a custom architecture</a></li>
<li class="toctree-l1"><a class="reference internal" href="../tutorial4/">Tutorial 4: Model evaluation & heatmaps</a></li>
<li class="toctree-l1"><a class="reference internal" href="../tutorial5/">Tutorial 5: Creating a mosaic map</a></li>
<li class="toctree-l1"><a class="reference internal" href="../tutorial6/">Tutorial 6: Custom slide filtering</a></li>
<li class="toctree-l1"><a class="reference internal" href="../tutorial7/">Tutorial 7: Training with custom augmentations</a></li>
<li class="toctree-l1"><a class="reference internal" href="../tutorial8/">Tutorial 8: Multiple-Instance Learning</a></li>
</ul>
</div>
</div>
</nav>
<div class="pytorch-container">
<div class="pytorch-page-level-bar" id="pytorch-page-level-bar">
<div class="pytorch-breadcrumbs-wrapper">
<div role="navigation" aria-label="breadcrumbs navigation">
<ul class="pytorch-breadcrumbs">
<li>
<a href="../">
Docs
</a> >
</li>
<li>slideflow.norm</li>
<li class="pytorch-breadcrumbs-aside">
<a href="../_sources/norm.rst.txt" rel="nofollow"><img src="../_static/images/view-page-source-icon.svg"></a>
</li>
</ul>
</div>
</div>
<div class="pytorch-shortcuts-wrapper" id="pytorch-shortcuts-wrapper">
Shortcuts
</div>
</div>
<section data-toggle="wy-nav-shift" id="pytorch-content-wrap" class="pytorch-content-wrap">
<div class="pytorch-content-left">
<div class="rst-content">
<div role="main" class="main-content" itemscope="itemscope" itemtype="http://schema.org/Article">
<article itemprop="articleBody" id="pytorch-article" class="pytorch-article">
<section id="slideflow-norm">
<h1>slideflow.norm<a class="headerlink" href="#slideflow-norm" title="Permalink to this heading">¶</a></h1>
<p>The <code class="docutils literal notranslate"><span class="pre">slideflow.norm</span></code> submodule includes tools for H&E stain normalization and augmentation.</p>
<p>Available stain normalization algorithms include:</p>
<ul class="simple">
<li><p><strong>macenko</strong>: <a class="reference external" href="https://www.cs.unc.edu/~mn/sites/default/files/macenko2009.pdf">Original Macenko paper</a>.</p></li>
<li><p><strong>macenko_fast</strong>: Modified Macenko algorithm with the brightness standardization step removed.</p></li>
<li><p><strong>reinhard</strong>: <a class="reference external" href="https://ieeexplore.ieee.org/document/946629">Original Reinhard paper</a>.</p></li>
<li><p><strong>reinhard_fast</strong>: Modified Reinhard algorithm with the brightness standardization step removed.</p></li>
<li><p><strong>reinhard_mask</strong>: Modified Reinhard algorithm, with background/whitespace removed.</p></li>
<li><p><strong>reinhard_fast_mask</strong>: Modified Reinhard-Fast algorithm, with background/whitespace removed.</p></li>
<li><p><strong>vahadane</strong>: <a class="reference external" href="https://ieeexplore.ieee.org/document/7460968">Original Vahadane paper</a>.</p></li>
<li><p><strong>augment</strong>: HSV colorspace augmentation.</p></li>
<li><p><strong>cyclegan</strong>: CycleGAN-based stain normalization, as implemented by <a class="reference external" href="https://github.com/Boehringer-Ingelheim/stain-transfer">Zingman et al</a> (PyTorch only)</p></li>
</ul>
<section id="overview">
<h2>Overview<a class="headerlink" href="#overview" title="Permalink to this heading">¶</a></h2>
<p>The main normalizer interface, <a class="reference internal" href="#slideflow.norm.StainNormalizer" title="slideflow.norm.StainNormalizer"><code class="xref py py-class docutils literal notranslate"><span class="pre">slideflow.norm.StainNormalizer</span></code></a>, offers
efficient numpy implementations for the Macenko, Reinhard, and Vahadane H&E stain normalization algorithms, as well
as an HSV colorspace stain augmentation method. This normalizer can convert
images to and from Tensors, numpy arrays, and raw JPEG/PNG images.</p>
<p>In addition to these numpy implementations, PyTorch-native and Tensorflow-native
implementations are also provided, which offer performance improvements, GPU acceleration,
and/or vectorized application. The native normalizers are found in
<code class="docutils literal notranslate"><span class="pre">slideflow.norm.tensorflow</span></code> and <code class="docutils literal notranslate"><span class="pre">slideflow.norm.torch</span></code>, respectively.</p>
<p>The Vahadane normalizer has two numpy implementations available: SPAMS
(<code class="docutils literal notranslate"><span class="pre">vahadane_spams</span></code>) and sklearn (<code class="docutils literal notranslate"><span class="pre">vahadane_sklearn</span></code>). By default,
the SPAMS implementation will be used if unspecified (<code class="docutils literal notranslate"><span class="pre">method='vahadane'</span></code>).</p>
<p>Use <code class="xref py py-func docutils literal notranslate"><span class="pre">slideflow.norm.autoselect()</span></code> to get the fastest available normalizer
for a given method and active backend (Tensorflow/PyTorch).</p>
</section>
<section id="how-to-use">
<h2>How to use<a class="headerlink" href="#how-to-use" title="Permalink to this heading">¶</a></h2>
<p>There are four ways you can use stain normalizers: 1) on individual images, 2) during dataset iteration, 3) during tile extraction, or 4) on-the-fly during training.</p>
<section id="individual-images">
<h3>Individual images<a class="headerlink" href="#individual-images" title="Permalink to this heading">¶</a></h3>
<p>Stain normalizers can be used directly on individual images or batches of images. The Tensorflow and PyTorch-native stain normalizers perform operations on Tensors, allowing you to incoporate stain normalization into an external preprocessing pipeline.</p>
<p>Load a backend-native stain normalizer with <code class="docutils literal notranslate"><span class="pre">autoselect</span></code>, then transform an image with <code class="docutils literal notranslate"><span class="pre">StainNormalizer.transform()</span></code>. This function will auto-detect the source image type, perform the most efficient transformation possible, and return normalized images of the same type.</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">slideflow</span> <span class="k">as</span> <span class="nn">sf</span>
<span class="n">macenko</span> <span class="o">=</span> <span class="n">sf</span><span class="o">.</span><span class="n">norm</span><span class="o">.</span><span class="n">autoselect</span><span class="p">(</span><span class="s1">'macenko'</span><span class="p">)</span>
<span class="n">image</span> <span class="o">=</span> <span class="n">macenko</span><span class="o">.</span><span class="n">transform</span><span class="p">(</span><span class="n">image</span><span class="p">)</span>
</pre></div>
</div>
<p>You can use <a class="reference internal" href="#slideflow.norm.StainNormalizer.fit" title="slideflow.norm.StainNormalizer.fit"><code class="xref py py-meth docutils literal notranslate"><span class="pre">slideflow.norm.StainNormalizer.fit()</span></code></a> to fit the normalizer to a custom reference image, or use one of our preset fits.</p>
</section>
<section id="dataloader-pre-processing">
<h3>Dataloader pre-processing<a class="headerlink" href="#dataloader-pre-processing" title="Permalink to this heading">¶</a></h3>
<p>You can apply stain normalization during dataloader preprocessing by passing the <code class="docutils literal notranslate"><span class="pre">StainNormalizer</span></code> object to the <code class="docutils literal notranslate"><span class="pre">normalizer</span></code> argument of either <code class="docutils literal notranslate"><span class="pre">Dataset.tensorflow()</span></code> or <code class="docutils literal notranslate"><span class="pre">Dataset.torch()</span></code>.</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">slideflow</span> <span class="k">as</span> <span class="nn">sf</span>
<span class="c1"># Get a PyTorch-native Macenko normalizer</span>
<span class="n">macenko</span> <span class="o">=</span> <span class="n">sf</span><span class="o">.</span><span class="n">norm</span><span class="o">.</span><span class="n">autoselect</span><span class="p">(</span><span class="s1">'macenko'</span><span class="p">)</span>
<span class="c1"># Create a PyTorch dataloader that applies stain normalization</span>
<span class="n">dataset</span> <span class="o">=</span> <span class="n">sf</span><span class="o">.</span><span class="n">Dataset</span><span class="p">(</span><span class="o">...</span><span class="p">)</span>
<span class="n">dataloader</span> <span class="o">=</span> <span class="n">dataset</span><span class="o">.</span><span class="n">torch</span><span class="p">(</span><span class="o">...</span><span class="p">,</span> <span class="n">normalizer</span><span class="o">=</span><span class="n">macenko</span><span class="p">)</span>
</pre></div>
</div>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>GPU acceleration cannot be performed within a PyTorch dataloader. Stain normalizers have a <code class="docutils literal notranslate"><span class="pre">.preprocess()</span></code> function that stain-normalizes and standardizes a batch of images, so the workflow to normalize on GPU in a custom PyTorch training loop would be:</p>
<ul class="simple">
<li><p>Get a Dataloader with <code class="docutils literal notranslate"><span class="pre">dataset.torch(standardize=False,</span> <span class="pre">normalize=False)</span></code></p></li>
<li><p>On an image batch, preprocess with <code class="docutils literal notranslate"><span class="pre">normalizer.preprocess()</span></code>:</p></li>
</ul>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># Slideflow dataset</span>
<span class="n">dataset</span> <span class="o">=</span> <span class="n">Project</span><span class="o">.</span><span class="n">dataset</span><span class="p">(</span><span class="n">tile_px</span><span class="o">=...</span><span class="p">,</span> <span class="n">tile_um</span><span class="o">=...</span><span class="p">)</span>
<span class="c1"># Create PyTorch dataloader</span>
<span class="n">dataloader</span> <span class="o">=</span> <span class="n">dataset</span><span class="o">.</span><span class="n">torch</span><span class="p">(</span><span class="o">...</span><span class="p">,</span> <span class="n">standardize</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
<span class="c1"># Get a stain normalizer</span>
<span class="n">normalizer</span> <span class="o">=</span> <span class="n">sf</span><span class="o">.</span><span class="n">norm</span><span class="o">.</span><span class="n">autoselect</span><span class="p">(</span><span class="s1">'reinhard'</span><span class="p">)</span>
<span class="c1"># Iterate through the dataloader</span>
<span class="k">for</span> <span class="n">img_batch</span><span class="p">,</span> <span class="n">labels</span> <span class="ow">in</span> <span class="n">dataloader</span><span class="p">:</span>
<span class="c1"># Stain normalize using GPU</span>
<span class="n">img_batch</span> <span class="o">=</span> <span class="n">img_batch</span><span class="o">.</span><span class="n">to</span><span class="p">(</span><span class="s1">'cuda'</span><span class="p">)</span>
<span class="k">with</span> <span class="n">torch</span><span class="o">.</span><span class="n">no_grad</span><span class="p">():</span>
<span class="n">proc_batch</span> <span class="o">=</span> <span class="n">normalizer</span><span class="o">.</span><span class="n">preprocess</span><span class="p">(</span><span class="n">img_batch</span><span class="p">)</span>
<span class="o">...</span>
</pre></div>
</div>
</div>
</section>
<section id="during-tile-extraction">
<h3>During tile extraction<a class="headerlink" href="#during-tile-extraction" title="Permalink to this heading">¶</a></h3>
<p>Image tiles can be normalized during tile extraction by using the <code class="docutils literal notranslate"><span class="pre">normalizer</span></code> and <code class="docutils literal notranslate"><span class="pre">normalizer_source</span></code> arguments. <code class="docutils literal notranslate"><span class="pre">normalizer</span></code> is the name of the algorithm. The normalizer source - either a path to a reference image, or a <code class="docutils literal notranslate"><span class="pre">str</span></code> indicating one of our presets (e.g. <code class="docutils literal notranslate"><span class="pre">'v1'</span></code>, <code class="docutils literal notranslate"><span class="pre">'v2'</span></code>, <code class="docutils literal notranslate"><span class="pre">'v3'</span></code>) - can also be set with <code class="docutils literal notranslate"><span class="pre">normalizer_source</span></code>.</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">P</span><span class="o">.</span><span class="n">extract_tiles</span><span class="p">(</span>
<span class="n">tile_px</span><span class="o">=</span><span class="mi">299</span><span class="p">,</span>
<span class="n">tile_um</span><span class="o">=</span><span class="mi">302</span><span class="p">,</span>
<span class="n">normalizer</span><span class="o">=</span><span class="s1">'reinhard'</span>
<span class="p">)</span>
</pre></div>
</div>
</section>
<section id="on-the-fly">
<h3>On-the-fly<a class="headerlink" href="#on-the-fly" title="Permalink to this heading">¶</a></h3>
<p>Performing stain normalization on-the-fly provides greater flexibility, as it allows you to change normalization strategies without re-extracting all of your image tiles.</p>
<p>Real-time normalization can be performed for most pipeline functions - such as model training or feature generation - by setting the <code class="docutils literal notranslate"><span class="pre">normalizer</span></code> and/or <code class="docutils literal notranslate"><span class="pre">normalizer_source</span></code> hyperparameters.</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">slideflow.model</span> <span class="kn">import</span> <span class="n">ModelParams</span>
<span class="n">hp</span> <span class="o">=</span> <span class="n">ModelParams</span><span class="p">(</span><span class="o">...</span><span class="p">,</span> <span class="n">normalizer</span><span class="o">=</span><span class="s1">'reinhard'</span><span class="p">)</span>
</pre></div>
</div>
<p>If a model was trained using a normalizer, the normalizer algorithm and fit information will be stored in the model metadata file, <code class="docutils literal notranslate"><span class="pre">params.json</span></code>, in the saved model folder. Any Slideflow function that uses this model will automatically process images using the same normalization strategy.</p>
</section>
</section>
<section id="performance">
<span id="normalizer-performance"></span><h2>Performance<a class="headerlink" href="#performance" title="Permalink to this heading">¶</a></h2>
<p>Slideflow has Tensorflow, PyTorch, and Numpy/OpenCV implementations of stain normalization algorithms. Performance benchmarks for these implementations
are given below:</p>
<table class="docutils align-default" id="id3">
<caption><span class="caption-text"><strong>Performance Benchmarks</strong> (299 x 299 images, Slideflow 2.0.0, benchmarked on 3960X and A100 40GB)</span><a class="headerlink" href="#id3" title="Permalink to this table">¶</a></caption>
<thead>
<tr class="row-odd"><th class="head"></th>
<th class="head"><p>Tensorflow backend</p></th>
<th class="head"><p>PyTorch backend</p></th>
</tr>
</thead>
<tbody>
<tr class="row-even"><td><p>macenko</p></td>
<td><p>929 img/s (<strong>native</strong>)</p></td>
<td><p>881 img/s (<strong>native</strong>)</p></td>
</tr>
<tr class="row-odd"><td><p>macenko_fast</p></td>
<td><p>1,404 img/s (<strong>native</strong>)</p></td>
<td><p>1,088 img/s (<strong>native</strong>)</p></td>
</tr>
<tr class="row-even"><td><p>reinhard</p></td>
<td><p>1,136 img/s (<strong>native</strong>)</p></td>
<td><p>3,329 img/s (<strong>native</strong>)</p></td>
</tr>
<tr class="row-odd"><td><p>reinhard_fast</p></td>
<td><p>4,226 img/s (<strong>native</strong>)</p></td>
<td><p>4,187 img/s (<strong>native</strong>)</p></td>
</tr>
<tr class="row-even"><td><p>reinhard_mask</p></td>
<td><p>1,136 img/s (<strong>native</strong>)</p></td>
<td><p>3,941 img/s (<strong>native</strong>)</p></td>
</tr>
<tr class="row-odd"><td><p>reinhard_fast_mask</p></td>
<td><p>4,496 img/s (<strong>native</strong>)</p></td>
<td><p>4,058 img/s (<strong>native</strong>)</p></td>
</tr>
<tr class="row-even"><td><p>vahadane_spams</p></td>
<td><p>0.7 img/s</p></td>
<td><p>2.2 img/s</p></td>
</tr>
<tr class="row-odd"><td><p>vahadane_sklearn</p></td>
<td><p>0.9 img/s</p></td>
<td><p>1.0 img/s</p></td>
</tr>
</tbody>
</table>
</section>
<section id="contextual-normalization">
<span id="id1"></span><h2>Contextual Normalization<a class="headerlink" href="#contextual-normalization" title="Permalink to this heading">¶</a></h2>
<p>Contextual stain normalization allows you to stain normalize an image using the staining context of a separate image. When the context image is a thumbnail of the whole slide, this may provide slight improvements in normalization quality for areas of a slide that are predominantly eosin (e.g. necrosis or low cellularity). For the Macenko normalizer, this works by determining the maximum H&E concentrations from the context image rather than the image being transformed. For the Reinhard normalizer, channel means and standard deviations are calculated from the context image instead of the image being transformed. This normalization approach can result in poor quality images if the context image has pen marks or other artifacts, so we do not recommend using this approach without ROIs or effective slide-level filtering.</p>
<p>Contextual normalization can be enabled during tile extraction by passing the argument <code class="docutils literal notranslate"><span class="pre">context_normalize=True</span></code> to <a class="reference internal" href="../dataset/#slideflow.Dataset.extract_tiles" title="slideflow.Dataset.extract_tiles"><code class="xref py py-meth docutils literal notranslate"><span class="pre">slideflow.Dataset.extract_tiles()</span></code></a>.</p>
<p>You can use contextual normalization when manually using a <code class="docutils literal notranslate"><span class="pre">StainNormalizer</span></code> object by using the <code class="docutils literal notranslate"><span class="pre">.context()</span></code> function. The context can either be a slide (path or <code class="docutils literal notranslate"><span class="pre">sf.WSI</span></code>) or an image (Tensor or np.ndarray).</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">slideflow</span> <span class="k">as</span> <span class="nn">sf</span>
<span class="c1"># Get a Macenko normalizer</span>
<span class="n">macenko</span> <span class="o">=</span> <span class="n">sf</span><span class="o">.</span><span class="n">norm</span><span class="o">.</span><span class="n">autoselect</span><span class="p">(</span><span class="s1">'macenko'</span><span class="p">)</span>
<span class="c1"># Use a given slide as context</span>
<span class="n">slide</span> <span class="o">=</span> <span class="n">sf</span><span class="o">.</span><span class="n">WSI</span><span class="p">(</span><span class="s1">'slide.svs'</span><span class="p">,</span> <span class="o">...</span><span class="p">)</span>
<span class="c1"># Context normalize an image</span>
<span class="k">with</span> <span class="n">macenko</span><span class="o">.</span><span class="n">context</span><span class="p">(</span><span class="n">slide</span><span class="p">):</span>
<span class="n">img</span> <span class="o">=</span> <span class="n">macenko</span><span class="o">.</span><span class="n">transform</span><span class="p">(</span><span class="n">img</span><span class="p">)</span>
</pre></div>
</div>
<p>You can also manually set or clear the normalizer context with <code class="docutils literal notranslate"><span class="pre">.set_context()</span></code> and <code class="docutils literal notranslate"><span class="pre">.clear_context()</span></code>:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># Set the normalizer context</span>
<span class="n">macenko</span><span class="o">.</span><span class="n">set_context</span><span class="p">(</span><span class="n">slide</span><span class="p">)</span>
<span class="c1"># Context normalize an image</span>
<span class="n">img</span> <span class="o">=</span> <span class="n">macenko</span><span class="o">.</span><span class="n">transform</span><span class="p">(</span><span class="n">img</span><span class="p">)</span>
<span class="c1"># Remove the normalizer context</span>
<span class="n">macenko</span><span class="o">.</span><span class="n">clear_context</span><span class="p">()</span>
</pre></div>
</div>
<p>Contextual normalization is not supported with on-the-fly normalization during training or dataset iteration.</p>
</section>
<section id="stain-augmentation">
<span id="id2"></span><h2>Stain Augmentation<a class="headerlink" href="#stain-augmentation" title="Permalink to this heading">¶</a></h2>
<p>One of the benefits of on-the-fly stain normalization is the ability to perform dynamic stain augmentation with normalization. For Reinhard normalizers, this is performed by randomizing the channel means and channel standard deviations. For Macenko normalizers, stain augmentation is performed by randomizing the stain matrix target and the target concentrations. In all cases, randomization is performed by sampling from a normal distribution whose mean is the reference fit and whose standard deviation is a predefined value (in <code class="docutils literal notranslate"><span class="pre">sf.norm.utils.augment_presets</span></code>). Of note, this strategy differs from the more commonly used strategy <a class="reference external" href="https://doi.org/10.1109/tmi.2018.2820199">described by Tellez</a>, where augmentation is performed by randomly perturbing images in the stain matrix space without normalization.</p>
<p>To enable stain augmentation, add the letter ‘n’ to the <code class="docutils literal notranslate"><span class="pre">augment</span></code> parameter when training a model.</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">slideflow</span> <span class="k">as</span> <span class="nn">sf</span>
<span class="c1"># Open a project</span>
<span class="n">project</span> <span class="o">=</span> <span class="n">sf</span><span class="o">.</span><span class="n">Project</span><span class="p">(</span><span class="o">...</span><span class="p">)</span>
<span class="c1"># Add stain augmentation to augmentation pipeline</span>
<span class="n">params</span> <span class="o">=</span> <span class="n">sf</span><span class="o">.</span><span class="n">ModelParams</span><span class="p">(</span><span class="o">...</span><span class="p">,</span> <span class="n">augment</span><span class="o">=</span><span class="s1">'xryjn'</span><span class="p">)</span>
<span class="c1"># Train a model</span>
<span class="n">project</span><span class="o">.</span><span class="n">train</span><span class="p">(</span><span class="o">...</span><span class="p">,</span> <span class="n">params</span><span class="o">=</span><span class="n">params</span><span class="p">)</span>
</pre></div>
</div>
<p>When using a StainNormalizer object, you can perform a combination of normalization and augmention for an image by using the argument <code class="docutils literal notranslate"><span class="pre">augment=True</span></code> when calling <a class="reference internal" href="#slideflow.norm.StainNormalizer.transform" title="slideflow.norm.StainNormalizer.transform"><code class="xref py py-meth docutils literal notranslate"><span class="pre">StainNormalizer.transform()</span></code></a>:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">slideflow</span> <span class="k">as</span> <span class="nn">sf</span>
<span class="c1"># Get a Macenko normalizer</span>
<span class="n">macenko</span> <span class="o">=</span> <span class="n">sf</span><span class="o">.</span><span class="n">norm</span><span class="o">.</span><span class="n">autoselect</span><span class="p">(</span><span class="s1">'macenko'</span><span class="p">)</span>
<span class="c1"># Perform combination of stain normalization and augmentation</span>
<span class="n">img</span> <span class="o">=</span> <span class="n">macenko</span><span class="o">.</span><span class="n">transform</span><span class="p">(</span><span class="n">img</span><span class="p">,</span> <span class="n">augment</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
</pre></div>
</div>
<p>To stain augment an image without normalization, use the method <a class="reference internal" href="#slideflow.norm.StainNormalizer.augment" title="slideflow.norm.StainNormalizer.augment"><code class="xref py py-meth docutils literal notranslate"><span class="pre">StainNormalizer.augment()</span></code></a>:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">slideflow</span> <span class="k">as</span> <span class="nn">sf</span>
<span class="c1"># Get a Macenko normalizer</span>
<span class="n">macenko</span> <span class="o">=</span> <span class="n">sf</span><span class="o">.</span><span class="n">norm</span><span class="o">.</span><span class="n">autoselect</span><span class="p">(</span><span class="s1">'macenko'</span><span class="p">)</span>
<span class="c1"># Perform stain augmentation</span>
<span class="n">img</span> <span class="o">=</span> <span class="n">macenko</span><span class="o">.</span><span class="n">augment</span><span class="p">(</span><span class="n">img</span><span class="p">)</span>
</pre></div>
</div>
</section>
<section id="stainnormalizer">
<h2>StainNormalizer<a class="headerlink" href="#stainnormalizer" title="Permalink to this heading">¶</a></h2>
<dl class="py class">
<dt class="sig sig-object py" id="slideflow.norm.StainNormalizer">
<em class="property"><span class="pre">class</span><span class="w"> </span></em><span class="sig-name descname"><span class="pre">StainNormalizer</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">method</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><a class="reference external" href="https://docs.python.org/3/library/stdtypes.html#str" title="(in Python v3.12)"><span class="pre">str</span></a></span></em>, <em class="sig-param"><span class="o"><span class="pre">**</span></span><span class="n"><span class="pre">kwargs</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/slideflow/norm/#StainNormalizer"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#slideflow.norm.StainNormalizer" title="Permalink to this definition">¶</a></dt>
<dd><p>H&E Stain normalizer supporting various normalization methods.</p>
<p>The stain normalizer supports numpy images, PNG or JPG strings,
Tensorflow tensors, and PyTorch tensors. The default <code class="docutils literal notranslate"><span class="pre">.transform()</span></code>
method will attempt to preserve the original image type while
minimizing conversions to and from Tensors.</p>
<p>Alternatively, you can manually specify the image conversion type
by using the appropriate function. For example, to convert a Tensor
to a normalized numpy RGB image, use <code class="docutils literal notranslate"><span class="pre">.tf_to_rgb()</span></code>.</p>
<dl class="field-list simple">
<dt class="field-odd">Parameters<span class="colon">:</span></dt>
<dd class="field-odd"><p><strong>method</strong> (<a class="reference external" href="https://docs.python.org/3/library/stdtypes.html#str" title="(in Python v3.12)"><em>str</em></a>) – Normalization method. Options include ‘macenko’,
‘reinhard’, ‘reinhard_fast’, ‘reinhard_mask’,
‘reinhard_fast_mask’, ‘vahadane’, ‘vahadane_spams’,
‘vahadane_sklearn’, and ‘augment’.</p>
</dd>
<dt class="field-even">Keyword Arguments<span class="colon">:</span></dt>
<dd class="field-even"><ul class="simple">
<li><p><strong>stain_matrix_target</strong> (<em>np.ndarray</em><em>, </em><em>optional</em>) – Set the stain matrix
target for the normalizer. May raise an error if the normalizer
does not have a stain_matrix_target fit attribute.</p></li>
<li><p><strong>target_concentrations</strong> (<em>np.ndarray</em><em>, </em><em>optional</em>) – Set the target
concentrations for the normalizer. May raise an error if the
normalizer does not have a target_concentrations fit attribute.</p></li>
<li><p><strong>target_means</strong> (<em>np.ndarray</em><em>, </em><em>optional</em>) – Set the target means for the
normalizer. May raise an error if the normalizer does not have
a target_means fit attribute.</p></li>
<li><p><strong>target_stds</strong> (<em>np.ndarray</em><em>, </em><em>optional</em>) – Set the target standard
deviations for the normalizer. May raise an error if the
normalizer does not have a target_stds fit attribute.</p></li>
</ul>
</dd>
<dt class="field-odd">Raises<span class="colon">:</span></dt>
<dd class="field-odd"><p><a class="reference external" href="https://docs.python.org/3/library/exceptions.html#ValueError" title="(in Python v3.12)"><strong>ValueError</strong></a> – If the specified normalizer method is not available.</p>
</dd>
</dl>
<dl>
<dt>Examples</dt><dd><p>Normalize a numpy image using the default fit.</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="kn">import</span> <span class="nn">slideflow</span> <span class="k">as</span> <span class="nn">sf</span>
<span class="gp">>>> </span><span class="n">macenko</span> <span class="o">=</span> <span class="n">sf</span><span class="o">.</span><span class="n">norm</span><span class="o">.</span><span class="n">StainNormalizer</span><span class="p">(</span><span class="s1">'macenko'</span><span class="p">)</span>
<span class="gp">>>> </span><span class="n">macenko</span><span class="o">.</span><span class="n">transform</span><span class="p">(</span><span class="n">image</span><span class="p">)</span>
</pre></div>
</div>
<p>Fit the normalizer to a target image (numpy or path).</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">macenko</span><span class="o">.</span><span class="n">fit</span><span class="p">(</span><span class="n">target_image</span><span class="p">)</span>
</pre></div>
</div>
<p>Fit the normalizer using a preset configuration.</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">macenko</span><span class="o">.</span><span class="n">fit</span><span class="p">(</span><span class="s1">'v2'</span><span class="p">)</span>
</pre></div>
</div>
<p>Fit the normalizer to all images in a Dataset.</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">dataset</span> <span class="o">=</span> <span class="n">sf</span><span class="o">.</span><span class="n">Dataset</span><span class="p">(</span><span class="o">...</span><span class="p">)</span>
<span class="gp">>>> </span><span class="n">macenko</span><span class="o">.</span><span class="n">fit</span><span class="p">(</span><span class="n">dataset</span><span class="p">)</span>
</pre></div>
</div>
<p>Normalize an image and convert from Tensor to numpy array (RGB).</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">macenko</span><span class="o">.</span><span class="n">tf_to_rgb</span><span class="p">(</span><span class="n">image</span><span class="p">)</span>
</pre></div>
</div>
<p>Normalize images during DataLoader pre-processing.</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">dataset</span> <span class="o">=</span> <span class="n">sf</span><span class="o">.</span><span class="n">Dataset</span><span class="p">(</span><span class="o">...</span><span class="p">)</span>
<span class="gp">>>> </span><span class="n">dataloader</span> <span class="o">=</span> <span class="n">dataset</span><span class="o">.</span><span class="n">torch</span><span class="p">(</span><span class="o">...</span><span class="p">,</span> <span class="n">normalizer</span><span class="o">=</span><span class="n">macenko</span><span class="p">)</span>
<span class="gp">>>> </span><span class="n">dts</span> <span class="o">=</span> <span class="n">dataset</span><span class="o">.</span><span class="n">tensorflow</span><span class="p">(</span><span class="o">...</span><span class="p">,</span> <span class="n">normalizer</span><span class="o">=</span><span class="n">macenko</span><span class="p">)</span>
</pre></div>
</div>
</dd>
</dl>
</dd></dl>
<dl class="py function">
<dt class="sig sig-object py" id="slideflow.norm.StainNormalizer.fit">
<span class="sig-name descname"><span class="pre">fit</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">self</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">arg1</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><a class="reference internal" href="../dataset/#slideflow.Dataset" title="slideflow.dataset.Dataset"><span class="pre">Dataset</span></a><span class="w"> </span><span class="p"><span class="pre">|</span></span><span class="w"> </span><span class="pre">ndarray</span><span class="w"> </span><span class="p"><span class="pre">|</span></span><span class="w"> </span><a class="reference external" href="https://docs.python.org/3/library/stdtypes.html#str" title="(in Python v3.12)"><span class="pre">str</span></a><span class="w"> </span><span class="p"><span class="pre">|</span></span><span class="w"> </span><a class="reference external" href="https://docs.python.org/3/library/constants.html#None" title="(in Python v3.12)"><span class="pre">None</span></a></span></em>, <em class="sig-param"><span class="n"><span class="pre">batch_size</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><a class="reference external" href="https://docs.python.org/3/library/functions.html#int" title="(in Python v3.12)"><span class="pre">int</span></a></span><span class="w"> </span><span class="o"><span class="pre">=</span></span><span class="w"> </span><span class="default_value"><span class="pre">64</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">num_threads</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><a class="reference external" href="https://docs.python.org/3/library/stdtypes.html#str" title="(in Python v3.12)"><span class="pre">str</span></a><span class="w"> </span><span class="p"><span class="pre">|</span></span><span class="w"> </span><a class="reference external" href="https://docs.python.org/3/library/functions.html#int" title="(in Python v3.12)"><span class="pre">int</span></a></span><span class="w"> </span><span class="o"><span class="pre">=</span></span><span class="w"> </span><span class="default_value"><span class="pre">'auto'</span></span></em>, <em class="sig-param"><span class="o"><span class="pre">**</span></span><span class="n"><span class="pre">kwargs</span></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><a class="reference internal" href="#slideflow.norm.StainNormalizer" title="slideflow.norm.StainNormalizer"><span class="pre">StainNormalizer</span></a></span></span><a class="headerlink" href="#slideflow.norm.StainNormalizer.fit" title="Permalink to this definition">¶</a></dt>
<dd><p>Fit the normalizer to a target image or dataset of images.</p>
<dl class="field-list simple">
<dt class="field-odd">Parameters<span class="colon">:</span></dt>
<dd class="field-odd"><ul class="simple">
<li><p><strong>arg1</strong> – (Dataset, np.ndarray, str): Target to fit. May be a str,
numpy image array (uint8), path to an image, or a Slideflow
Dataset. If this is a string, will fit to the corresponding
preset fit (either ‘v1’, ‘v2’, or ‘v3’).
If a Dataset is provided, will average fit values across
all images in the dataset.</p></li>
<li><p><strong>batch_size</strong> (<a class="reference external" href="https://docs.python.org/3/library/functions.html#int" title="(in Python v3.12)"><em>int</em></a><em>, </em><em>optional</em>) – Batch size during fitting, if fitting
to dataset. Defaults to 64.</p></li>
<li><p><strong>num_threads</strong> (<em>Union</em><em>[</em><a class="reference external" href="https://docs.python.org/3/library/stdtypes.html#str" title="(in Python v3.12)"><em>str</em></a><em>, </em><a class="reference external" href="https://docs.python.org/3/library/functions.html#int" title="(in Python v3.12)"><em>int</em></a><em>]</em><em>, </em><em>optional</em>) – Number of threads to use
during fitting, if fitting to a dataset. Defaults to ‘auto’.</p></li>
</ul>
</dd>
</dl>
</dd></dl>
<dl class="py function">
<dt class="sig sig-object py" id="slideflow.norm.StainNormalizer.get_fit">
<span class="sig-name descname"><span class="pre">get_fit</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">self</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">as_list</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><a class="reference external" href="https://docs.python.org/3/library/functions.html#bool" title="(in Python v3.12)"><span class="pre">bool</span></a></span><span class="w"> </span><span class="o"><span class="pre">=</span></span><span class="w"> </span><span class="default_value"><span class="pre">False</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#slideflow.norm.StainNormalizer.get_fit" title="Permalink to this definition">¶</a></dt>
<dd><p>Get the current normalizer fit.</p>
<dl class="field-list simple">
<dt class="field-odd">Parameters<span class="colon">:</span></dt>
<dd class="field-odd"><p><strong>as_list</strong> (<a class="reference external" href="https://docs.python.org/3/library/functions.html#bool" title="(in Python v3.12)"><em>bool</em></a><em>)</em><em>. Convert the fit values</em><em> (</em><em>numpy arrays</em>) – format. Defaults to False.</p>
</dd>
<dt class="field-even">Returns<span class="colon">:</span></dt>
<dd class="field-even"><p>Dictionary mapping fit parameters (e.g.
‘target_concentrations’) to their respective fit values.</p>
</dd>
<dt class="field-odd">Return type<span class="colon">:</span></dt>
<dd class="field-odd"><p>Dict[<a class="reference external" href="https://docs.python.org/3/library/stdtypes.html#str" title="(in Python v3.12)">str</a>, np.ndarray]</p>
</dd>
</dl>
</dd></dl>
<dl class="py function">
<dt class="sig sig-object py" id="slideflow.norm.StainNormalizer.set_fit">
<span class="sig-name descname"><span class="pre">set_fit</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">self</span></span></em>, <em class="sig-param"><span class="o"><span class="pre">**</span></span><span class="n"><span class="pre">kwargs</span></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><a class="reference external" href="https://docs.python.org/3/library/constants.html#None" title="(in Python v3.12)"><span class="pre">None</span></a></span></span><a class="headerlink" href="#slideflow.norm.StainNormalizer.set_fit" title="Permalink to this definition">¶</a></dt>
<dd><p>Set the normalizer fit to the given values.</p>
<dl class="field-list simple">
<dt class="field-odd">Keyword Arguments<span class="colon">:</span></dt>
<dd class="field-odd"><ul class="simple">
<li><p><strong>stain_matrix_target</strong> (<em>np.ndarray</em><em>, </em><em>optional</em>) – Set the stain matrix
target for the normalizer. May raise an error if the normalizer
does not have a stain_matrix_target fit attribute.</p></li>
<li><p><strong>target_concentrations</strong> (<em>np.ndarray</em><em>, </em><em>optional</em>) – Set the target
concentrations for the normalizer. May raise an error if the
normalizer does not have a target_concentrations fit attribute.</p></li>
<li><p><strong>target_means</strong> (<em>np.ndarray</em><em>, </em><em>optional</em>) – Set the target means for the
normalizer. May raise an error if the normalizer does not have
a target_means fit attribute.</p></li>
<li><p><strong>target_stds</strong> (<em>np.ndarray</em><em>, </em><em>optional</em>) – Set the target standard
deviations for the normalizer. May raise an error if the
normalizer does not have a target_stds fit attribute.</p></li>
</ul>
</dd>
</dl>
</dd></dl>
<dl class="py function">
<dt class="sig sig-object py" id="slideflow.norm.StainNormalizer.augment">
<span class="sig-name descname"><span class="pre">augment</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">self</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">image</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">ndarray</span><span class="w"> </span><span class="p"><span class="pre">|</span></span><span class="w"> </span><span class="pre">tf.Tensor</span><span class="w"> </span><span class="p"><span class="pre">|</span></span><span class="w"> </span><span class="pre">torch.Tensor</span></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><span class="pre">ndarray</span><span class="w"> </span><span class="p"><span class="pre">|</span></span><span class="w"> </span><span class="pre">tf.Tensor</span><span class="w"> </span><span class="p"><span class="pre">|</span></span><span class="w"> </span><span class="pre">torch.Tensor</span></span></span><a class="headerlink" href="#slideflow.norm.StainNormalizer.augment" title="Permalink to this definition">¶</a></dt>
<dd><p>Augment a target image, attempting to preserve the original type.</p>
<dl class="field-list simple">
<dt class="field-odd">Parameters<span class="colon">:</span></dt>
<dd class="field-odd"><p><strong>image</strong> (<em>np.ndarray</em><em>, </em><em>tf.Tensor</em><em>, or </em><em>torch.Tensor</em>) – Image as a uint8
array. Numpy and Tensorflow images are normalized in W x H x C
space. PyTorch images provided as C x W x H will be
auto-converted and permuted back after normalization.</p>
</dd>
<dt class="field-even">Returns<span class="colon">:</span></dt>
<dd class="field-even"><p>Augmented image of the original type (uint8).</p>
</dd>
</dl>
</dd></dl>
<dl class="py function">
<dt class="sig sig-object py" id="slideflow.norm.StainNormalizer.transform">
<span class="sig-name descname"><span class="pre">transform</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">self</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">image</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">ndarray</span><span class="w"> </span><span class="p"><span class="pre">|</span></span><span class="w"> </span><span class="pre">tf.Tensor</span><span class="w"> </span><span class="p"><span class="pre">|</span></span><span class="w"> </span><span class="pre">torch.Tensor</span></span></em>, <em class="sig-param"><span class="o"><span class="pre">*</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">augment</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><a class="reference external" href="https://docs.python.org/3/library/functions.html#bool" title="(in Python v3.12)"><span class="pre">bool</span></a></span><span class="w"> </span><span class="o"><span class="pre">=</span></span><span class="w"> </span><span class="default_value"><span class="pre">False</span></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><span class="pre">ndarray</span><span class="w"> </span><span class="p"><span class="pre">|</span></span><span class="w"> </span><span class="pre">tf.Tensor</span><span class="w"> </span><span class="p"><span class="pre">|</span></span><span class="w"> </span><span class="pre">torch.Tensor</span></span></span><a class="headerlink" href="#slideflow.norm.StainNormalizer.transform" title="Permalink to this definition">¶</a></dt>
<dd><p>Normalize a target image, attempting to preserve the original type.</p>
<dl class="field-list simple">
<dt class="field-odd">Parameters<span class="colon">:</span></dt>
<dd class="field-odd"><p><strong>image</strong> (<em>np.ndarray</em><em>, </em><em>tf.Tensor</em><em>, or </em><em>torch.Tensor</em>) – Image as a uint8
array. Numpy and Tensorflow images are normalized in W x H x C
space. PyTorch images provided as C x W x H will be
auto-converted and permuted back after normalization.</p>
</dd>
<dt class="field-even">Keyword Arguments<span class="colon">:</span></dt>
<dd class="field-even"><p><strong>augment</strong> (<a class="reference external" href="https://docs.python.org/3/library/functions.html#bool" title="(in Python v3.12)"><em>bool</em></a>) – Transform using stain aumentation.
Defaults to False.</p>
</dd>
<dt class="field-odd">Returns<span class="colon">:</span></dt>
<dd class="field-odd"><p>Normalized image of the original type (uint8).</p>
</dd>
</dl>
</dd></dl>
<dl class="py function">
<dt class="sig sig-object py" id="slideflow.norm.StainNormalizer.jpeg_to_jpeg">
<span class="sig-name descname"><span class="pre">jpeg_to_jpeg</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">self</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">jpeg_string</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><a class="reference external" href="https://docs.python.org/3/library/stdtypes.html#str" title="(in Python v3.12)"><span class="pre">str</span></a><span class="w"> </span><span class="p"><span class="pre">|</span></span><span class="w"> </span><a class="reference external" href="https://docs.python.org/3/library/stdtypes.html#bytes" title="(in Python v3.12)"><span class="pre">bytes</span></a></span></em>, <em class="sig-param"><span class="o"><span class="pre">*</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">quality</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><a class="reference external" href="https://docs.python.org/3/library/functions.html#int" title="(in Python v3.12)"><span class="pre">int</span></a></span><span class="w"> </span><span class="o"><span class="pre">=</span></span><span class="w"> </span><span class="default_value"><span class="pre">100</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">augment</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><a class="reference external" href="https://docs.python.org/3/library/functions.html#bool" title="(in Python v3.12)"><span class="pre">bool</span></a></span><span class="w"> </span><span class="o"><span class="pre">=</span></span><span class="w"> </span><span class="default_value"><span class="pre">False</span></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><a class="reference external" href="https://docs.python.org/3/library/stdtypes.html#bytes" title="(in Python v3.12)"><span class="pre">bytes</span></a></span></span><a class="headerlink" href="#slideflow.norm.StainNormalizer.jpeg_to_jpeg" title="Permalink to this definition">¶</a></dt>
<dd><p>Normalize a JPEG image, returning a JPEG image.</p>
<dl class="field-list simple">
<dt class="field-odd">Parameters<span class="colon">:</span></dt>
<dd class="field-odd"><p><strong>jpeg_string</strong> (<a class="reference external" href="https://docs.python.org/3/library/stdtypes.html#str" title="(in Python v3.12)"><em>str</em></a><em>, </em><a class="reference external" href="https://docs.python.org/3/library/stdtypes.html#bytes" title="(in Python v3.12)"><em>bytes</em></a>) – JPEG image data.</p>
</dd>
<dt class="field-even">Keyword Arguments<span class="colon">:</span></dt>
<dd class="field-even"><ul class="simple">
<li><p><strong>augment</strong> (<a class="reference external" href="https://docs.python.org/3/library/functions.html#bool" title="(in Python v3.12)"><em>bool</em></a>) – Transform using stain aumentation.
Defaults to False.</p></li>
<li><p><strong>quality</strong> (<a class="reference external" href="https://docs.python.org/3/library/functions.html#int" title="(in Python v3.12)"><em>int</em></a><em>, </em><em>optional</em>) – Quality level for creating the resulting
normalized JPEG image. Defaults to 100.</p></li>
</ul>
</dd>
<dt class="field-odd">Returns<span class="colon">:</span></dt>
<dd class="field-odd"><p>Normalized JPEG image.</p>
</dd>
<dt class="field-even">Return type<span class="colon">:</span></dt>
<dd class="field-even"><p><a class="reference external" href="https://docs.python.org/3/library/stdtypes.html#bytes" title="(in Python v3.12)">bytes</a></p>
</dd>
</dl>
</dd></dl>
<dl class="py function">
<dt class="sig sig-object py" id="slideflow.norm.StainNormalizer.jpeg_to_rgb">
<span class="sig-name descname"><span class="pre">jpeg_to_rgb</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">self</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">jpeg_string</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><a class="reference external" href="https://docs.python.org/3/library/stdtypes.html#str" title="(in Python v3.12)"><span class="pre">str</span></a><span class="w"> </span><span class="p"><span class="pre">|</span></span><span class="w"> </span><a class="reference external" href="https://docs.python.org/3/library/stdtypes.html#bytes" title="(in Python v3.12)"><span class="pre">bytes</span></a></span></em>, <em class="sig-param"><span class="o"><span class="pre">*</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">augment</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><a class="reference external" href="https://docs.python.org/3/library/functions.html#bool" title="(in Python v3.12)"><span class="pre">bool</span></a></span><span class="w"> </span><span class="o"><span class="pre">=</span></span><span class="w"> </span><span class="default_value"><span class="pre">False</span></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><span class="pre">ndarray</span></span></span><a class="headerlink" href="#slideflow.norm.StainNormalizer.jpeg_to_rgb" title="Permalink to this definition">¶</a></dt>
<dd><p>Normalize a JPEG image, returning a numpy uint8 array.</p>
<dl class="field-list simple">
<dt class="field-odd">Parameters<span class="colon">:</span></dt>
<dd class="field-odd"><p><strong>jpeg_string</strong> (<a class="reference external" href="https://docs.python.org/3/library/stdtypes.html#str" title="(in Python v3.12)"><em>str</em></a><em>, </em><a class="reference external" href="https://docs.python.org/3/library/stdtypes.html#bytes" title="(in Python v3.12)"><em>bytes</em></a>) – JPEG image data.</p>
</dd>
<dt class="field-even">Keyword Arguments<span class="colon">:</span></dt>
<dd class="field-even"><p><strong>augment</strong> (<a class="reference external" href="https://docs.python.org/3/library/functions.html#bool" title="(in Python v3.12)"><em>bool</em></a>) – Transform using stain aumentation.
Defaults to False.</p>
</dd>
<dt class="field-odd">Returns<span class="colon">:</span></dt>
<dd class="field-odd"><p>Normalized image, uint8, W x H x C.</p>
</dd>
<dt class="field-even">Return type<span class="colon">:</span></dt>
<dd class="field-even"><p>np.ndarray</p>
</dd>
</dl>
</dd></dl>
<dl class="py function">
<dt class="sig sig-object py" id="slideflow.norm.StainNormalizer.png_to_png">
<span class="sig-name descname"><span class="pre">png_to_png</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">self</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">png_string</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><a class="reference external" href="https://docs.python.org/3/library/stdtypes.html#str" title="(in Python v3.12)"><span class="pre">str</span></a><span class="w"> </span><span class="p"><span class="pre">|</span></span><span class="w"> </span><a class="reference external" href="https://docs.python.org/3/library/stdtypes.html#bytes" title="(in Python v3.12)"><span class="pre">bytes</span></a></span></em>, <em class="sig-param"><span class="o"><span class="pre">*</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">augment</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><a class="reference external" href="https://docs.python.org/3/library/functions.html#bool" title="(in Python v3.12)"><span class="pre">bool</span></a></span><span class="w"> </span><span class="o"><span class="pre">=</span></span><span class="w"> </span><span class="default_value"><span class="pre">False</span></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><a class="reference external" href="https://docs.python.org/3/library/stdtypes.html#bytes" title="(in Python v3.12)"><span class="pre">bytes</span></a></span></span><a class="headerlink" href="#slideflow.norm.StainNormalizer.png_to_png" title="Permalink to this definition">¶</a></dt>
<dd><p>Normalize a PNG image, returning a PNG image.</p>
<dl class="field-list simple">
<dt class="field-odd">Parameters<span class="colon">:</span></dt>
<dd class="field-odd"><p><strong>png_string</strong> (<a class="reference external" href="https://docs.python.org/3/library/stdtypes.html#str" title="(in Python v3.12)"><em>str</em></a><em>, </em><a class="reference external" href="https://docs.python.org/3/library/stdtypes.html#bytes" title="(in Python v3.12)"><em>bytes</em></a>) – PNG image data.</p>
</dd>
<dt class="field-even">Keyword Arguments<span class="colon">:</span></dt>
<dd class="field-even"><p><strong>augment</strong> (<a class="reference external" href="https://docs.python.org/3/library/functions.html#bool" title="(in Python v3.12)"><em>bool</em></a>) – Transform using stain aumentation.
Defaults to False.</p>
</dd>
<dt class="field-odd">Returns<span class="colon">:</span></dt>
<dd class="field-odd"><p>Normalized PNG image.</p>
</dd>
<dt class="field-even">Return type<span class="colon">:</span></dt>
<dd class="field-even"><p><a class="reference external" href="https://docs.python.org/3/library/stdtypes.html#bytes" title="(in Python v3.12)">bytes</a></p>
</dd>
</dl>
</dd></dl>
<dl class="py function">
<dt class="sig sig-object py" id="slideflow.norm.StainNormalizer.png_to_rgb">
<span class="sig-name descname"><span class="pre">png_to_rgb</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">self</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">png_string</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><a class="reference external" href="https://docs.python.org/3/library/stdtypes.html#str" title="(in Python v3.12)"><span class="pre">str</span></a><span class="w"> </span><span class="p"><span class="pre">|</span></span><span class="w"> </span><a class="reference external" href="https://docs.python.org/3/library/stdtypes.html#bytes" title="(in Python v3.12)"><span class="pre">bytes</span></a></span></em>, <em class="sig-param"><span class="o"><span class="pre">*</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">augment</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><a class="reference external" href="https://docs.python.org/3/library/functions.html#bool" title="(in Python v3.12)"><span class="pre">bool</span></a></span><span class="w"> </span><span class="o"><span class="pre">=</span></span><span class="w"> </span><span class="default_value"><span class="pre">False</span></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><span class="pre">ndarray</span></span></span><a class="headerlink" href="#slideflow.norm.StainNormalizer.png_to_rgb" title="Permalink to this definition">¶</a></dt>
<dd><p>Normalize a PNG image, returning a numpy uint8 array.</p>
<dl class="field-list simple">
<dt class="field-odd">Parameters<span class="colon">:</span></dt>
<dd class="field-odd"><p><strong>png_string</strong> (<a class="reference external" href="https://docs.python.org/3/library/stdtypes.html#str" title="(in Python v3.12)"><em>str</em></a><em>, </em><a class="reference external" href="https://docs.python.org/3/library/stdtypes.html#bytes" title="(in Python v3.12)"><em>bytes</em></a>) – PNG image data.</p>
</dd>
<dt class="field-even">Keyword Arguments<span class="colon">:</span></dt>
<dd class="field-even"><p><strong>augment</strong> (<a class="reference external" href="https://docs.python.org/3/library/functions.html#bool" title="(in Python v3.12)"><em>bool</em></a>) – Transform using stain aumentation.
Defaults to False.</p>
</dd>
<dt class="field-odd">Returns<span class="colon">:</span></dt>
<dd class="field-odd"><p>Normalized image, uint8, W x H x C.</p>
</dd>
<dt class="field-even">Return type<span class="colon">:</span></dt>
<dd class="field-even"><p>np.ndarray</p>
</dd>
</dl>
</dd></dl>
<dl class="py function">
<dt class="sig sig-object py" id="slideflow.norm.StainNormalizer.rgb_to_rgb">
<span class="sig-name descname"><span class="pre">rgb_to_rgb</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">self</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">image</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">ndarray</span></span></em>, <em class="sig-param"><span class="o"><span class="pre">*</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">augment</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><a class="reference external" href="https://docs.python.org/3/library/functions.html#bool" title="(in Python v3.12)"><span class="pre">bool</span></a></span><span class="w"> </span><span class="o"><span class="pre">=</span></span><span class="w"> </span><span class="default_value"><span class="pre">False</span></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><span class="pre">ndarray</span></span></span><a class="headerlink" href="#slideflow.norm.StainNormalizer.rgb_to_rgb" title="Permalink to this definition">¶</a></dt>
<dd><p>Normalize a numpy array (uint8), returning a numpy array (uint8).</p>
<dl class="field-list simple">
<dt class="field-odd">Parameters<span class="colon">:</span></dt>
<dd class="field-odd"><p><strong>image</strong> (<em>np.ndarray</em>) – Image (uint8).</p>
</dd>
<dt class="field-even">Keyword Arguments<span class="colon">:</span></dt>
<dd class="field-even"><p><strong>augment</strong> (<a class="reference external" href="https://docs.python.org/3/library/functions.html#bool" title="(in Python v3.12)"><em>bool</em></a>) – Transform using stain aumentation.
Defaults to False.</p>
</dd>
<dt class="field-odd">Returns<span class="colon">:</span></dt>
<dd class="field-odd"><p>Normalized image, uint8, W x H x C.</p>
</dd>
<dt class="field-even">Return type<span class="colon">:</span></dt>
<dd class="field-even"><p>np.ndarray</p>
</dd>
</dl>
</dd></dl>
<dl class="py function">
<dt class="sig sig-object py" id="slideflow.norm.StainNormalizer.tf_to_rgb">
<span class="sig-name descname"><span class="pre">tf_to_rgb</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">self</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">image</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">tf.Tensor</span></span></em>, <em class="sig-param"><span class="o"><span class="pre">*</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">augment</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><a class="reference external" href="https://docs.python.org/3/library/functions.html#bool" title="(in Python v3.12)"><span class="pre">bool</span></a></span><span class="w"> </span><span class="o"><span class="pre">=</span></span><span class="w"> </span><span class="default_value"><span class="pre">False</span></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><span class="pre">ndarray</span></span></span><a class="headerlink" href="#slideflow.norm.StainNormalizer.tf_to_rgb" title="Permalink to this definition">¶</a></dt>
<dd><p>Normalize a tf.Tensor (uint8), returning a numpy array (uint8).</p>
<dl class="field-list simple">
<dt class="field-odd">Parameters<span class="colon">:</span></dt>
<dd class="field-odd"><p><strong>image</strong> (<em>tf.Tensor</em>) – Image (uint8).</p>
</dd>
<dt class="field-even">Keyword Arguments<span class="colon">:</span></dt>
<dd class="field-even"><p><strong>augment</strong> (<a class="reference external" href="https://docs.python.org/3/library/functions.html#bool" title="(in Python v3.12)"><em>bool</em></a>) – Transform using stain aumentation.
Defaults to False.</p>
</dd>
<dt class="field-odd">Returns<span class="colon">:</span></dt>
<dd class="field-odd"><p>Normalized image, uint8, W x H x C.</p>
</dd>
<dt class="field-even">Return type<span class="colon">:</span></dt>
<dd class="field-even"><p>np.ndarray</p>
</dd>
</dl>
</dd></dl>
<dl class="py function">
<dt class="sig sig-object py" id="slideflow.norm.StainNormalizer.tf_to_tf">
<span class="sig-name descname"><span class="pre">tf_to_tf</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">self</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">image</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><a class="reference external" href="https://docs.python.org/3/library/typing.html#typing.Dict" title="(in Python v3.12)"><span class="pre">Dict</span></a><span class="w"> </span><span class="p"><span class="pre">|</span></span><span class="w"> </span><span class="pre">tf.Tensor</span></span></em>, <em class="sig-param"><span class="o"><span class="pre">*</span></span><span class="n"><span class="pre">args</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><a class="reference external" href="https://docs.python.org/3/library/typing.html#typing.Any" title="(in Python v3.12)"><span class="pre">Any</span></a></span></em>, <em class="sig-param"><span class="n"><span class="pre">augment</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><a class="reference external" href="https://docs.python.org/3/library/functions.html#bool" title="(in Python v3.12)"><span class="pre">bool</span></a></span><span class="w"> </span><span class="o"><span class="pre">=</span></span><span class="w"> </span><span class="default_value"><span class="pre">False</span></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><a class="reference external" href="https://docs.python.org/3/library/typing.html#typing.Tuple" title="(in Python v3.12)"><span class="pre">Tuple</span></a><span class="p"><span class="pre">[</span></span><a class="reference external" href="https://docs.python.org/3/library/typing.html#typing.Dict" title="(in Python v3.12)"><span class="pre">Dict</span></a><span class="w"> </span><span class="p"><span class="pre">|</span></span><span class="w"> </span><span class="pre">tf.Tensor</span><span class="p"><span class="pre">,</span></span><span class="w"> </span><span class="p"><span class="pre">...</span></span><span class="p"><span class="pre">]</span></span></span></span><a class="headerlink" href="#slideflow.norm.StainNormalizer.tf_to_tf" title="Permalink to this definition">¶</a></dt>
<dd><p>Normalize a tf.Tensor (uint8), returning a numpy array (uint8).</p>
<dl class="field-list simple">
<dt class="field-odd">Parameters<span class="colon">:</span></dt>
<dd class="field-odd"><ul class="simple">
<li><p><strong>image</strong> (<em>tf.Tensor</em><em>, </em><em>Dict</em>) – Image (uint8) either as a raw Tensor,
or a Dictionary with the image under the key ‘tile_image’.</p></li>
<li><p><strong>args</strong> (<em>Any</em><em>, </em><em>optional</em>) – Any additional arguments, which will be passed
and returned unmodified.</p></li>
</ul>
</dd>
<dt class="field-even">Keyword Arguments<span class="colon">:</span></dt>
<dd class="field-even"><p><strong>augment</strong> (<a class="reference external" href="https://docs.python.org/3/library/functions.html#bool" title="(in Python v3.12)"><em>bool</em></a>) – Transform using stain aumentation.
Defaults to False.</p>
</dd>
<dt class="field-odd">Returns<span class="colon">:</span></dt>
<dd class="field-odd"><p>A tuple containing the normalized tf.Tensor image (uint8,
W x H x C) and any additional arguments provided.</p>
</dd>
</dl>
</dd></dl>
<dl class="py function">
<dt class="sig sig-object py" id="slideflow.norm.StainNormalizer.torch_to_torch">
<span class="sig-name descname"><span class="pre">torch_to_torch</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">self</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">image</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><a class="reference external" href="https://docs.python.org/3/library/typing.html#typing.Dict" title="(in Python v3.12)"><span class="pre">Dict</span></a><span class="w"> </span><span class="p"><span class="pre">|</span></span><span class="w"> </span><span class="pre">torch.Tensor</span></span></em>, <em class="sig-param"><span class="o"><span class="pre">*</span></span><span class="n"><span class="pre">args</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">augment</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><a class="reference external" href="https://docs.python.org/3/library/functions.html#bool" title="(in Python v3.12)"><span class="pre">bool</span></a></span><span class="w"> </span><span class="o"><span class="pre">=</span></span><span class="w"> </span><span class="default_value"><span class="pre">False</span></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><a class="reference external" href="https://docs.python.org/3/library/typing.html#typing.Tuple" title="(in Python v3.12)"><span class="pre">Tuple</span></a><span class="p"><span class="pre">[</span></span><a class="reference external" href="https://docs.python.org/3/library/typing.html#typing.Dict" title="(in Python v3.12)"><span class="pre">Dict</span></a><span class="w"> </span><span class="p"><span class="pre">|</span></span><span class="w"> </span><span class="pre">torch.Tensor</span><span class="p"><span class="pre">,</span></span><span class="w"> </span><span class="p"><span class="pre">...</span></span><span class="p"><span class="pre">]</span></span></span></span><a class="headerlink" href="#slideflow.norm.StainNormalizer.torch_to_torch" title="Permalink to this definition">¶</a></dt>
<dd><p>Normalize a torch.Tensor (uint8), returning a numpy array (uint8).</p>
<dl class="field-list simple">
<dt class="field-odd">Parameters<span class="colon">:</span></dt>
<dd class="field-odd"><ul class="simple">
<li><p><strong>image</strong> (<em>torch.Tensor</em><em>, </em><em>Dict</em>) – Image (uint8) either as a raw Tensor,
or a Dictionary with the image under the key ‘tile_image’.</p></li>
<li><p><strong>args</strong> (<em>Any</em><em>, </em><em>optional</em>) – Any additional arguments, which will be passed
and returned unmodified.</p></li>
</ul>
</dd>
<dt class="field-even">Keyword Arguments<span class="colon">:</span></dt>
<dd class="field-even"><p><strong>augment</strong> (<a class="reference external" href="https://docs.python.org/3/library/functions.html#bool" title="(in Python v3.12)"><em>bool</em></a>) – Transform using stain aumentation.
Defaults to False.</p>
</dd>
<dt class="field-odd">Returns<span class="colon">:</span></dt>
<dd class="field-odd"><p><p>A tuple containing</p>
<blockquote>
<div><p>np.ndarray: Normalized torch.Tensor image, uint8 (channel dimension matching the input image)</p>
<p>args (Any, optional): Any additional arguments provided, unmodified.</p>
</div></blockquote>
</p>
</dd>
</dl>
</dd></dl>
</section>
<section id="example-images">
<h2>Example images<a class="headerlink" href="#example-images" title="Permalink to this heading">¶</a></h2>
<figure class="align-default" id="id4">
<img alt="../_images/wsi_norm_compare.jpg" src="../_images/wsi_norm_compare.jpg" />
<figcaption>
<p><span class="caption-text">Comparison of normalizers applied to a whole-slide image.</span><a class="headerlink" href="#id4" title="Permalink to this image">¶</a></p>
</figcaption>
</figure>
<figure class="align-default" id="id5">
<img alt="../_images/tile_norm_compare.jpg" src="../_images/tile_norm_compare.jpg" />
<figcaption>
<p><span class="caption-text">Comparison of normalizers applied to an image tile.</span><a class="headerlink" href="#id5" title="Permalink to this image">¶</a></p>
</figcaption>
</figure>
<figure class="align-default" id="id6">
<img alt="../_images/wsi_unnormalized.jpg" src="../_images/wsi_unnormalized.jpg" />
<figcaption>
<p><span class="caption-text">Unnormalized whole-slide images.</span><a class="headerlink" href="#id6" title="Permalink to this image">¶</a></p>
</figcaption>
</figure>
<figure class="align-default" id="id7">
<img alt="../_images/wsi_reinhard_v1.jpg" src="../_images/wsi_reinhard_v1.jpg" />
<figcaption>
<p><span class="caption-text">Whole-slide images normalized with <strong>Reinhard</strong>, fit to preset “v1” (default)</span><a class="headerlink" href="#id7" title="Permalink to this image">¶</a></p>
</figcaption>
</figure>
<figure class="align-default" id="id8">
<img alt="../_images/wsi_reinhard_v2.jpg" src="../_images/wsi_reinhard_v2.jpg" />
<figcaption>
<p><span class="caption-text">Whole-slide images normalized with <strong>Reinhard</strong>, fit to preset “v2”</span><a class="headerlink" href="#id8" title="Permalink to this image">¶</a></p>
</figcaption>
</figure>
<figure class="align-default" id="id9">
<img alt="../_images/wsi_macenko_v1.jpg" src="../_images/wsi_macenko_v1.jpg" />
<figcaption>
<p><span class="caption-text">Whole-slide images normalized with <strong>Macenko</strong>, fit to preset “v1” (default)</span><a class="headerlink" href="#id9" title="Permalink to this image">¶</a></p>
</figcaption>
</figure>
<figure class="align-default" id="id10">
<img alt="../_images/wsi_macenko_v2.jpg" src="../_images/wsi_macenko_v2.jpg" />
<figcaption>
<p><span class="caption-text">Whole-slide images normalized with <strong>Macenko</strong>, fit to preset “v2”</span><a class="headerlink" href="#id10" title="Permalink to this image">¶</a></p>
</figcaption>
</figure>
<figure class="align-default" id="id11">
<img alt="../_images/wsi_vahadane_v1.jpg" src="../_images/wsi_vahadane_v1.jpg" />
<figcaption>
<p><span class="caption-text">Whole-slide images normalized with <strong>Vahadane</strong>, fit to preset “v1” (default)</span><a class="headerlink" href="#id11" title="Permalink to this image">¶</a></p>
</figcaption>
</figure>
<figure class="align-default" id="id12">
<img alt="../_images/wsi_vahadane_v2.jpg" src="../_images/wsi_vahadane_v2.jpg" />
<figcaption>
<p><span class="caption-text">Whole-slide images normalized with <strong>Vahadane</strong>, fit to preset “v2”</span><a class="headerlink" href="#id12" title="Permalink to this image">¶</a></p>
</figcaption>
</figure>
<figure class="align-default" id="id13">
<img alt="../_images/wsi_vahadane_spams_v1.jpg" src="../_images/wsi_vahadane_spams_v1.jpg" />
<figcaption>
<p><span class="caption-text">Whole-slide images normalized with <strong>Vahadane (SPAMS)</strong>, fit to preset “v1” (default)</span><a class="headerlink" href="#id13" title="Permalink to this image">¶</a></p>
</figcaption>
</figure>
<figure class="align-default" id="id14">
<img alt="../_images/wsi_vahadane_spams_v2.jpg" src="../_images/wsi_vahadane_spams_v2.jpg" />
<figcaption>
<p><span class="caption-text">Whole-slide images normalized with <strong>Vahadane (SPAMS)</strong>, fit to preset “v2”</span><a class="headerlink" href="#id14" title="Permalink to this image">¶</a></p>
</figcaption>
</figure>
<figure class="align-default" id="id15">
<img alt="../_images/tile_unnormalized.jpg" src="../_images/tile_unnormalized.jpg" />
<figcaption>
<p><span class="caption-text">Unnormalized image tiles.</span><a class="headerlink" href="#id15" title="Permalink to this image">¶</a></p>
</figcaption>
</figure>
<figure class="align-default" id="id16">
<img alt="../_images/tile_reinhard_v1.jpg" src="../_images/tile_reinhard_v1.jpg" />
<figcaption>
<p><span class="caption-text">Image tiles normalized with <strong>Reinhard Mask</strong>, fit to preset “v1” (default)</span><a class="headerlink" href="#id16" title="Permalink to this image">¶</a></p>
</figcaption>
</figure>
<figure class="align-default" id="id17">
<img alt="../_images/tile_reinhard_v2.jpg" src="../_images/tile_reinhard_v2.jpg" />
<figcaption>
<p><span class="caption-text">Image tiles normalized with <strong>Reinhard Mask</strong>, fit to preset “v2”</span><a class="headerlink" href="#id17" title="Permalink to this image">¶</a></p>
</figcaption>
</figure>
<figure class="align-default" id="id18">
<img alt="../_images/tile_macenko_v1.jpg" src="../_images/tile_macenko_v1.jpg" />
<figcaption>
<p><span class="caption-text">Image tiles normalized with <strong>Macenko</strong>, fit to preset “v1” (default)</span><a class="headerlink" href="#id18" title="Permalink to this image">¶</a></p>
</figcaption>
</figure>
<figure class="align-default" id="id19">
<img alt="../_images/tile_macenko_v2.jpg" src="../_images/tile_macenko_v2.jpg" />
<figcaption>
<p><span class="caption-text">Image tiles normalized with <strong>Macenko</strong>, fit to preset “v2”</span><a class="headerlink" href="#id19" title="Permalink to this image">¶</a></p>
</figcaption>
</figure>
<figure class="align-default" id="id20">
<img alt="../_images/tile_vahadane_v1.jpg" src="../_images/tile_vahadane_v1.jpg" />
<figcaption>
<p><span class="caption-text">Image tiles normalized with <strong>Vahadane</strong>, fit to preset “v1” (default)</span><a class="headerlink" href="#id20" title="Permalink to this image">¶</a></p>
</figcaption>
</figure>
<figure class="align-default" id="id21">
<img alt="../_images/tile_vahadane_v2.jpg" src="../_images/tile_vahadane_v2.jpg" />
<figcaption>
<p><span class="caption-text">Image tiles normalized with <strong>Vahadane</strong>, fit to preset “v2”</span><a class="headerlink" href="#id21" title="Permalink to this image">¶</a></p>
</figcaption>
</figure>
<figure class="align-default" id="id22">
<img alt="../_images/tile_vahadane_spams_v1.jpg" src="../_images/tile_vahadane_spams_v1.jpg" />
<figcaption>
<p><span class="caption-text">Image tiles normalized with <strong>Vahadane (SPAMS)</strong>, fit to preset “v1” (default)</span><a class="headerlink" href="#id22" title="Permalink to this image">¶</a></p>
</figcaption>
</figure>
<figure class="align-default" id="id23">
<img alt="../_images/tile_vahadane_spams_v2.jpg" src="../_images/tile_vahadane_spams_v2.jpg" />
<figcaption>
<p><span class="caption-text">Image tiles normalized with <strong>Vahadane (SPAMS)</strong>, fit to preset “v2”</span><a class="headerlink" href="#id23" title="Permalink to this image">¶</a></p>
</figcaption>
</figure>
</section>
</section>
</article>
</div>
<footer>
<div class="rst-footer-buttons" role="navigation" aria-label="footer navigation">
<a href="../simclr/" class="btn btn-neutral float-right" title="slideflow.simclr" accesskey="n" rel="next">Next <img src="../_static/images/chevron-right-orange.svg" class="next-page"></a>
<a href="../model_torch/" class="btn btn-neutral" title="slideflow.model.torch" accesskey="p" rel="prev"><img src="../_static/images/chevron-right-orange.svg" class="previous-page"> Previous</a>
</div>
<hr>
<div role="contentinfo">
<p>
© Copyright 2023, James M Dolezal.
</p>
</div>
<div>
Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/rtfd/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
</div>
</footer>
</div>
</div>
<div class="pytorch-content-right" id="pytorch-content-right">
<div class="pytorch-right-menu" id="pytorch-right-menu">
<div class="pytorch-side-scroll" id="pytorch-side-scroll-right">
<ul>
<li><a class="reference internal" href="#">slideflow.norm</a><ul>
<li><a class="reference internal" href="#overview">Overview</a></li>
<li><a class="reference internal" href="#how-to-use">How to use</a><ul>
<li><a class="reference internal" href="#individual-images">Individual images</a></li>
<li><a class="reference internal" href="#dataloader-pre-processing">Dataloader pre-processing</a></li>
<li><a class="reference internal" href="#during-tile-extraction">During tile extraction</a></li>
<li><a class="reference internal" href="#on-the-fly">On-the-fly</a></li>
</ul>
</li>
<li><a class="reference internal" href="#performance">Performance</a></li>
<li><a class="reference internal" href="#contextual-normalization">Contextual Normalization</a></li>
<li><a class="reference internal" href="#stain-augmentation">Stain Augmentation</a></li>
<li><a class="reference internal" href="#stainnormalizer">StainNormalizer</a><ul>
<li><a class="reference internal" href="#slideflow.norm.StainNormalizer"><code class="docutils literal notranslate"><span class="pre">StainNormalizer</span></code></a></li>
<li><a class="reference internal" href="#slideflow.norm.StainNormalizer.fit"><code class="docutils literal notranslate"><span class="pre">fit()</span></code></a></li>
<li><a class="reference internal" href="#slideflow.norm.StainNormalizer.get_fit"><code class="docutils literal notranslate"><span class="pre">get_fit()</span></code></a></li>
<li><a class="reference internal" href="#slideflow.norm.StainNormalizer.set_fit"><code class="docutils literal notranslate"><span class="pre">set_fit()</span></code></a></li>
<li><a class="reference internal" href="#slideflow.norm.StainNormalizer.augment"><code class="docutils literal notranslate"><span class="pre">augment()</span></code></a></li>
<li><a class="reference internal" href="#slideflow.norm.StainNormalizer.transform"><code class="docutils literal notranslate"><span class="pre">transform()</span></code></a></li>
<li><a class="reference internal" href="#slideflow.norm.StainNormalizer.jpeg_to_jpeg"><code class="docutils literal notranslate"><span class="pre">jpeg_to_jpeg()</span></code></a></li>
<li><a class="reference internal" href="#slideflow.norm.StainNormalizer.jpeg_to_rgb"><code class="docutils literal notranslate"><span class="pre">jpeg_to_rgb()</span></code></a></li>
<li><a class="reference internal" href="#slideflow.norm.StainNormalizer.png_to_png"><code class="docutils literal notranslate"><span class="pre">png_to_png()</span></code></a></li>
<li><a class="reference internal" href="#slideflow.norm.StainNormalizer.png_to_rgb"><code class="docutils literal notranslate"><span class="pre">png_to_rgb()</span></code></a></li>
<li><a class="reference internal" href="#slideflow.norm.StainNormalizer.rgb_to_rgb"><code class="docutils literal notranslate"><span class="pre">rgb_to_rgb()</span></code></a></li>
<li><a class="reference internal" href="#slideflow.norm.StainNormalizer.tf_to_rgb"><code class="docutils literal notranslate"><span class="pre">tf_to_rgb()</span></code></a></li>
<li><a class="reference internal" href="#slideflow.norm.StainNormalizer.tf_to_tf"><code class="docutils literal notranslate"><span class="pre">tf_to_tf()</span></code></a></li>
<li><a class="reference internal" href="#slideflow.norm.StainNormalizer.torch_to_torch"><code class="docutils literal notranslate"><span class="pre">torch_to_torch()</span></code></a></li>
</ul>
</li>
<li><a class="reference internal" href="#example-images">Example images</a></li>
</ul>
</li>
</ul>
</div>
</div>
</div>
</section>
</div>
<script type="text/javascript" id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
<script data-url_root="../" id="documentation_options" src="../_static/documentation_options.js"></script>
<script src="../_static/doctools.js"></script>
<script src="../_static/sphinx_highlight.js"></script>
<script type="text/javascript" src="../_static/js/vendor/jquery-3.6.3.min.js"></script>
<script type="text/javascript" src="../_static/js/vendor/popper.min.js"></script>
<script type="text/javascript" src="../_static/js/vendor/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/list.js/1.5.0/list.min.js"></script>
<script type="text/javascript" src="../_static/js/theme.js"></script>
<script type="text/javascript">
jQuery(function () {
SphinxRtdTheme.Navigation.enable(true);
});
</script>
<!-- Begin Footer -->
<!-- End Footer -->
<!-- Begin Mobile Menu -->
<div class="mobile-main-menu">
<div class="container-fluid">
<div class="container">
<div class="mobile-main-menu-header-container">
<a class="header-logo" href="https://pytorch.org/" aria-label="PyTorch"></a>
<a class="main-menu-close-button" href="#" data-behavior="close-mobile-menu"></a>
</div>
</div>
</div>
<div class="mobile-main-menu-links-container">
<div class="main-menu">
<ul>
<li>
<a href="https://slideflow.dev">Docs</a>
</li>
<li>
<a href="https://slideflow.dev/tutorial1/">Tutorials</a>
</li>
<li>
<a href="https://github.com/slideflow/slideflow">Github</a>
</li>
</ul>
</div>
</div>
</div>
<!-- End Mobile Menu -->
<script script type="text/javascript">
var collapsedSections = [];
</script>
<script type="text/javascript" src="../_static/js/vendor/anchor.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
mobileMenu.bind();
mobileTOC.bind();
pytorchAnchors.bind();
sideMenus.bind();
scrollToAnchor.bind();
highlightNavigation.bind();
mainMenuDropdown.bind();
filterTags.bind();
// Add class to links that have code blocks, since we cannot create links in code blocks
$("article.pytorch-article a span.pre").each(function(e) {
$(this).closest("a").addClass("has-code");
});
})
</script>
</body>
</html>