Created
July 17, 2012 21:53
-
-
Save jamesthompson/3132383 to your computer and use it in GitHub Desktop.
CLEAN algorithm Implemented in Scala
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package CLEAN | |
import scalala.tensor.dense.{DenseMatrix => Image} | |
import collection.mutable.ArrayBuffer | |
/** | |
* Clean class implemented in Scala | |
* Author: James R. Thompson, D.Phil | |
* Date: 7/16/12 | |
* Time: 9:31 AM | |
* USC Mork Family Dept. of Chem. Eng. & Mat. Sci. | |
*/ | |
abstract class PixelType | |
case class EdgePixel(loc:(Int,Int), intensity:Double) extends PixelType | |
case class GotchaPixel(loc:(Int,Int), intensity:Double) extends PixelType | |
case class DimPixel(loc:(Int,Int), intensity:Double) extends PixelType | |
class Clean(img:Image[Short], val patchSize:Int) { | |
implicit def conv2DTo1D(loc:(Int,Int)) : Int = loc._2 * img.numCols + loc._1 | |
implicit def conv1Dto2D(loc:Int) : (Int,Int) = (loc % img.numCols, math.floor(loc / img.numCols).toInt) | |
implicit def normalize(in:Image[Short]) : Array[Double] = { | |
val data = in.data | |
val max = data.max.toDouble | |
val min = data.min.toDouble | |
data.map(s => (s.toDouble - min) * (1 / (max - min))) | |
} | |
lazy val i : Array[Double] = img | |
lazy val mean = i.sum / i.length | |
val foundSpots = ArrayBuffer[(Double,Double)]() | |
def cleanImage(brightest:Double, threshold:Double) = { | |
val loc = i.indexOf(brightest) | |
assignPixelType(loc, brightest, threshold) match { | |
case e:EdgePixel => i.update(loc,mean) | |
case g:GotchaPixel => foundSpots += cleanMe(loc) | |
case d:DimPixel => () | |
} | |
def assignPixelType(loc:(Int,Int), intensity:Double, threshold:Double) = { | |
if(loc._1 <= patchSize || loc._2 <= patchSize || loc._1 >= img.numCols - patchSize || loc._2 >= img.numRows - patchSize) EdgePixel(loc, intensity) | |
else if(intensity < threshold) DimPixel(loc, intensity) | |
else GotchaPixel(loc, intensity) | |
} | |
def cleanMe(loc:(Int,Int)) = { | |
val pixelMap = for(x <- loc._1 - patchSize to loc._1 + patchSize; y <- loc._2 - patchSize to loc._2 + patchSize) yield ((x,y),i.apply((x,y))) | |
pixelMap.map(p => i.update(p._1, mean)) | |
moment(pixelMap) | |
} | |
} | |
def findSpots(threshold:Double) = { | |
while(i.max > threshold) cleanImage(i.max, threshold) | |
(i, foundSpots.toArray) | |
} | |
def moment(in:IndexedSeq[((Int,Int), Double)]) = { | |
val d = in.map(_._2).sum | |
val x = in.map(v => v._1._1 * v._2).sum / d | |
val y = in.map(v => v._1._2 * v._2).sum / d | |
(x,y) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Clean algorithm adapted for Scala. Detects spots in a pixelated image, assuming the spots are imaged as approximate Gaussians. Fits the location using a moment finding method and outputs the locations and cleaned image. Adapted for single molecule TIRF microscopy image analysis here.