/** * Computes the standard deviations of the intensities of all blocks and * the minimum standard deviation */ func computeStdevs(blocks []image.Image) (float64, []float64) { stdevs := make([]float64, len(blocks), len(blocks)) minStdev := math.Inf(1) ch := make(chan indexValuePair) for i, block := range blocks { go func(i int, block image.Image) { variance, mean := 0.0, 0.0 minX, minY := block.Bounds().Min.X, block.Bounds().Min.Y maxX, maxY := block.Bounds().Max.X, block.Bounds().Max.Y total := float64((maxX - minX) * (maxY - minY)) for i := minX; i < maxX; i++ { for j := minY; j < maxY; j++ { mean += utils.Intensity(block.At(i, j)) } } mean /= total for i := minX; i < maxX; i++ { for j := minY; j < maxY; j++ { variance += math.Pow(utils.Intensity(block.At(i, j))-mean, 2) } } ch <- indexValuePair{i: i, value: math.Sqrt(variance / total)} }(i, block) } for i := 0; i < len(blocks); i++ { pair := <-ch stdevs[pair.i] = pair.value minStdev = utils.MinF(pair.value, minStdev) } close(ch) return minStdev, stdevs }
/** * Last part of the HMSF algorithm, merge regions if the credit of any of them * exceeds the weight of the edge connecting them. */ func (s *Segmenter) hmsfMergeRegionsByCredit(edges graph.EdgeList, regionCredit []float64) { for _, edge := range edges { u := s.resultset.Find(edge.U()) v := s.resultset.Find(edge.V()) if u != v { credit := utils.MinF(regionCredit[u], regionCredit[v]) if credit > edge.Weight() { s.resultset.Union(u, v) survivor := s.resultset.Find(u) regionCredit[survivor] = credit - edge.Weight() } } } }