maladmin

stMincut

Jun 3rd, 2014
290
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
R 4.77 KB | None | 0 0
  1. rm(list=ls())
  2. library(igraph)
  3. library(Matrix)
  4.  
  5.  
  6. # Helper functions for graph creation -------------------------------------
  7.  
  8. getSubscripts <- function(idx,msize)
  9. {
  10.   idx<-idx - 1;
  11.   fsize <- msize[1] * msize[2]
  12.   z <- (idx %/% fsize)
  13.   idx <- idx - (z*fsize)
  14.   y <- idx %/% msize[1]
  15.   x<-idx - (y*msize[1])
  16.   return(c(x+1,y+1,z+1))
  17. }
  18. getNeighbourIndex<-function(idx,msize,dX,dY)
  19. {
  20.   s<-getSubscripts(idx,msize)
  21.   neighbours<-rep(NA,6)
  22.   neighbours[1]<-getIndex(s[1]+1,s[2],s[3],msize,base=TRUE) #voxel below
  23.   neighbours[2]<-getIndex(s[1]+dX,s[2]+1,s[3],msize,base=TRUE) #next column
  24.   neighbours[3]<-getIndex(s[1]+dX,s[2]-1,s[3],msize,base=TRUE) #prev column
  25.   neighbours[4]<-getIndex(s[1]+dY,s[2],s[3]+1,msize,base=TRUE) #next frame
  26.   neighbours[5]<-getIndex(s[1]+dY,s[2],s[3]-1,msize,base=TRUE) #prev frame
  27.   neighbours[6]<-idx
  28.   return(neighbours)
  29. }
  30. getIndex <- function(x,y,z,msize,base=TRUE)
  31. {
  32.   if(base)
  33.   {
  34.     x[x<1]<-NA
  35.   }else{
  36.     x[x<1]<-NA
  37.   }
  38.  
  39.   if(base)
  40.   {
  41.     x[x>msize[1]]<-msize[1]
  42.     #      x[x>msize[1]]<-NA
  43.   }else{
  44.     x[x>msize[1]]<-NA
  45.   }
  46.   y[y<1]<-NA
  47.   y[y>msize[2]]<-NA
  48.   z[z<1]<-NA
  49.   if(is.na(msize[3]))
  50.   {
  51.     z[z>1]<-NA
  52.   }else{
  53.     z[z>msize[3]]<-NA
  54.   }
  55.  
  56.   fsize <- msize[1] * msize[2]
  57.   idx = (z-1) * fsize
  58.   idx <- (y - 1) * msize[1] + idx
  59.   idx <- x + idx;
  60.   return(idx)
  61. }
  62. getBaseNeighbourIndex<-function(idx,msize)
  63. {
  64.   s<-getSubscripts(idx,msize)
  65.   if(s[1]!=msize[1])
  66.     #if(s[1]!=1)
  67.   {
  68.     stop('Not a base layer voxel')
  69.   }
  70.   neighbours<-rep(NA,4)
  71.   neighbours[1]<-getIndex(s[1],s[2]+1,s[3],msize,base=TRUE) #voxel next column
  72.   neighbours[2]<-getIndex(s[1],s[2]-1,s[3],msize,base=TRUE) #voxel prev column
  73.   neighbours[3]<-getIndex(s[1],s[2],s[3]+1,msize,base=TRUE) #next frame
  74.   neighbours[4]<-getIndex(s[1],s[2],s[3]-1,msize,base=TRUE) #prev frame
  75.   return(neighbours)
  76. }
  77. # Create artificial image -------------------------------------------------
  78. img<-matrix(0,nrow=6,ncol=5)
  79.  
  80. szImg<-dim(img)
  81. numEl<-szImg[1]*szImg[2]
  82.  
  83.  
  84. img[c(3,5),]<-1
  85.  
  86. sources_S1<-vector(length=(numEl*6))
  87. targets_S1<-vector(length=(numEl*6))
  88.  
  89.  
  90. mnames<-matrix(nrow=numEl,ncol=3)
  91.  
  92.  
  93. # build the internal n-links ----------------------------------------------
  94.  
  95. dX_s1<-1
  96. dY_s1<-1
  97. for(iVoxel in 1:numEl)
  98.   {
  99.   if(iVoxel %% 1000 == 0)
  100.     {
  101.     cat(sprintf('Processing Voxel:%i\n',iVoxel))
  102.     }
  103.   subscript <- getSubscripts(iVoxel,szImg)
  104.   mnames[iVoxel,]<-subscript
  105.   neighbours<-getNeighbourIndex(iVoxel,szImg,dX_s1,dY_s1)
  106.   sources_S1[((iVoxel-1)*6 + 1):(iVoxel*6)]<-iVoxel
  107.   targets_S1[((iVoxel-1)*6 + 1):(iVoxel*6)]<-neighbours
  108.   }
  109.  
  110. blanks<-is.na(targets_S1)
  111. sources_S1<-sources_S1[!blanks]
  112. targets_S1<-targets_S1[!blanks]
  113.  
  114. #make the bottom layer (Vb) well connected
  115. sources_base<-vector(length=(numEl / szImg[1])*4)
  116. targets_base<-vector(length=(numEl / szImg[1])*4)
  117. baseVoxels<-seq(from=szImg[1],to=numEl,by=szImg[1])
  118.  
  119. for(iloc in 1:length(baseVoxels))
  120.   {
  121.   iVoxel=baseVoxels[iloc]
  122.   neighbours<-getBaseNeighbourIndex(iVoxel,szImg)
  123.   sources_base[((iloc-1)*4 + 1):(iloc*4)]<-iVoxel
  124.   targets_base[((iloc-1)*4 + 1):(iloc*4)]<-neighbours
  125.   }
  126. blanks<-is.na(targets_base)
  127. sources_base<-sources_base[!blanks]
  128. targets_base<-targets_base[!blanks]
  129.  
  130. sources<-c(sources_S1,sources_base)
  131. targets<-c(targets_S1,targets_base)
  132.  
  133.  
  134. # create the adjacency matrix ---------------------------------------------
  135. adjM<-sparseMatrix(i=sources,j=targets,x=10000)
  136.  
  137.  
  138. # create the inital MRF ---------------------------------------------------
  139. g<-graph.adjacency(adjM,mode='directed',weighted=TRUE)
  140.  
  141. g<-simplify(g)  #remove the edge loops
  142.  
  143. g<-set.vertex.attribute(g,'r',1:numEl,mnames[,1])
  144. g<-set.vertex.attribute(g,'c',1:numEl,mnames[,2])
  145. g<-set.vertex.attribute(g,'f',1:numEl,mnames[,3])
  146. g<-set.vertex.attribute(g,'s',1:numEl,1)
  147. g<-set.vertex.attribute(g,'color',1:numEl,'green')
  148. g<-set.vertex.attribute(g,'name',1:vcount(g),sprintf('s=%i,r=%i,c=%i,f=%i',V(g)$s,V(g)$r,V(g)$c,V(g)$f))
  149.  
  150. # add the source and sink vertices {s,t} ----------------------------------
  151. g<-g+vertex('s',f=0,r=0,c=0,id='s',name='s')
  152. g<-g+vertex('t',f=0,r=0,c=0,id='t',name='t')
  153.  
  154.  
  155. # generate the costs for the voxels ---------------------------------------
  156.  
  157. costS1<-apply(img,2,cumsum)
  158.  
  159. # normalise costs to be between -1 and +1
  160. costS1<-(costS1-median(costS1))/((max(costS1)-min(costS1))/2)
  161.  
  162.  
  163. #voxels with a low cost are likely to be of interest, they should be connected to the source
  164.  
  165. ri<-which(costS1<0)  
  166. g['s',ri,attr='weight']<-abs(costS1[ri])
  167.  
  168.  
  169. #join the base layer (Vb) to the source vertex
  170. rVb<-seq(from=szImg[1],to=numEl,by=szImg[1])
  171.  
  172. g['s',rVb,attr='weight']<-2
  173.  
  174. #join the other vertices to the terminal vertex
  175. rOther<-setdiff(1:numEl,c(ri,rVb))
  176. g[rOther,'t',attr='weight']<-costS1[rOther]
  177.  
  178.  
  179. cut<-stMincuts(g,'s','t')
Add Comment
Please, Sign In to add comment