func detectFace(input *image.Image, multiple bool) (*bytes.Buffer, error) { daniel := opencv.LoadImage("static/daniel.jpg").ToImage() hdaniel := int(daniel.Bounds().Dy()) wdaniel := int(daniel.Bounds().Dx()) _image := opencv.FromImage(*input) cascade := opencv.LoadHaarClassifierCascade("haarcascade_frontalface_alt.xml") faces := cascade.DetectObjects(_image) found := false bounds := (*input).Bounds() output := image.NewRGBA(bounds) draw.Draw(output, bounds, *input, image.ZP, draw.Src) for _, value := range faces { x := int(value.X()) y := int(value.Y()) w := int(value.Width()) h := int(value.Height()) y2 := y + h h = hdaniel * w / wdaniel y = y2 - h danielTmp := resize.Resize(uint(w), uint(h), daniel, resize.Lanczos3) if multiple || !found { draw.Draw(output, image.Rect(x, y, x+w, y+h), danielTmp, image.ZP, draw.Src) } found = true } if !found { return nil, errors.New("No faces found") } toOut := new(bytes.Buffer) err := jpeg.Encode(toOut, output, nil) if err != nil { return nil, err } return toOut, nil }
func faceDetect(settings CropSettings, i image.Image, o image.Image) error { cvImage := opencv.FromImage(i) _, err := os.Stat(settings.FaceDetectionHaarCascadeFilepath) if err != nil { return err } cascade := opencv.LoadHaarClassifierCascade(settings.FaceDetectionHaarCascadeFilepath) faces := cascade.DetectObjects(cvImage) gc := draw2dimg.NewGraphicContext((o).(*image.RGBA)) if settings.DebugMode == true { log.Println("Faces detected:", len(faces)) } for _, face := range faces { if settings.DebugMode == true { log.Printf("Face: x: %d y: %d w: %d h: %d\n", face.X(), face.Y(), face.Width(), face.Height()) } draw2dkit.Ellipse( gc, float64(face.X()+(face.Width()/2)), float64(face.Y()+(face.Height()/2)), float64(face.Width()/2), float64(face.Height())/2) gc.SetFillColor(color.RGBA{255, 0, 0, 255}) gc.Fill() } return nil }
func faceDetect(i *image.Image, o *image.Image) { cvImage := opencv.FromImage(*i) _, err := os.Stat(faceDetectionHaarCascade) if err != nil { fmt.Println(err) os.Exit(1) } cascade := opencv.LoadHaarClassifierCascade(faceDetectionHaarCascade) faces := cascade.DetectObjects(cvImage) gc := draw2dimg.NewGraphicContext((*o).(*image.RGBA)) if debug == true { fmt.Println("Faces detected:", len(faces)) } for _, face := range faces { if debug == true { fmt.Printf("Face: x: %d y: %d w: %d h: %d\n", face.X(), face.Y(), face.Width(), face.Height()) } draw2dkit.Ellipse( gc, float64(face.X()+(face.Width()/2)), float64(face.Y()+(face.Height()/2)), float64(face.Width()/2), float64(face.Height())/2) gc.SetFillColor(color.RGBA{255, 0, 0, 255}) gc.Fill() } }
func faceDetect(settings CropSettings, i image.Image, o image.Image, scale float64) ([]Face, error) { cvImage := opencv.FromImage(i) _, err := os.Stat(settings.FaceDetectionHaarCascadeFilepath) if err != nil { return []Face{}, err } cascade := opencv.LoadHaarClassifierCascade(settings.FaceDetectionHaarCascadeFilepath) faces := cascade.DetectObjects(cvImage) gc := draw2dimg.NewGraphicContext((o).(*image.RGBA)) if settings.DebugMode == true { log.Println("Faces detected:", len(faces)) } if len(faces) == 0 { return []Face{}, ErrNoFacesFound } resultFaces := []Face{} for _, face := range faces { if settings.DebugMode == true { log.Printf("Face: x: %d y: %d w: %d h: %d\n", face.X(), face.Y(), face.Width(), face.Height()) } draw2dkit.Ellipse( gc, float64(face.X()+(face.Width()/2)), float64(face.Y()+(face.Height()/2)), float64(face.Width()/2), float64(face.Height())/2) gc.SetFillColor(color.RGBA{255, 0, 0, 255}) gc.Fill() x := int(float64(face.X()) * scale) y := int(float64(face.Y()) * scale) width := int(float64(face.Width()) * scale) height := int(float64(face.Height()) * scale) resultFaces = append(resultFaces, Face{X: x, Y: y, Width: width, Height: height}) } return resultFaces, nil }
func detect(cascade *opencv.HaarCascade, r io.Reader) ([]*Face, error) { img, format, err := image.Decode(r) if err != nil { return []*Face{}, err } log.Printf("Image format: %s", format) rects := cascade.DetectObjects(opencv.FromImage(img)) faces := []*Face{} for _, value := range rects { face := &Face{ PointX: value.X(), PointY: value.Y(), Width: value.Width(), Height: value.Height(), } faces = append(faces, face) } return faces, nil }
func detectFaces(img image.Image) (center image.Rectangle) { cx, cy := (img.Bounds().Max.X-img.Bounds().Min.X)/2, (img.Bounds().Max.Y-img.Bounds().Min.Y)/2 center = image.Rect(cx, cy, cx, cy) srcImg := opencv.FromImage(img) if srcImg == nil { return } defer srcImg.Release() mutex.Lock() defer mutex.Unlock() first := true for _, value := range cascade.DetectObjects(srcImg) { if value != nil { if first { first = false center = image.Rect(value.X(), value.Y(), value.X()+value.Width(), value.Y()+value.Height()) } else { if value.X() < center.Min.X { center.Min.X = value.X() } if value.X()+value.Width() > center.Max.X { center.Max.X = value.X() + value.Width() } if value.Y() < center.Min.Y { center.Min.Y = value.Y() } if value.Y()+value.Height() > center.Max.Y { center.Max.Y = value.Y() + value.Height() } } } } return }
func (s smartcropResizer) smartResize(input image.Image, dstWidth, dstHeight int) (image.Image, error) { if dstWidth < 0 || dstHeight < 0 { return nil, fmt.Errorf("Please specify both width and height for your target image") } scaledInput, scale, err := normalizeInput(input, 1024) if err != nil { return input, err } cvImage := opencv.FromImage(scaledInput) _, err = os.Stat(s.haarcascade) if err != nil { return input, err } cascade := opencv.LoadHaarClassifierCascade(s.haarcascade) faces := cascade.DetectObjects(cvImage) if len(faces) == 0 { return nil, ErrNoFacesFound } var biggestFace *opencv.Rect for _, f := range faces { if biggestFace == nil { biggestFace = f continue } biggestArea := biggestFace.Width() * biggestFace.Height() currentArea := f.Width() * f.Height() if biggestArea < currentArea { biggestFace = f } } log.Printf("Faces found %d\n", len(faces)) if biggestFace == nil { return nil, ErrNoFacesFound } faceArea := biggestFace.Width() * biggestFace.Height() imagePixels := scaledInput.Bounds().Dx() * scaledInput.Bounds().Dy() faceAreaPercentage := float64(faceArea) / float64(imagePixels) if faceAreaPercentage < faceImageTreshold { return nil, fmt.Errorf("face area too small: %.2f.\n", faceAreaPercentage) } if sub, ok := input.(subImager); ok { x := int(float64(biggestFace.X()) * scale) y := int(float64(biggestFace.Y()) * scale) width := int(float64(biggestFace.Width()) * scale) height := int(float64(biggestFace.Height()) * scale) facePoint := image.Pt(x, y) target := image.Rect(0, 0, int(float64(dstWidth)*scale), int(float64(dstHeight)*scale)) r := image.Rect(0, 0, x+width, y+height).Add(facePoint) for !target.In(r) && r.Min.X > 0 && r.Min.Y > 0 { r = image.Rect(r.Min.X-1, r.Min.Y-1, r.Max.X+1, r.Max.Y+1) } cropImage := sub.SubImage(r) return imaging.Thumbnail(cropImage, dstWidth, dstHeight, imaging.Lanczos), nil } return input, err }