Beispiel #1
0
func (t OverlapTest) Overlap(a, b image.Rectangle) bool {
	if detect.Cover(a, b) >= t.MaxCover {
		return true
	}
	if detect.IOU(a, b) >= t.MaxIOU {
		return true
	}
	if detect.Cover(a, b) >= t.MaxCoverBoth && detect.Cover(b, a) >= t.MaxCoverBoth {
		return true
	}
	return false
}
Beispiel #2
0
// 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
}
Beispiel #3
0
func main() {
	var (
		// Dataset options.
		name = flag.String("dataset", "usatest", "Dataset identifier.")
		dir  = flag.String("dir", "", "Location of dataset. Empty means working dir.")
		// Detection options.
		pyrStep  = flag.Float64("pyr-step", 1.2, "Geometric scale steps in image pyramid.")
		maxScale = flag.Float64("max-scale", 1, "Maximum amount to scale image. Greater than 1 is upsampling.")
		maxIOU   = flag.Float64("max-iou", 0.3, "Maximum IOU that two detections can have before NMS.")
		margin   = flag.Int("margin", 0, "Spatial bin parameter to HOG.")
		// Validation options.
		minValIOU      = flag.Float64("min-val-iou", 0.5, "Minimum IOU for a detection to be validated.")
		minIgnoreCover = flag.Float64("min-ignore-cover", 0, "Minimum that a detection must be covered by an ignore region to be ignored.")
		// Display options.
		numShow = flag.Int("num-show", 4, "Number of detections to show per image")
	)
	flag.Parse()
	if flag.NArg() != 2 {
		flag.Usage()
		os.Exit(1)
	}
	var (
		tmplFile      = flag.Arg(0)
		transformFile = flag.Arg(1)
	)

	// Get dataset from name.
	dataset, err := datasetByName(*name)
	if err != nil {
		log.Fatalln(err)
	}
	// Load template from file.
	var tmpl *detect.FeatTmpl
	if err := fileutil.LoadExt(tmplFile, &tmpl); err != nil {
		log.Fatalln("load template:", err)
	}
	// Load transform from file.
	var transform *feat.Marshaler
	if err := fileutil.LoadJSON(transformFile, &transform); err != nil {
		log.Fatalln("load transform:", err)
	}

	overlap := func(a, b image.Rectangle) bool { return detect.IOU(a, b) > *maxIOU }
	opts := detect.MultiScaleOpts{
		MaxScale:    *maxScale,
		PyrStep:     *pyrStep,
		Interp:      resize.Bicubic,
		Transform:   transform,
		Pad:         feat.Pad{feat.UniformMargin(*margin), imsamp.Continue},
		DetFilter:   detect.DetFilter{LocalMax: true, MinScore: math.Inf(-1)},
		SupprFilter: detect.SupprFilter{MaxNum: 0, Overlap: overlap},
	}

	var val *detect.ValSet
	err = fileutil.Cache(&val, "val-set.json", func() (*detect.ValSet, error) {
		return testAll(dataset, *dir, tmpl, opts, *minValIOU, *minIgnoreCover, *numShow)
	})
	if err != nil {
		log.Fatal(err)
	}
}
Beispiel #4
0
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)
	}
}