| name | bio-spatial-transcriptomics-image-analysis |
| description | Process and analyze tissue images from spatial transcriptomics data using Squidpy. Extract image features, segment cells/nuclei, and compute morphological features from H&E or IF images. Use when processing tissue images for spatial transcriptomics. |
| tool_type | python |
| primary_tool | squidpy |
| measurable_outcome | Execute skill workflow successfully with valid output within 15 minutes. |
| allowed-tools | ["read_file","run_shell_command"] |
Image Analysis for Spatial Transcriptomics
Extract features and segment tissue images in spatial transcriptomics data.
Required Imports
import squidpy as sq
import scanpy as sc
import numpy as np
import matplotlib.pyplot as plt
from skimage import io, filters, segmentation
Access Tissue Images
library_id = list(adata.uns['spatial'].keys())[0]
img_dict = adata.uns['spatial'][library_id]['images']
hires = img_dict['hires']
lowres = img_dict['lowres']
print(f'Hires shape: {hires.shape}')
print(f'Lowres shape: {lowres.shape}')
scalef = adata.uns['spatial'][library_id]['scalefactors']
spot_diameter = scalef['spot_diameter_fullres']
hires_scale = scalef['tissue_hires_scalef']
Create ImageContainer
img = sq.im.ImageContainer(adata.uns['spatial'][library_id]['images']['hires'])
print(img)
img = sq.im.ImageContainer('tissue_image.tif')
arr = img['image'].values
Extract Image Features per Spot
sq.im.calculate_image_features(
adata,
img,
features=['summary', 'histogram', 'texture'],
key_added='img_features',
spot_scale=1.0,
n_jobs=4,
)
print(f"Image features shape: {adata.obsm['img_features'].shape}")
Available Image Features
sq.im.calculate_image_features(adata, img, features='summary')
sq.im.calculate_image_features(adata, img, features='histogram', features_kwargs={'histogram': {'bins': 16}})
sq.im.calculate_image_features(adata, img, features='texture')
sq.im.calculate_image_features(
adata, img,
features=['summary', 'texture'],
features_kwargs={
'summary': {'quantiles': [0.1, 0.5, 0.9]},
'texture': {'distances': [1, 2], 'angles': [0, np.pi/4, np.pi/2]},
}
)
Segment Cells/Nuclei
sq.im.segment(
img,
layer='image',
method='watershed',
channel=0,
thresh=0.5,
)
seg_mask = img['segmented_watershed'].values
Segment with Cellpose
from cellpose import models
model = models.Cellpose(model_type='nuclei')
image = img['image'].values[:, :, 0]
masks, flows, styles, diams = model.eval(image, diameter=30, channels=[0, 0])
img.add_img(masks, layer='cellpose_masks')
Extract Spot Image Crops
def get_spot_crop(adata, img_arr, spot_idx, crop_size=100):
coords = adata.obsm['spatial'][spot_idx]
scalef = adata.uns['spatial'][library_id]['scalefactors']['tissue_hires_scalef']
x, y = int(coords[0] * scalef), int(coords[1] * scalef)
half = crop_size // 2
crop = img_arr[max(0, y-half):y+half, max(0, x-half):x+half]
return crop
crop = get_spot_crop(adata, hires, 0)
plt.imshow(crop)
Color Deconvolution (H&E)
from skimage.color import rgb2hed, hed2rgb
hed = rgb2hed(hires)
hematoxylin = hed[:, :, 0]
eosin = hed[:, :, 1]
dab = hed[:, :, 2]
fig, axes = plt.subplots(1, 3, figsize=(15, 5))
axes[0].imshow(hematoxylin, cmap='gray')
axes[0].set_title('Hematoxylin')
axes[1].imshow(eosin, cmap='gray')
axes[1].set_title('Eosin')
axes[2].imshow(hires)
axes[2].set_title('Original')
plt.tight_layout()
Compute Morphological Features
from skimage.measure import regionprops_table
props = regionprops_table(
seg_mask,
intensity_image=hires[:, :, 0],
properties=['label', 'area', 'eccentricity', 'solidity', 'mean_intensity']
)
import pandas as pd
morph_df = pd.DataFrame(props)
print(morph_df.describe())
Use Image Features for Clustering
import numpy as np
expr_pca = adata.obsm['X_pca'][:, :20]
img_features = adata.obsm['img_features']
from sklearn.preprocessing import StandardScaler
expr_scaled = StandardScaler().fit_transform(expr_pca)
img_scaled = StandardScaler().fit_transform(img_features)
alpha = 0.3
combined = np.hstack([
(1 - alpha) * expr_scaled,
alpha * img_scaled
])
adata.obsm['X_combined'] = combined
sc.pp.neighbors(adata, use_rep='X_combined')
sc.tl.leiden(adata, key_added='combined_leiden')
Smooth Expression with Image
from scipy.spatial.distance import cdist
img_features = adata.obsm['img_features']
img_sim = 1 / (1 + cdist(img_features, img_features, metric='euclidean'))
img_sim = img_sim / img_sim.sum(axis=1, keepdims=True)
X_smoothed = img_sim @ adata.X
adata.layers['img_smoothed'] = X_smoothed
Related Skills
- spatial-data-io - Load spatial data with images
- spatial-visualization - Visualize images with expression
- spatial-domains - Use image features for domain detection