Beispiel #1
0
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
}
Beispiel #2
0
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
}
Beispiel #3
0
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()
	}

}
Beispiel #4
0
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
}
Beispiel #5
0
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
}
Beispiel #6
0
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
}