-标题:“基础的图像数据和空间模式分析在*R*”作者:“Andrzej Oleś and Wolfgang Huber”日期:21 July | BioC2015输出:ioslides_presentation: fig_retina: null css: style.css宽屏:false bibliography: BioC2015Oles。bib nocite: | @Pau2010, @Haralick1979, @Jones2005 vignette: > %\VignetteIndexEntry{R} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8}——```{R echo = false,message = false}库(Bioc2015oles)库(knitr)opts_chunk $ set(错误= false)set.seed(7).dpi = 100``` ##这个研讨会的目标 - 学习如何在* R *中读取和写入图像 - 了解如何在* R *中表示图像以及如何操作它们 - 了解如何将过滤器和转换应用于图像 - 将这些技能应用于要做分割的单元格的显微镜图像和特征提取 - 探索单元格的位置的空间分布## EBIMAGE ###图像处理和分析工具箱* R * - 读取和写入图像文件 - 交互式图像查看器 - 图像操作,转换和过滤 - 对象检测和功能萃取
自*Bioconductor* 1.8(2006)以来
###原创开发人员:Olebob电竞体育官网g Sklyar Wolfgang Huber Mike Smith Gregoire Pau |
###贡献者:Joseph Barry Bernd Fischer Ilia Kats Philip A. Marais |
! [EBImage-logo](图片/ logo.png) |
## 让我们开始吧!```{r,message = false,figth = 768 / .dpi,figth = 512 / .dpi,dpi = .dpi / 2}库(ebimage)f = system.file(“图像”,“sample.png“,package =”ebimage“)IMG = ReadImage(F)显示(IMG)```##读取和显示图像图片可以从本地文件或url中读取。' ' ' {r, fig.width = 480 /。dpi, fig.height = 138 /。dpi, dpi =。dpi, eval=FALSE} bioc = readImage("//www.anjoumacpherson.com/images/logo/jpg/bioconductor_logo_rgb.jpg") display(bioc)' ' '
! [RBioFormats](图片/ RBioFormats-logo.png) |
*EBImage*支持JPEG, PNG和TIFF文件格式。用于读取专有显微镜图像数据和元数据使用*[RBioFormats](https://github.com/aoles/RBioFormats)*。 |
###显示图像 - 交互式JavaScript Viewer - * R *的构建绘图设备默认的' display '方法可以通过' options(EBImage.display) '设置。“‘{r, eval = FALSE} (EBImage选项。显示=“光栅”)“# #添加文本标签的“{r, fig.width =暗(img) [1 l] /。dpi fig.height =暗(img) [2 l] /。dpi, dpi =。} display(img, method = "raster") text(x = 20, y = 20, label = "Parrots", adj = c(0,1), col = "orange", cex = 2) filename = "Parrots .jpg" dev.print(jpeg, filename = filename, width = dim(img)[1], height = dim(img)[2])' ' ' {r} file.size(文件名)支持的文件格式:JPEG, PNG和TIFF。{r} writeImage(img, "sample.tiff", quality = 85) writeImage(img, "sample.tiff") writeImage(img, "sample_compressed.tiff", compression = "deflate") files = list。data.frame(row.names= Files, size=file.size(Files))" " ##图像表示
多维像素强度阵列 - (x,y) - (x,y,**z**)z堆栈 - (x,y,**T.**)延时- (x, y, ** .C**)通道- (x, y, c, z, t,…) |
![样本](图像/ sample.png) |
![复制](图像/ replicate.png) |
! [sample-rgb](图片/ sample-rgb.png) |
##图像表示```{R} str(IMG)getClassDef(“图像”)DIM(IMG)```##图像摘要```{R} IMG IMAGEDATA(IMG)[1:3,1:6]```##图像直方图```{r,fig.width = 4,fig.height = 4} stay(img)范围(img)````````````{r,fig.width= DIM(IMG)[1L] /。DPI,Fig.Height = DIM(IMG)[2L] /。DPI,DPI = .dpi / 2,} f = system.file(“图像”,“样本颜色。PNG“,包=”ebimage“)Imgcol = ReadImage(F)显示(IMGCOL)打印(IMGCOL,SHORT = TRUE)```##图像堆栈```{r,echo = false} nuc = ReadImage(系统。文件(“图像”,“nuclei.tif”,package =“ebimage”))```{r,fig.width = dim(nuc)[1l] /。dpi,fig.height = dim(nuc)[2l] /。dpi,dpi = .dpi / 2} nuc = ReadImage(System.file(“图像”,“nuclei.tif”,package =“ebimage”))打印(NUC,Short = True)显示(NUC)```##图像堆栈```{r,fig.width = dim(nuc)[1l] /。dpi,fig.height = dim(nuc)[2l] /。dpi,dpi = .dpi}显示(nuc,方法=“光栅”,全部=真)```##操纵图像是数字阵列,可以通过任何* R *的算术运算符方便地操纵图像。###裁剪`````````{r,figth = 384l / .dpi,dpi = 384l / .dpi,dpi = .dpi / 2} Img = IMG [366:749,58:441]```###反演``````````````````````````````````````)dpi,fig.height = dim(img)[2l] /。dpi,dpi = .dpi / 2} img_neg =max(img) - img显示(Img_neg)```##操纵图像###亮度,对比度和伽马校正```{r算法,fig.width =(4 * dim(img)[1l] +100)/。dpi,fig.height =(dim(img)[2l] +40)/。dpi,dpi = .dpi / 2} IMG_COMB =组合(IMG,IMG + 0.3,IMG * 2,IMG ^ 0.5)显示(图块(IMG_COMB,NumberOfframes(IMG_COMB),LWD = 20,FG.COL =“WHITE”))```##特写图像###包含两组像素的二进制图像图像,它代表背景和前景像素。```{r,fig.width = dim(img)[1l] /。dpi,fig.height = dim(img)[2l] /。dpi,dpi = .dpi / 2} img_thresh = img> .5显示(img_thresh) ``` ## Tresholding images ### Binary images Images which contain only two sets of pixels, which represent the background and the foreground pixels. ```{r} img_thresh ``` ## Spatial transformations ### Translation ```{r translate, fig.width=dim(img)[1L]/.dpi, fig.height=dim(img)[2L]/.dpi, dpi=.dpi/2} img_translate = translate(img, v = c(100, -50)) display(img_translate) ``` ## Spatial transformations ### Rotation ```{r rotate-pre, echo=FALSE} img_rotate = rotate(img, 30) ```{r rotate, fig.width=dim(img_rotate)[1L]/.dpi, fig.height=dim(img_rotate)[2L]/.dpi, dpi=.dpi/2} img_rotate = rotate(img, angle = 30, bg.col = "white") display(img_rotate) ``` ## Spatial transformations ### Scaling ```{r resize, fig.width=512/.dpi, fig.height=256/.dpi, dpi=.dpi/2} img_resize = resize(img, w = 512, h = 256) display(img_resize) ```{r resize2, fig.width=256/.dpi, fig.height=256/.dpi, dpi=.dpi/2} img_resize = resize(img, 256) display(img_resize) ``` ## Spatial transformations ### Vertical and horizontal reflection ```{r flipflop, fig.width=dim(img)[1L]/.dpi, fig.height=dim(img)[2L]/.dpi, dpi=.dpi/2} display( flip(img) ) display( flop(img) ) ``` ## Affine transformation Described by a 3x2 transformation matrix $\textbf{m}$
$$ \ begin {bmatrix} x'_1&y'_1 \\ x'_2&y'_2 \\ \ vdots&vdots \\ \ neg {bmatrix} = \ begin {bmatrix} x_1&y_1&1 \\x_2&y_2&1 \\ \ vdots&vdots&\ ddots \\ \ nod {bmatrix} \ times \ textbf {m} $$
$ $ \ textbf {m} _{\文本翻译}{}= {bmatrix} \开始1 0 \ \ & 0 & 1 \ \ t_x & t_y \ \ \ {bmatrix}, \四\ textbf {m} _{\文本{旋转}}= {bmatrix} \ \开始cosθ}{\ & \ sinθ}{\ \ \ - \ sinθ}{\ & \ cosθ}{\ \ \ & 0 \ \ \ {bmatrix}, \四\ textbf {m} _{\文本{缩放}}= {bmatrix}开始\ W & 0 \ \ 0 & H \ \ & 0 \ \ \ {bmatrix} $ $
# #仿射变换例子:水平纯粹映射```{r,fig.width = dim(img)[1l] /。dpi,fig.height = dim(img)[2l] /。dpi,dpi = .dpi / 2}角= pi /6 m =矩阵(c(1,-sin(角),sin(角)* dim(img)[2] / 2,0,1,0),nrow = 3,ncol = 2)m img_affine =仿射(img,m)显示(Img_affine)```##图像转置```{r映射,figth = dim(imgcol)[2l] /。dpi,fig.height = dim(imgcol)[1l] /。DPI,DPI = .DPI / 2} IMGCOL_T =转置(IMGCOL)显示(IMGCOL_T)```##线性过滤器###移除局部人工制品或噪声——矩形窗口的平均值
$$ f'(x,y)= \ frac {1} {n} \ sum_ {s = -a} ^ {a} \ sum_ {t = -a} ^ {a} f(x + s,y +T.),$$ where $f(x,y)$ is the value of the pixel at position $(x, y)$, $a$ determines the window size, which is $2a+1$ in each direction. $N=(2a+1)^2$ is the number of pixels averaged over, and $f'$ is the new, smoothed image.
###泛化:使用一个权重函数$w$加权平均
$$(w * f)(x,y)= \ sum_ {s = - \ infty} ^ {+ infty} \ sum_ {t = - \ infty} ^ {+ \ infty} w(s,t)\,f(x + s,y + s)$$ - $ f $和$ w $的图像卷积,由$ * $ - 线性指示:对于任何两个图像$ f_1 $,$ f_2 $和数字$ c_1 $,$ c_2 $ $$ w *(c_1f_1 + c_2f_2)= c_1w * f_1 + c_2w * f_2 $$
##生成权重函数可以使用“MakeBrush”生成权重功能。```{r,echo = false} opts_knit $ set(global.par = true)```{r,echo = false} .par = par(mai = c(.45,.75,0.05,0.05))````{r makebrush,figthth = 3.8,fig.height = 3.5,dev =“svg”,} w = makebrush(size = 31,shape ='gaussian',sigma = 5)plot(w [(nrow(w)+1)/ 2,],ylab =“w”,xlab =“”)```其他可用刷子形状:`“box”`(默认),`“光盘”`,`“钻石”`,`“线”`##低通滤波2D线性卷积由`filter2`实现(使用FFT)例子:使用宽度5``` {r,echo = false} opts_knit $ set(global.par = false)```{r lopass,figth = dim(img)[1l] /。dpi fig.height =暗(img) [2 l] /。dpi, dpi =。dpi/2} img_flo = filter2(img, w) display(img_flo) ``` ## High-pass filtering Detecting edges and sharpening images ```{r highpass, fig.width=dim(img)[1L]/.dpi, fig.height=dim(img)[2L]/.dpi, dpi=.dpi/2} fhi = matrix(1, nrow = 3, ncol = 3) fhi[2, 2] = -8 fhi img_fhi = filter2(img, fhi) display(img_fhi) ``` ## Adaptive tresholding Compensate for spatial dependencies of the background signal ```{r, fig.width=(3*dim(nuc)[1L]+80)/.dpi, fig.height=(dim(nuc)[2L]+40)/.dpi, dpi=.dpi/2} disc = makeBrush(21, "disc") disc = disc / sum(disc) nuc = getFrame(nuc, 1) nuc_bg = filter2(nuc, disc) offset = 0.02 nuc_thresh = (nuc - nuc_bg) > offset img_comb = combine(nuc, nuc_bg, nuc_thresh) display( tile(img_comb, numberOfFrames(img_comb), lwd = 20, fg.col = "white") ) ``` ## Median filter Non-linear noise removal technique - particularly effective in the case of speckle noise - preserves edges ```{r medianFilter, fig.width=2*dim(img)[1L]/.dpi, fig.height=dim(img)[2L]/.dpi, dpi=.dpi/2, eval=TRUE} l = length(img) n = l/10 img_noisy = img img_noisy[sample(l, n)] = runif(n, min = 0, max = 1) img_median = medianFilter(img_noisy, size = 1) display( combine(img_noisy, img_median), all=TRUE) ```
使用恒定时间算法[@ perreault2007]实现。
##形态操作{.noiterpolation}二进制图像的非线性滤波 -侵蚀:对于每一个FG.像素,将遮罩放在它周围,如果掩模下面的任何像素是来自的BG.,将所有这些像素设置为BG.。-扩张:每次BG.像素,将遮罩放在它周围,如果掩模下面的任何像素是来自的FG.,将所有这些像素设置为FG.。````{R echo = false}叶= ReadImage(System.file('emages','flap.png',package ='bioc2015oles')).lafdim = bioc2015oles ::: tilesdim(Dim(叶),3)```{r,fig.width = .lafdim [1] /。dpi,fig.height = .lafdim [2] /。dpi,dpi = .dpi,out.width = 2 * .lafdim [1],结果='hide'}叶= readimage(system.file('emages','leaf.png',package ='bioc2015oles'))kern = makebrush(size = 3)变形(叶子,erode(叶,kern),扩张(叶,谢尔))displaytiles(变形)```##形态学操作{.noiterpolation} - **开幕式:**侵蚀和膨胀将小物体从背景中移除- **关闭:**膨胀之后的侵蚀填充前景中的空洞' ' {r, fig.width=. leafdim[1]/。dpi fig.height = .leafDim[2] /。dpi, dpi =。dpi out.width = 2 *。leafDim[1]} morph = combine(leaf, open (leaf, kern), closing(leaf, kern)) displayTiles(morph)在细胞生物学中的应用荧光显微镜图像来自HeLa细胞的两个通道。' ' ' {r} dna = readImage(系统。print(dna, short=TRUE) tub = readImage(system. txt, txt . txt, txt . txt)("images", "cells.tif", package="EBImage"){r, fig.width=2*dim(nuc)[1L]/. {r, fig.width=2*dim(nuc)[1L]/.}dpi fig.height =暗(nuc) [2 l] /。dpi, dpi =。dpi/3} display(combine(dna, 3), getFrame(tub, 3)), all=TRUE)' ' ' {r, fig.width = BioC2015Oles::: tilesDim(暗(dna), numberOfFrames (dna)) [1 l] /。dpi fig.height = BioC2015Oles::: tilesDim(暗(dna), numberOfFrames (dna)) (2 l) /。dpi, dpi =。dpi/3} rgb = rgbImage(green = 1.5 * tub, blue = dna) displayTiles(rgb) ``` ## Nuclei segmentation - Adaptive thresholding of the DNA channel - Morphological opening and filling of holes - Distance map computation and watershed transformation ### Adaptive thresholding and morphological filtering ```{r, fig.width=2*dim(nuc)[1L]/.dpi, fig.height=dim(nuc)[2L]/.dpi, dpi=.dpi/2} nmaskt = thresh(dna, w = 15, h = 15, offset = 0.05) nmaskf = fillHull( opening(nmaskt, makeBrush(5, shape='disc')) ) display( combine(getFrame(nmaskt, 3), getFrame(nmaskf, 3)), all=TRUE ) ``` ## Nuclei segmentation ### Distance map computation ```{r, fig.width=dim(nuc)[1L]/.dpi, fig.height=dim(nuc)[2L]/.dpi, dpi=.dpi/2} dmap = distmap(nmaskf) range(dmap) display(normalize(dmap), frame = 3) ``` ## Nuclei segmentation ### Watershed transformation ```{r, fig.width=2*dim(nuc)[1L]/.dpi, fig.height=dim(nuc)[2L]/.dpi, dpi=.dpi/2} nmask = watershed(dmap, tolerance = 2) display( combine( toRGB( getFrame(dna, 3) ), colorLabels( getFrame(nmask, 3) ) ), all=TRUE ) ``` `bwlabel` - a simpler and faster function for segmenting connected objects ## Cytoplasm segmentation Identification of cell bodies by Voronoi partitioning using the segmented nuclei as seeds. ```{r, fig.width=2*dim(nuc)[1L]/.dpi, fig.height=dim(nuc)[2L]/.dpi, dpi=.dpi/2} cmaskt = closing( gblur(tub, 1) > 0.105, makeBrush(5, shape='disc') ) cmask = propagate(tub, seeds=nmask, mask=cmaskt, lambda = 0.001) display( combine( toRGB( getFrame(cmaskt, 3) ), colorLabels( getFrame(cmask, 3) ) ), all=TRUE ) ``` ## Voronoi tesselation Voronoi diagram is a partitioning of a plane into regions based on distance to some specific points of that plane (seeds). ### Voronoi tesselation on a Riemann manifold - arbitrary shape (provided in `mask`) - arbitrary metric (dependent on image gradient $z$)
点$(x, y, z)$和$(x+dx, y+dy, z+dz)$之间的距离大概{$ $ ds = \ \压裂{2}{\λ+ 1}\离开[\λ\离开(dx ^ 2 + dy ^ 2 \右)+ dz ^ 2 \]} $ $$\lambda$控制欧几里德距离项的权重-当$\lambda$很大时,$ds$趋向于欧几里德距离-对于小的$\lambda$, $ds$趋向于图像的强度梯度
##最终分割```{r,fig.width = 2 * dim(nuc)[1l] /。dpi,fig.height = 2 * dim(nuc)[2l] /。dpi,dpi = .dpi / 2显示(PaintObjects(CMASK,PINSOROBJECT(CMASK,RGB,COL =“洋红色”,厚= TRUE),COL =“黄色”,厚=真),ALL = TRUE)``##单个单元格堆叠```{r,fig.width = 2 * dim(nuc)[1l] /。dpi,fig.height = 2 * dim(nuc)[2l] /。dpi,dpi = .dpi / 2,eval = true} st =StackObjects(CMASK,RGB)显示(ST,ALL = TRUE)```##特征提取定量蜂窝描述符 - 像素强度`ComputeAtures.Basic`形状的基本统计数据(区域,周边,半径)`computemeatures.shape`- 时刻(质量中心,偏心,...)`computemeatures.moment` - haralick纹理特征`computemeatures.haralick```` {r}头(computefeatures.shape(cmask [,,1],浴缸[,1]))````##使用多变量分析方法的自动蜂窝成像方法我们可以: - 检测细胞亚群(聚类) - 将细胞分类为预定义的细胞类型或表型(分类) - BASED在亚步骤的频率上比较不同的生物条件
![管道](图像/ pipeline.png)
#空间统计:点过程免疫和癌细胞之间的相互作用淋巴结-免疫过滤器由B细胞,T细胞,树突状细胞(DC)和巨噬细胞组成-临床意义的癌症分期(*哨兵*淋巴结)
{r, echo=FALSE}。文件("images", "testscan_1_2_RGB99-4525D.jpg", package = "BioC2015Oles")' ' ' {r,呼应= FALSE, fig.width =暗(.lymphnode) [1 l] / (4 * .dpi), fig.height =暗(.lymphnode) (2 l) / (4 * .dpi), dpi =。dpi}显示器(.lymphnode)' ' ' |
乳腺癌淋巴结活检[@ setiadi2010]。通过用提供特定签名的蛋白质抗体染色细胞来完成细胞键入。 |
##淋巴结活检' ' ' {r} data(brcalymphnode, package = "BioC2015Oles") head(brcalymphnode) nrow(brcalymphnode) table(brcalymphnode$class)T细胞(左)、肿瘤细胞(右)*x*、*y*位置图’‘{r, fig.width = 7, fig.height = 3.5} par (mfrow = c(1、2)、3月= c (4.5, 4.5, 0.5, 0.5)) xlim =范围(brcalymphnode $ x) ylim =范围(brcalymphnode $ y)关口= c(“T_cells”=“dodgerblue4”,“肿瘤”=“darkmagenta”),(我在seq_along(关口))情节(子集(brcalymphnode、类= =名字(关口)[我])[c (x, y)], pch =“。”,asp = 1, xlim = xlim ylim = ylim,坳=关口[我])标记空间点过程的空间点模式分析:-位于数学空间(' xlim ', ' ylim ')的孤立点集-标记某些属性(因子'类')的点' ' ' {r、消息= FALSE}图书馆(“spatstat”)ln = (brcalymphnode,购买力平价(x = x, y = y,标志着=类,xrange = xlim yrange = ylim)) ln的“# #凸包的“{r, fig.width = 2, fig.height = 2} chull = convexhull (ln)标准(mar = c(0, 0, 0, 0))情节(窗口(ln),主要= NULL, asp = 1)情节(chull lty = 2,坳=“lightblue”,ln ' ' ' ##一阶效应:强度-在一个区域的圆圈内的点的数量$a$在一个点附近$p=(x,y)$$$ n(p,a)$$- 局部强度$ $ \λ(p) = \ lim_ {\ rightarrow 0} \压裂{E [N (p)]}{一}$ $- 对于*静止*过程,即,在该地区的各个均匀$$ \ lambda(p)= \ text {const。} $$然后,面积$ a $的强度与该区域成比例$$ e(n(\ cdot,a))= \ lambda a $$##估计点模式的强度内核平滑强度估计[@ dipgle1985]
$$ hat{\lambda}(p) = \sum_i e(p_i) K(p-p_i)$$,其中$K$为高斯平滑核,$e(p_i)$为边缘校正因子。
```{r density.ppp1,fig.width = 5.25,fig.height = 2.65}密度=孤立者(`挖掘的边缘校正'=浓度(子集(ln,marks ==“肿瘤”),dodgle = true),`没有边缘校正=密度(子集(LN,Marks ==“肿瘤”),边缘=假))绘图(密度,相等.Ribbon = True,Col = Topo.colors,Main =“”)```##小区类的概率估计特定事件类型的空间变化概率(Figth = 9.5,图= 2.8} Rr = RERRISK(LN,Sigma = 250)图(RR,等于。ribbon = TRUE, col = topo.colors, nrows = 1, main = "") ``` ## Second order effects: clustering Spatial clustering (or anticlustering) of points: whether and to what extent neighboring points are more/less dense than expected by chance. ### Poisson process
- 静止强度$ \ lambda $ - 非重叠区域中的物体发生之间的依赖性 - $ n(p,a)$遵循泊松分销,速率$ \ lambda a $
最近邻(NN)距离分布函数$G$从一个典型的随机点到其最近邻的距离$W$的累积分布函数。对于泊松过程$$ g(r)= p(w \ leq r)= 1-e ^ { - \ lambda \ pi r ^ 2} $$##估计NN距离函数* G *``{R gest} Gln = gest(ln)gln``` ##估计Nn距离函数* g *```{r,fig.width = 4,fig.height = 4,message = false}库(rcolorbrewer)par(mar = c(4.5,4.5,0.5,0.5))图(gln,lty = 1,col = brewer.pal(4,set1“),main =“”)```
- 有限细胞尺寸 - 大距离聚类的影响
## Ripley's * K * -K *静止点处理$ \ Lambda K(r)$是距离$ $ $ $ $ $ $ $ $ $ $ $ $ $的额外点数。###泛化点流程
$$ k _ {\ text {inhom}}(r)= sum_ {i,j} {\ mathbf 1} _ {d(p_i,p_j)\ le r} \ times \ frac {e(p_i,p_j,r)}} {\ lambda(x_i)\ lambda(x_j)},$$
其中$ d(p_i,p_j)$距离$ p_i $和$ p_j $之间的距离,$ e(p_i,p_j,r)$是一个边缘校正因子。对估计和可视化更有用的是$ l $ -function
$$ l(r)= \ sqrt {\ frac {k(r)} {\ pi}}。$$
对于泊松点模式,理论值是$ l(r)= r $。##估计不均匀的* l * -l * -function``` {r,eval = false} lln = linhom(子集(ln,marks ==“t_cells”))lln``` {r,echo = false}数据(lln,package =“bioc2015oles”)lln``` ##估计不均匀* l * -l * l * -function``` {r,figthth = 4.5,fig.height = 4.5} par(mar = c(4.5,4.5,0.5,0.5))图(LLN,Lln,Ltty = 1,Col = Brewer.pal(3,“set1”),main =“”)```##对相关函数描述点密度如何随距离的函数而变化从参考点。
$$ g(r)= \ frac {1} {2 \ pi r} \ frac {dk} {dr}(r)$$
对于静止泊松过程$ g(r)= 1 $。
- $ g(r)<1 $ - 点之间的禁止 - $ g(r)>> $ - 群集
##对关联函数```{r,eval = false} pcfln = pcf(kinshom(subset(ln,marks ==“t_cells”)))“pcfln,lty = 1,log =”x“)```{r,fig.width = 4.5,fig.height = 4.5,echo = false} par(mar = c(4.5,4.5,0.5,0.5))数据(pcfln,package =“bioc2015oles”)plot(pcfln,lty= 1,log =“x”,main =“”)```##引用{.smaller}