コード例 #1
0
ファイル: image.go プロジェクト: jvlmdr/go-cv
func loadFeatureImage(file string, sbin int) (*rimg64.Multi, error) {
	f, err := loadRealImage(file)
	if err != nil {
		return nil, err
	}
	g := hog.HOG(f, hog.FGMRConfig(sbin))
	return g, nil
}
コード例 #2
0
ファイル: main.go プロジェクト: jvlmdr/go-cv
func evalImage(tmpl *detect.FeatTmpl, im image.Image, pyrStep float64, hogBin int, opts featpyr.DetectOpts) []detect.Det {
	// Construct image pyramid.
	scales := imgpyr.Scales(im.Bounds().Size(), tmpl.Size, pyrStep)
	pixpyr := imgpyr.New(im, scales)
	// Construct HOG pyramid.
	fn := func(rgb *rimg64.Multi) *rimg64.Multi { return hog.HOG(rgb, hog.FGMRConfig(hogBin)) }
	pyr := featpyr.New(pixpyr, fn, hogBin)
	// Search feature pyramid.
	dets := featpyr.Detect(pyr, tmpl, opts)
	return dets
}
コード例 #3
0
ファイル: main.go プロジェクト: jvlmdr/go-cv
func loadFeatImage(fname string, sbin int) (*rimg64.Multi, error) {
	file, err := os.Open(fname)
	if err != nil {
		return nil, err
	}
	defer file.Close()

	im, _, err := image.Decode(file)
	if err != nil {
		return nil, err
	}
	return hog.HOG(rimg64.FromColor(im), hog.FGMRConfig(sbin)), nil
}
コード例 #4
0
ファイル: test.go プロジェクト: jvlmdr/go-cv
// Runs a single detector across a single image and returns results.
func detectImage(tmpl *detect.FeatTmpl, im image.Image, margin int, step float64, sbin int, localmax bool, maxiou float64) []detect.Det {
	// Construct pyramid.
	// Get range of scales.
	scales := imgpyr.Scales(im.Bounds().Size(), tmpl.Size, step)
	// Define feature transform.
	phi := hog.Transform{hog.FGMRConfig(sbin)}
	// Define amount and type of padding.
	pad := feat.Pad{feat.Margin{margin, margin, margin, margin}, imsamp.Continue}
	pyr := featpyr.NewPad(imgpyr.New(im, scales), phi, pad)

	// Search feature pyramid.
	// Options for running detector on each level.
	detopts := detect.DetFilter{LocalMax: localmax, MinScore: math.Inf(-1)}
	// Use intersection-over-union criteria for non-max suppression.
	overlap := func(a, b image.Rectangle) bool {
		return detect.IOU(a, b) > maxiou
	}
	// Options for non-max suppression.
	suppropts := detect.SupprFilter{MaxNum: 0, Overlap: overlap}
	dets := detect.Pyramid(pyr, tmpl, detopts, suppropts)
	return dets
}
コード例 #5
0
ファイル: main.go プロジェクト: jvlmdr/go-cv
func main() {
	var (
		sbin     = flag.Int("hog-sbin", 4, "Spatial bin parameter to HOG")
		pyrStep  = flag.Float64("pyr-step", 1.2, "Geometric scale steps in image pyramid")
		maxIOU   = flag.Float64("max-iou", 0, "Maximum intersection over union that two detections can have")
		margin   = flag.Int("margin", 0, "Spatial bin parameter to HOG")
		localMax = flag.Bool("local-max", true, "Suppress detections which are less than a neighbor?")
		minInter = flag.Float64("min-inter", 0.5, "Minimum intersection-over-union to validate a true positive")
	)

	flag.Usage = func() {
		fmt.Fprintln(os.Stderr, "Usage:")
		fmt.Fprintln(os.Stderr, path.Base(os.Args[0]), "[flags] tmpl.gob inria/ roc.txt")
		fmt.Fprintln(os.Stderr)
		fmt.Fprintln(os.Stderr, "Tests a detector.")
		fmt.Fprintln(os.Stderr)
		fmt.Fprintln(os.Stderr, "inria/Test/")
		fmt.Fprintln(os.Stderr, "\tannotations/")
		fmt.Fprintln(os.Stderr, "\tannotations.lst")
		fmt.Fprintln(os.Stderr, "\tpos/")
		fmt.Fprintln(os.Stderr, "\tpos.lst")
		fmt.Fprintln(os.Stderr, "\tneg/")
		fmt.Fprintln(os.Stderr, "\tneg.lst")
		fmt.Fprintln(os.Stderr)
		fmt.Fprintln(os.Stderr, "Options:")
		flag.PrintDefaults()
		fmt.Fprintln(os.Stderr)
	}
	flag.Parse()
	grideng.ExecIfSlave()

	if flag.NArg() != 3 {
		flag.Usage()
		os.Exit(1)
	}
	var (
		tmplFile = flag.Arg(0)
		inriaDir = flag.Arg(1)
		rocFile  = flag.Arg(2)
	)

	detOpts := DetectOpts{
		HOGBin:   *sbin,
		PyrStep:  *pyrStep,
		MaxIOU:   *maxIOU,
		Margin:   *margin,
		LocalMax: *localMax,
	}

	// Load list of positive test image annotations.
	posAnnots, err := loadAnnots(path.Join(inriaDir, "Test", "annotations.lst"), inriaDir)
	if err != nil {
		log.Fatal(err)
	}
	// Load list of negative test images.
	negIms, err := loadLines(path.Join(inriaDir, "Test", "neg.lst"))
	if err != nil {
		log.Fatal(err)
	}

	// Load template.
	var tmpl *detect.FeatTmpl
	if err := loadGob(tmplFile, &tmpl); err != nil {
		log.Fatal(err)
	}
	log.Println("template size (pixels):", tmpl.Size)
	log.Println("template interior (pixels):", tmpl.Interior)
	log.Println("template size (features):", tmpl.Image.Size())
	if want, got := tmpl.Image.Size(), hog.FeatSize(tmpl.Size, hog.FGMRConfig(*sbin)); !got.Eq(want) {
		log.Fatalln("feature transform of patch is different size to weights")
	}

	// Test detector.
	annots := append(posAnnots, imsToAnnots(negIms)...)
	results, err := test(tmpl, annots, inriaDir, detOpts, *minInter)
	if err != nil {
		log.Fatal(err)
	}

	// Save results.
	enum := results.Enum()
	if err := saveResults(rocFile, enum); err != nil {
		log.Fatal(err)
	}
	fmt.Println("avgprec:", ml.ResultSet(enum).AveragePrecision())
}
コード例 #6
0
ファイル: main.go プロジェクト: jvlmdr/go-cv
func main() {
	var (
		sbin     = flag.Int("sbin", 4, "Spatial binning parameter to HOG")
		margin   = flag.Int("margin", 0, "Margin to add around images before computing features")
		step     = flag.Float64("pyr-step", 1.1, "Geometric step to use in image pyramid")
		maxinter = flag.Float64("max-intersect", 0.5, "Maximum overlap of detections. Zero means detections can't overlap at all, one means they can overlap entirely.")
		localmax = flag.Bool("local-max", true, "Detections cannot score less than a neighbor")
	)

	flag.Usage = usage
	flag.Parse()

	if flag.NArg() != 3 {
		flag.Usage()
		os.Exit(1)
	}
	var (
		tmplFile = flag.Arg(0)
		imFile   = flag.Arg(1)
		detsFile = flag.Arg(2)
	)

	// Load image.
	im, err := loadImage(imFile)
	if err != nil {
		log.Fatal(err)
	}
	// Construct pyramid.
	scales := imgpyr.Scales(im.Bounds().Size(), image.Pt(24, 24), *step)
	phi := hog.Transform{hog.FGMRConfig(*sbin)}
	pad := feat.Pad{feat.Margin{*margin, *margin, *margin, *margin}, imsamp.Continue}
	pyr := featpyr.NewPad(imgpyr.New(im, scales), phi, pad)

	// Load template.
	var tmpl *detect.FeatTmpl
	if err := loadGob(tmplFile, &tmpl); err != nil {
		log.Fatal(err)
	}

	detopts := detect.DetFilter{
		LocalMax: *localmax,
		MinScore: math.Inf(-1),
	}
	// Use intersection-over-union criteria for non-max suppression.
	overlap := func(a, b image.Rectangle) bool {
		return detect.IOU(a, b) > *maxinter
	}
	suppropts := detect.SupprFilter{
		MaxNum:  0,
		Overlap: overlap,
	}
	dets := detect.Pyramid(pyr, tmpl, detopts, suppropts)

	if err := saveJSON(detsFile, dets); err != nil {
		log.Fatal(err)
	}

	for i, det := range dets {
		r := det.Rect
		cmd := fmt.Sprintf("rectangle %d,%d %d,%d", r.Min.X, r.Min.Y, r.Max.X, r.Max.Y)
		fmt.Printf("convert %s -fill none -stroke white -draw '%s' det_%06d.jpg\n", imFile, cmd, i)
	}
}