此处以批量缩小ROI为例介绍如何利用shapely模块对ROI进行调整。
由于在ImageJ中选取ROI太小操作上会有点困难,所以有时候为了提高效率,会先稍微选取大一点的范围。但这样做不仅包含了信号区域,同时还包含了较多的背景区域,这个时候的采样就不是“纯”的信号了。有一种方案就是批量操作ROI,比如把它缩小一点。
from roifile import roiread, ImagejRoiimport numpy as npfrom 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扩大来选取像素。