From: Greg Burri Date: Tue, 22 Dec 2015 00:38:04 +0000 (+0100) Subject: Cleaning. X-Git-Tag: 1.0.11~74 X-Git-Url: http://git.euphorik.ch/index.cgi?a=commitdiff_plain;h=6d99ab0dadc57e91cd846844b620fc90b52a2f96;p=master-thesis.git Cleaning. --- diff --git a/Parasitemia/Parasitemia/Classifier.fs b/Parasitemia/Parasitemia/Classifier.fs index 4c6cc56..a12e595 100644 --- a/Parasitemia/Parasitemia/Classifier.fs +++ b/Parasitemia/Parasitemia/Classifier.fs @@ -29,10 +29,10 @@ let findCells (ellipses: Ellipse list) (parasites: ParasitesMarker2.Result) (img let infection = parasites.infection.Copy() // To avoid to modify the parameter. // This is the minimum window size to check if other ellipses touch 'e'. - let searchRegion (e: Ellipse) = { KdTree.minX = e.Cx - (e.A + config.RBCMax) * config.Parameters.scale - KdTree.maxX = e.Cx + (e.A + config.RBCMax) * config.Parameters.scale - KdTree.minY = e.Cy - (e.A + config.RBCMax) * config.Parameters.scale - KdTree.maxY = e.Cy + (e.A + config.RBCMax) * config.Parameters.scale } + let searchRegion (e: Ellipse) = { KdTree.minX = e.Cx - (e.A + config.RBCMaxRadius) * config.Parameters.scale + KdTree.maxX = e.Cx + (e.A + config.RBCMaxRadius) * config.Parameters.scale + KdTree.minY = e.Cy - (e.A + config.RBCMaxRadius) * config.Parameters.scale + KdTree.maxY = e.Cy + (e.A + config.RBCMaxRadius) * config.Parameters.scale } // The minimum window to contain a given ellipse. let ellipseWindow (e: Ellipse) = @@ -114,8 +114,12 @@ let findCells (ellipses: Ellipse list) (parasites: ParasitesMarker2.Result) (img let c = PointD(e.Cx, e.Cy) for d1 in lines do let d2 = Utils.lineFromTwoPoints c p - let p' = Utils.pointFromTwoLines d1 d2 - yield sign (c.X - p.X) <> sign (c.X - p'.X) || Utils.squaredDistanceTwoPoints c p' > Utils.squaredDistanceTwoPoints c p // 'false' -> the point is owned by another ellipse. + if d2.Valid + then + let p' = Utils.pointFromTwoLines d1 d2 + yield sign (c.X - p.X) <> sign (c.X - p'.X) || Utils.squaredDistanceTwoPoints c p' > Utils.squaredDistanceTwoPoints c p // 'false' -> the point is owned by another ellipse. + else + yield true } |> Seq.forall id ellipsesWithNeigbors @@ -171,7 +175,7 @@ let findCells (ellipses: Ellipse list) (parasites: ParasitesMarker2.Result) (img sqrt (((float sumCoords_x) / (float nbElement) - e.Cx) ** 2.0 + ((float sumCoords_y) / (float nbElement) - e.Cy) ** 2.0) > e.A * config.maxOffcenter *) then Peculiar - elif infectedPixels.Count > config.Parameters.infectionPixelsRequired + elif infectedPixels.Count > config.Parameters.parasitePixelsRequired then let infectionToRemove = ImgTools.connectedComponents parasites.stain infectedPixels for p in infectionToRemove do diff --git a/Parasitemia/Parasitemia/Config.fs b/Parasitemia/Parasitemia/Config.fs index 55e142c..a1b06e2 100644 --- a/Parasitemia/Parasitemia/Config.fs +++ b/Parasitemia/Parasitemia/Config.fs @@ -26,7 +26,7 @@ type Parameters = { infectionArea: float // Factor of a RBC area. 0.5 means the half of RBC area. infectionLevel: float // [0, 1] - infectionPixelsRequired: int + parasitePixelsRequired: int maxDarkStainRatio: float @@ -36,12 +36,12 @@ type Parameters = { type Config (param: Parameters) = member this.Parameters = param member val Debug = DebugOff with get, set - member val RBCSize = 30. with get, set + member val RBCRadius = 30. with get, set - member this.RBCMin = this.RBCSize + param.minRbcRadius * this.RBCSize - member this.RBCMax = this.RBCSize + param.maxRbcRadius * this.RBCSize + member this.RBCMinRadius = this.RBCRadius + param.minRbcRadius * this.RBCRadius + member this.RBCMaxRadius = this.RBCRadius + param.maxRbcRadius * this.RBCRadius - member this.RBCMinArea = param.minimumCellArea * Math.PI * this.RBCSize ** 2.0 + member this.RBCMinArea = param.minimumCellArea * Math.PI * this.RBCRadius ** 2.0 - member this.ParasiteArea = param.infectionArea * Math.PI * this.RBCSize ** 2.0 - member this.StainArea = param.stainArea * Math.PI * this.RBCSize ** 2.0 + member this.InfectionArea = param.infectionArea * Math.PI * this.RBCRadius ** 2.0 + member this.StainArea = param.stainArea * Math.PI * this.RBCRadius ** 2.0 diff --git a/Parasitemia/Parasitemia/Ellipse.fs b/Parasitemia/Parasitemia/Ellipse.fs index 33333bf..48c7f54 100644 --- a/Parasitemia/Parasitemia/Ellipse.fs +++ b/Parasitemia/Parasitemia/Ellipse.fs @@ -208,7 +208,7 @@ let find (edges: Matrix) (yDir: Image) (config: Config) : MatchingEllipses = - let r1, r2 = config.Parameters.scale * config.RBCMin, config.Parameters.scale * config.RBCMax // FIXME: scale factor should be applied in Config!? + let r1, r2 = config.Parameters.scale * config.RBCMinRadius, config.Parameters.scale * config.RBCMaxRadius // FIXME: scale factor should be applied in Config!? let windowSize = roundInt (config.Parameters.factorWindowSize * r2) let factorNbPick = config.Parameters.factorNbPick diff --git a/Parasitemia/Parasitemia/MainAnalysis.fs b/Parasitemia/Parasitemia/MainAnalysis.fs index d959624..6f78b7c 100644 --- a/Parasitemia/Parasitemia/MainAnalysis.fs +++ b/Parasitemia/Parasitemia/MainAnalysis.fs @@ -32,22 +32,23 @@ let doAnalysis (img: Image) (name: string) (config: Config) : Cell li logTime "areaOpen" (fun () -> ImgTools.areaOpen filteredGreen 2000) - config.RBCSize <- Granulometry.findRadius filteredGreen (10, 100) 0.5 |> float + config.RBCRadius <- Granulometry.findRadius filteredGreen (10, 100) 0.5 |> float let filteredGreenFloat = filteredGreen.Convert() // Is it neccessary? let kmediansResults = logTime "Finding foreground (k-medians)" (fun () -> KMedians.kmedians filteredGreenFloat 1.0) - let parasites, filteredGreenWhitoutParasites, filteredGreenWhitoutStain = ParasitesMarker2.find filteredGreen filteredGreenFloat kmediansResults config - let filteredGreenWhitoutParasitesFloat = filteredGreenWhitoutParasites.Convert() + let parasites, filteredGreenWhitoutInfection, filteredGreenWhitoutStain = ParasitesMarker2.find filteredGreen filteredGreenFloat kmediansResults config + let filteredGreenWhitoutInfectionFloat = filteredGreenWhitoutInfection.Convert() + let filteredGreenWhitoutStainFloat = filteredGreenWhitoutStain.Convert() use sobelKernel = new ConvolutionKernelF(array2D [[ 1.0f; 0.0f; -1.0f ] [ 2.0f; 0.0f; -2.0f ] [ 1.0f; 0.0f; -1.0f ]], Point(0, 0)) - use xEdges = filteredGreenWhitoutParasitesFloat.Convolution(sobelKernel).Convert() - use yEdges = filteredGreenWhitoutParasitesFloat.Convolution(sobelKernel.Transpose()).Convert() + use xEdges = filteredGreenWhitoutStainFloat.Convolution(sobelKernel).Convert() + use yEdges = filteredGreenWhitoutStainFloat.Convolution(sobelKernel.Transpose()).Convert() let xEdgesData = xEdges.Data let yEdgesData = yEdges.Data @@ -83,7 +84,7 @@ let doAnalysis (img: Image) (name: string) (config: Config) : Cell li let matchingEllipses = Ellipse.find edges xEdges yEdges config matchingEllipses.Ellipses, matchingEllipses.PrunedEllipses ) - let cells = logTime "Classifier" (fun () -> Classifier.findCells ellipses parasites filteredGreenWhitoutParasites config) + let cells = logTime "Classifier" (fun () -> Classifier.findCells ellipses parasites filteredGreenWhitoutStain config) // Output pictures if debug flag is set. match config.Debug with @@ -123,7 +124,7 @@ let doAnalysis (img: Image) (name: string) (config: Config) : Cell li saveImg filteredGreenMaxima (buildFileName " - filtered - maxima.png") saveImg filteredGreen (buildFileName " - filtered.png") - saveImg filteredGreenWhitoutParasites (buildFileName " - filtered closed.png") + saveImg filteredGreenWhitoutStain (buildFileName " - filtered closed.png") (*saveImg parasitesMarker (buildFileName " - parasites (area closing).png") saveImg stainMarker (buildFileName " - stain (area closing).png")*) diff --git a/Parasitemia/Parasitemia/ParasitesMarker2.fs b/Parasitemia/Parasitemia/ParasitesMarker2.fs index 03af2b6..17a032d 100644 --- a/Parasitemia/Parasitemia/ParasitesMarker2.fs +++ b/Parasitemia/Parasitemia/ParasitesMarker2.fs @@ -7,8 +7,8 @@ open Emgu.CV.Structure type Result = { darkStain: Image - stain: Image - infection: Image } + infection: Image + stain: Image } // Create three binary markers : // * 'Dark stain' corresponds to the colored pixel, it's independent of the size of the areas. @@ -32,16 +32,18 @@ let find (filteredGreen: Image) (filteredGreenFloat: Image Gray, Gray(255.)) + let valueThreshold = if (!max).[0] * threshold < 0.1 * (median_bg - median_fg) then 0.1 * (median_bg - median_fg) else (!max).[0] * threshold + + diff._ThresholdBinary(Gray(valueThreshold), Gray(255.)) diff, closed - let parasitesMarker, filteredGreenWithoutParasites = marker (int config.ParasiteArea) config.Parameters.infectionLevel + let infectionMarker, filteredGreenWithoutInfection = marker (int config.InfectionArea) config.Parameters.infectionLevel let stainMarker, filteredGreenWithoutStain = marker (int config.StainArea) config.Parameters.stainLevel { darkStain = darkStain - stain = parasitesMarker - infection = stainMarker }, - filteredGreenWithoutParasites, + infection = infectionMarker + stain = stainMarker }, + filteredGreenWithoutInfection, filteredGreenWithoutStain diff --git a/Parasitemia/Parasitemia/Program.fs b/Parasitemia/Parasitemia/Program.fs index 103596a..ac495b5 100644 --- a/Parasitemia/Parasitemia/Program.fs +++ b/Parasitemia/Parasitemia/Program.fs @@ -71,12 +71,12 @@ let main args = darkStainLevel = 0.4 // Lower -> more sensitive. - stainArea = 0.02 - stainLevel = 0.2 - - infectionArea = 0.06 + infectionArea = 0.015 infectionLevel = 0.2 - infectionPixelsRequired = 1 + parasitePixelsRequired = 1 + + stainArea = 0.06 + stainLevel = 0.2 maxDarkStainRatio = 0.1 diff --git a/Parasitemia/Parasitemia/Types.fs b/Parasitemia/Parasitemia/Types.fs index 634a7b7..e27f7d0 100644 --- a/Parasitemia/Parasitemia/Types.fs +++ b/Parasitemia/Parasitemia/Types.fs @@ -52,6 +52,7 @@ type Cell = { type Line (a: float, b: float) = member this.A = a member this.B = b + member this.Valid = not (Double.IsInfinity this.A) [] type PointD (x: float, y: float) =