示例#1
0
func (detector *FaceDetector) DetectEyes(image *opencv.IplImage, roi pixelArea) (leftEyes, rightEyes pixelCoords) {

	var topFaceLeft, topFaceRight opencv.Rect

	topFaceLeft.Init(roi.X(), roi.Y()+int(float64(roi.Height())*0.20), roi.Width()/2, int(float64(roi.Height())/2))

	topFaceRight.Init(roi.X()+roi.Width()/2, roi.Y()+int(float64(roi.Height())*0.20), roi.Width()/2, int(float64(roi.Height())/2))

	image.SetROI(topFaceLeft)
	for _, eye := range detector.eyeCascade.DetectObjects(image) {
		leftEyes = append(leftEyes, pixelCoord{
			x:      eye.X() + topFaceLeft.X(),
			y:      eye.Y() + topFaceLeft.Y(),
			width:  eye.Width(),
			height: eye.Height(),
		})
	}

	fmt.Println(len(leftEyes), " left eyes found")

	image.SetROI(topFaceRight)
	for _, eye := range detector.righteyeCascade.DetectObjects(image) {
		rightEyes = append(rightEyes, pixelCoord{
			x:      eye.X() + topFaceRight.X(),
			y:      eye.Y() + topFaceRight.Y(),
			width:  eye.Width(),
			height: eye.Height(),
		})
	}
	fmt.Println(len(rightEyes), " right eyes found")

	image.ResetROI()
	return
}
func main() {
	runtime.GOMAXPROCS(runtime.NumCPU())

	_, currentfile, _, _ := runtime.Caller(0)
	cascade := path.Join(path.Dir(currentfile), "haarcascade_frontalface_alt.xml")
	window := opencv.NewWindowDriver()
	camera := opencv.NewCameraDriver("tcp://192.168.1.1:5555")
	ardroneAdaptor := ardrone.NewAdaptor()
	drone := ardrone.NewDriver(ardroneAdaptor)

	work := func() {
		detect := false
		drone.TakeOff()
		var image *cv.IplImage
		camera.On(opencv.Frame, func(data interface{}) {
			image = data.(*cv.IplImage)
			if !detect {
				window.ShowImage(image)
			}
		})
		drone.On(ardrone.Flying, func(data interface{}) {
			gobot.After(1*time.Second, func() { drone.Up(0.2) })
			gobot.After(2*time.Second, func() { drone.Hover() })
			gobot.After(5*time.Second, func() {
				detect = true
				gobot.Every(300*time.Millisecond, func() {
					drone.Hover()
					i := image
					faces := opencv.DetectFaces(cascade, i)
					biggest := 0
					var face *cv.Rect
					for _, f := range faces {
						if f.Width() > biggest {
							biggest = f.Width()
							face = f
						}
					}
					if face != nil {
						opencv.DrawRectangles(i, []*cv.Rect{face}, 0, 255, 0, 5)
						centerX := float64(image.Width()) * 0.5
						turn := -(float64(face.X()) - centerX) / centerX
						fmt.Println("turning:", turn)
						if turn < 0 {
							drone.Clockwise(math.Abs(turn * 0.4))
						} else {
							drone.CounterClockwise(math.Abs(turn * 0.4))
						}
					}
					window.ShowImage(i)
				})
				gobot.After(20*time.Second, func() { drone.Land() })
			})
		})
	}

	robot := gobot.NewRobot("face",
		[]gobot.Connection{ardroneAdaptor},
		[]gobot.Device{window, camera, drone},
		work,
	)

	robot.Start()
}
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
}