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 }
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 }
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 }
// 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 }
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()) }
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) } }