예제 #1
0
func (im *ImageMap) Neighbors(node astar.Node, edges []astar.Edge) ([]astar.Edge, error) {
	x := int(node) % im.Width
	y := int(node) / im.Width
	off := y*im.YStride + x*im.XStride
	c := im.Pix[off]

	if x > 0 {
		edges = append(edges, astar.Edge{Node: node - 1, Cost: 1 + colorCost(c, im.Pix[off-im.XStride])})
		if y > 0 {
			edges = append(edges, astar.Edge{Node: node - 1 - astar.Node(im.Width), Cost: math.Sqrt2 + colorCost(c, im.Pix[off-im.XStride-im.YStride])})
		}
		if y < im.Height-1 {
			edges = append(edges, astar.Edge{Node: node - 1 + astar.Node(im.Width), Cost: math.Sqrt2 + colorCost(c, im.Pix[off-im.XStride+im.YStride])})
		}
	}
	if x < im.Width-1 {
		edges = append(edges, astar.Edge{Node: node + 1, Cost: 1 + colorCost(c, im.Pix[off+im.XStride])})
		if y > 0 {
			edges = append(edges, astar.Edge{Node: node + 1 - astar.Node(im.Width), Cost: math.Sqrt2 + colorCost(c, im.Pix[off+im.XStride-im.YStride])})
		}
		if y < im.Height-1 {
			edges = append(edges, astar.Edge{Node: node + 1 + astar.Node(im.Width), Cost: math.Sqrt2 + colorCost(c, im.Pix[off+im.XStride+im.YStride])})
		}
	}
	if y > 0 {
		edges = append(edges, astar.Edge{Node: node - astar.Node(im.Width), Cost: 1 + colorCost(c, im.Pix[off-im.YStride])})
	}
	if y < im.Height-1 {
		edges = append(edges, astar.Edge{Node: node + astar.Node(im.Width), Cost: 1 + colorCost(c, im.Pix[off+im.YStride])})
	}
	return edges, nil
}
예제 #2
0
func main() {
	if len(os.Args) < 2 {
		log.Fatal("syntax: imagepath [path]")
	}
	rd, err := os.Open(os.Args[1])
	if err != nil {
		log.Fatal(err)
	}
	defer rd.Close()
	img, _, err := image.Decode(rd)
	if err != nil {
		log.Fatal(err)
	}

	log.Println("Processing image")
	im, err := NewImageMap(img)
	if err != nil {
		log.Fatal(err)
	}

	if len(os.Args) > 2 {
		wr, err := os.Create("cpu.prof")
		if err != nil {
			log.Fatal(err)
		}
		defer wr.Close()
		if err := pprof.StartCPUProfile(wr); err != nil {
			log.Fatal(err)
		}
	}

	log.Println("Finding path")
	var memStats runtime.MemStats
	runtime.ReadMemStats(&memStats)
	totalAlloc := memStats.TotalAlloc
	t := time.Now()
	path, err := astar.FindPath(im, 0, astar.Node(img.Bounds().Dx()-1+img.Bounds().Dx()*(img.Bounds().Dy()-1)))
	pprof.StopCPUProfile()
	if err != nil {
		log.Fatal(err)
	}
	log.Printf("\t%d ms", time.Since(t).Nanoseconds()/1e6)
	runtime.ReadMemStats(&memStats)
	log.Printf("\t%d MB allocated", (memStats.TotalAlloc-totalAlloc)/(1024*1024))

	log.Printf("Nodes in path: %d", len(path))

	log.Println("Rendering path")
	for _, node := range path {
		x := int(node) % img.Bounds().Dx()
		y := int(node) / img.Bounds().Dx()
		im.Set(x, y, color.RGBA{0, 255, 0, 255})
	}

	log.Println("Encoding/writing output image")
	wr, err := os.Create("out.jpg")
	if err != nil {
		log.Fatal(err)
	}
	if err := jpeg.Encode(wr, img, nil); err != nil {
		log.Fatal(err)
	}
	wr.Close()
}