此处以批量缩小ROI为例介绍如何利用shapely模块对ROI进行调整。

由于在ImageJ中选取ROI太小操作上会有点困难,所以有时候为了提高效率,会先稍微选取大一点的范围。但这样做不仅包含了信号区域,同时还包含了较多的背景区域,这个时候的采样就不是“纯”的信号了。有一种方案就是批量操作ROI,比如把它缩小一点。

2025-05-13T11:01:34.png

from roifile import roiread, ImagejRoi
import numpy as np
from shapely import geometry as geo

def roi_shrink(roi, ratio=0.1, verbose=False):
    '''
    roi: roifile读取后的roi对象
    '''
    assert ratio>0 and ratio<1
    roi_ = geo.Polygon(roi.coordinates())
    x, y = roi_.centroid.xy
    cx = x[0]
    cy = y[0]
    # 遍历所有轮廓上的点,找到一个距离质心最短的点,避免过度缩放
    xs, ys = roi_.exterior.xy
    idx = 0
    ds = []
    for xn, yn in zip(xs, ys):
        # 快速计算两点之间距离
        d = np.linalg.norm([xn-cx, yn-cy])
        ds.append(d)
        idx += 1
    idy = np.argmin(ds)
    mx = xs[idy]
    my = ys[idy]
    md = ds[idy]
    # 确定要缩小的buffer量(像素单位)
    td = md*ratio
    roi_2 = roi_.buffer(-td)  # 如果要放大就去除负号
    if verbose:
        print(f"buffer={td}")
    # 构造一个新的roi对象
    x2, y2 = roi_2.exterior.xy
    locs = np.array([x2, y2]).T
    roi2 = ImagejRoi.frompoints(locs)
    roi2.roitype=roi.roitype
    roi2.name = roi.name
    return roi2

上述代码算是一个ROI和Shapely综合利用的模板案例,事实上在这类抽样的问题中,更多是在ImageJ使用更为方便的点选,这样得到的是一个点,然后再buffer扩大来选取像素。

最后修改:2025 年 05 月 21 日
请大力赞赏以支持本站持续运行!