<jupyter_start><jupyter_text>SNOW network extraction The SNOW algorithm, [published in Physical Review E](https://doi.org/10.1103/PhysRevE.96.023307), uses a marker-based watershed segmentation algorithm to partition an image into regions belonging to each pore.  The main contribution of the SNOW algorithm is to find a suitable set of initial markers in the image so that the watershed is not over-segmented.  SNOW is an acronym for Sub-Network of an Over-segmented Watershed.  This code works on both 2D and 3D images.  In this example a 2D image will be segmented using the predefined ``snow`` function in PoreSpy.  Start by importing the necessary packages:<jupyter_code>import numpy as np
import porespy as ps
import openpnm as op
import matplotlib.pyplot as plt
ps.visualization.set_mpl_style()
np.random.seed(10)<jupyter_output><empty_output><jupyter_text>Generate an artificial 2D image for illustration purposes:<jupyter_code>im = ps.generators.blobs(shape=[400, 400], porosity=0.6, blobiness=2)
fig, ax = plt.subplots()
ax.imshow(im);<jupyter_output><empty_output><jupyter_text>SNOW is composed of a series of filters, but PoreSpy has a single function that applies all the necessary steps:<jupyter_code>snow_output = ps.networks.snow2(im, voxel_size=1)<jupyter_output><empty_output><jupyter_text>The ``snow`` function returns an object that has a ``network`` attribute.  This is a dictionary that is suitable for loading into OpenPNM.  The best way to get this into OpenPNM is to use the ``PoreSpy`` IO class.  This splits the data into a network and a geometry:<jupyter_code>prj = op.io.PoreSpy.import_data(snow_output.network)<jupyter_output><empty_output><jupyter_text>As can be seen by printing the project, it contains two objects:<jupyter_code>print(prj)<jupyter_output>――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
 Object Name     Object ID                                                        
――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
 net_01          <openpnm.network.GenericNetwork object at 0x21b6771d810>         
 geo_01          <openpnm.geometry.Imported object at 0x21b6771b450>              
――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――<jupyter_text>The network and geometry objects can be retrieved from the project as follows:<jupyter_code>pn = prj['net_01']
geo = prj['geo_01']<jupyter_output><empty_output><jupyter_text>You can also overlay the network on the image natively in `porespy`. Note that you need to transpose the image using `im.T`, since `imshow` uses matrix representation, e.g. a (10, 20)-shaped array is shown as 10 pixels in the y-axis, and 20 pixels in the x-axis.<jupyter_code>fig, ax = plt.subplots(figsize=[8, 8])
ax.imshow(im.T, cmap=plt.cm.bone);
op.topotools.plot_coordinates(ax=fig,
                              network=pn,
                              size_by=pn["pore.inscribed_diameter"],
                              color_by=pn["pore.inscribed_diameter"],
                              markersize=1000)
op.topotools.plot_connections(network=pn, ax=fig)
ax.axis("off");<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.15163934426229508, 'fraction_numerical': 0.023013871374527112, 'mean_word_length': 4.350758853288364, 'pattern_counts': {'":': 0, '<': 30, '<?xml version=': 0, '>': 30, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '7', 'dir': 'jupyter-structured-clean-dedup', 'id': '260849', 'license': 'MIT', 'n_tokens_mistral': 1217, 'n_tokens_neox': 1137, 'n_words': 294, 'path': 'examples/networks/tutorials/snow_basic.ipynb', 'repo_name': 'jamesobutler/porespy', 'size': '3172'}