func (self *HaarClassifierCascade) DetectObjects(image *IplImage, storage *MemStorage, scale float64, minNeighbors, flags int, minSize, maxSize Size) []*Rect { c_storage := (*C.CvMemStorage)(storage) c_self := (*C.CvHaarClassifierCascade)(self) c_seq := C.cvHaarDetectObjects( unsafe.Pointer(image), c_self, c_storage, C.double(scale), C.int(minNeighbors), C.int(flags), C.cvSize(C.int(minSize.Width), C.int(minSize.Height)), C.cvSize(C.int(maxSize.Width), C.int(maxSize.Height)), ) seq := (*Seq)(c_seq) var arr []*Rect var r Rect seq.ForEach(reflect.TypeOf(r), func(obj interface{}) { arr = append(arr, obj.(*Rect)) }) return arr }
func dendriteCam(deltaE chan float32, config Configuration) { camera := C.cvCaptureFromCAM(-1) // Shutdown dendrite if no camera detected. if camera == nil { fmt.Printf("WARNING: No camera detected. Shutting down DendriteCam\n") return } C.cvSetCaptureProperty(camera, C.CV_CAP_PROP_FRAME_WIDTH, 160) C.cvSetCaptureProperty(camera, C.CV_CAP_PROP_FRAME_HEIGHT, 120) // Capture original frame. prev := C.cvCloneImage(C.cvQueryFrame(camera)) // Save out the first frame for debuging purposes. file := C.CString("frame.png") C.cvSaveImage(file, unsafe.Pointer(prev), nil) C.free(unsafe.Pointer(file)) flow := C.cvCreateImage(C.cvSize(prev.width, prev.height), C.IPL_DEPTH_32F, 2) prevG := C.cvCreateImage(C.cvSize(prev.width, prev.height), C.IPL_DEPTH_8U, 1) nextG := C.cvCreateImage(C.cvSize(prev.width, prev.height), C.IPL_DEPTH_8U, 1) C.cvConvertImage(unsafe.Pointer(prev), unsafe.Pointer(prevG), 0) for { C.cvGrabFrame(camera) // Capture the new frame and convert it to grayscale. next := C.cvCloneImage(C.cvQueryFrame(camera)) C.cvConvertImage(unsafe.Pointer(prev), unsafe.Pointer(prevG), 0) C.cvConvertImage(unsafe.Pointer(next), unsafe.Pointer(nextG), 0) C.cvCalcOpticalFlowFarneback(unsafe.Pointer(prevG), unsafe.Pointer(nextG), unsafe.Pointer(flow), 0.5, 2, 5, 2, 5, 1.1, 0) deltaE <- float32(calcDeltaEnergy(flow, &config)) C.cvReleaseImage(&prev) prev = next } // Never reached - but here in comments for completeness. //C.cvReleaseImage(&prev) //C.cvReleaseImage(&nextG) //C.cvReleaseImage(&prevG) //C.cvReleaseImage(&flow) //C.cvReleaseCapture(&camera) }
/* Allocates and initializes IplImage header */ func CreateImageHeader(w, h, depth, channels int) *IplImage { hdr := C.cvCreateImageHeader( C.cvSize(C.int(w), C.int(h)), C.int(depth), C.int(channels), ) return (*IplImage)(hdr) }
/* Inializes IplImage header */ func (img *IplImage) InitHeader(w, h, depth, channels, origin, align int) { C.cvInitImageHeader( (*C.IplImage)(img), C.cvSize(C.int(w), C.int(h)), C.int(depth), C.int(channels), C.int(origin), C.int(align), ) }
func detect(tarImg *C.IplImage) *C.CvSeq { cvHCC := (*C.CvHaarClassifierCascade)( C.cvLoad(C.CString("./config/haarcascade_frontalface_default.xml"), (*C.CvMemStorage)(nil), (*C.char)(nil), (**C.char)(nil))) cvMStr := C.cvCreateMemStorage(0) return C.cvHaarDetectObjects( unsafe.Pointer(tarImg), cvHCC, cvMStr, 1.11, 3, 0, C.cvSize(0, 0), C.cvSize(0, 0), ) }
/* initialize video file writer */ func NewVideoWriter(filename string, fourcc int, fps float32, frame_width, frame_height, is_color int) *VideoWriter { size := C.cvSize(C.int(frame_width), C.int(frame_height)) filename_c := C.CString(filename) defer C.free(unsafe.Pointer(filename_c)) rv := C.cvCreateVideoWriter(filename_c, C.int(fourcc), C.double(fps), size, C.int(is_color), ) return (*VideoWriter)(rv) }
func main() { fmt.Println("Hello World!") text := C.CString("Hello World!") defer C.free(unsafe.Pointer(text)) C.cvNamedWindow(text, 1) img := unsafe.Pointer(C.cvCreateImage(C.cvSize(640, 480), C.IPL_DEPTH_8U, 1)) C.cvSet(img, C.cvScalar(0, 0, 0, 0), nil) var font C.CvFont C.cvInitFont(&font, C.CV_FONT_HERSHEY_SIMPLEX|C.CV_FONT_ITALIC, 1.0, 1.0, 0, 1, 8) C.cvPutText(img, text, C.cvPoint(200, 400), &font, C.cvScalar(255, 255, 0, 0)) C.cvShowImage(text, img) C.cvWaitKey(0) }
/* Creates IPL image (header and data) */ func CreateImage(w, h, depth, channels int) *IplImage { size := C.cvSize(C.int(w), C.int(h)) img := C.cvCreateImage(size, C.int(depth), C.int(channels)) return (*IplImage)(img) }
func (this *HaarCascade) DetectObjects(image *IplImage) []*Rect { storage := C.cvCreateMemStorage(0) seq := C.cvHaarDetectObjects(unsafe.Pointer(image), this.cascade, storage, 1.1, 3, C.CV_HAAR_DO_CANNY_PRUNING, C.cvSize(0, 0), C.cvSize(0, 0)) var faces []*Rect for i := 0; i < (int)(seq.total); i++ { rect := (*Rect)((*_Ctype_CvRect)(unsafe.Pointer(C.cvGetSeqElem(seq, C.int(i))))) faces = append(faces, rect) } storage_c := (*C.CvMemStorage)(storage) C.cvReleaseMemStorage(&storage_c) return faces }
func LoadHaarClassifierCascade(haar string) *HaarCascade { haarCascade := new(HaarCascade) haarCascade.cascade = C.cvLoadHaarClassifierCascade(C.CString(haar), C.cvSize(1, 1)) return haarCascade }
func measure(deltaC chan Command, videoFile string, debug bool, config Configuration) { camera, err := getVideoSource(videoFile) if err != nil { // No valid video source. Abort measuring. log.Printf("ERROR: Unable to get video source") log.Print(err) return } defer C.cvReleaseCapture(&camera) // Make sure we release the camera when the operating system crushes us. c := make(chan os.Signal, 1) signal.Notify(c, os.Interrupt) go func() { <-c log.Printf("INFO: The OS shut down the scout.") C.cvReleaseCapture(&camera) return }() scene := initScene() // Build the calibration frame from disk. var calibrationFrame *C.IplImage if _, err := os.Stat("calibrationFrame.jpg"); err == nil { file := C.CString("calibrationFrame.jpg") calibrationFrame = C.cvLoadImage(file, C.CV_LOAD_IMAGE_COLOR) defer C.cvReleaseImage(&calibrationFrame) C.free(unsafe.Pointer(file)) } else { log.Printf("ERROR: Unable to measure, missing calibration frame") log.Print(err) return } // Create a frame to hold the foreground mask results. mask := C.cvCreateImage(C.cvSize(calibrationFrame.width, calibrationFrame.height), C.IPL_DEPTH_8U, 1) defer C.cvReleaseImage(&mask) // Push the initial calibration frame into the MOG2 image subtractor. C.initMOG2(C.int(config.MogHistoryLength), C.double(config.MogThreshold), C.int(config.MogDetectShadows)) C.applyMOG2(unsafe.Pointer(calibrationFrame), unsafe.Pointer(mask)) // Current frame counter. frame := int64(0) measuring := true // Start monitoring from the camera. for measuring && C.cvGrabFrame(camera) != 0 { // See if there are any new commands on the deltaC channel. select { case c := <-deltaC: switch { case c == STOP_MEASURE: log.Printf("INFO: Stopping measure") measuring = false } default: // Procceed with measuring. } // Subtract the calibration frame from the current frame. nextFrame := C.cvRetrieveFrame(camera, 0) C.applyMOG2(unsafe.Pointer(nextFrame), unsafe.Pointer(mask)) // Filter the foreground mask to clean up any noise or holes (morphological-closing). C.cvSmooth(unsafe.Pointer(mask), unsafe.Pointer(mask), C.CV_GAUSSIAN, C.int(config.GaussianSmooth), 0, 0.0, 0.0) C.cvThreshold(unsafe.Pointer(mask), unsafe.Pointer(mask), C.double(config.ForegroundThresh), 255, 0) C.cvDilate(unsafe.Pointer(mask), unsafe.Pointer(mask), nil, C.int(config.DilationIterations)) // Detect contours in filtered foreground mask storage := C.cvCreateMemStorage(0) contours := C.cvCreateSeq(0, C.size_t(unsafe.Sizeof(C.CvSeq{})), C.size_t(unsafe.Sizeof(C.CvPoint{})), storage) offset := C.cvPoint(C.int(0), C.int(0)) num := int(C.cvFindContours(unsafe.Pointer(mask), storage, &contours, C.int(unsafe.Sizeof(C.CvContour{})), C.CV_RETR_LIST, C.CV_CHAIN_APPROX_SIMPLE, offset)) var detectedObjects []Waypoint // Track each of the detected contours. for contours != nil { area := float64(C.cvContourArea(unsafe.Pointer(contours), C.cvSlice(0, 0x3fffffff), 0)) // Only track large objects. if area > config.MinArea { boundingBox := C.cvBoundingRect(unsafe.Pointer(contours), 0) w := int(boundingBox.width / 2) h := int(boundingBox.height / 2) x := int(boundingBox.x) + w y := int(boundingBox.y) + h detectedObjects = append(detectedObjects, Waypoint{x, y, w, h, 0.0}) if debug { // DEBUG -- Render contours and bounding boxes around detected objects. pt1 := C.cvPoint(boundingBox.x, boundingBox.y) pt2 := C.cvPoint(boundingBox.x+boundingBox.width, boundingBox.y+boundingBox.height) C.cvDrawContours(unsafe.Pointer(nextFrame), contours, C.cvScalar(12.0, 212.0, 250.0, 255), C.cvScalar(0, 0, 0, 0), 2, 1, 8, offset) C.cvRectangle(unsafe.Pointer(nextFrame), pt1, pt2, C.cvScalar(16.0, 8.0, 186.0, 255), C.int(5), C.int(8), C.int(0)) } } else { num-- } contours = contours.h_next } scene.update(detectedObjects, debug, config) C.cvClearMemStorage(storage) C.cvReleaseMemStorage(&storage) if debug { var font C.CvFont C.cvInitFont(&font, C.CV_FONT_HERSHEY_SIMPLEX, C.double(0.5), C.double(0.5), C.double(1.0), C.int(2), C.CV_AA) txt := C.CString("Hello friend.") C.cvPutText(unsafe.Pointer(nextFrame), txt, C.cvPoint(2, 2), &font, C.cvScalar(255.0, 255.0, 255.0, 255)) C.free(unsafe.Pointer(txt)) // DEBUG -- render current interaction path for detected objects. for _, i := range scene.Interactions { for _, w := range i.Path { pt1 := C.cvPoint(C.int(w.XPixels), C.int(w.YPixels)) C.cvCircle(unsafe.Pointer(nextFrame), pt1, C.int(10), C.cvScalar(109.0, 46.0, 0.0, 255), C.int(2), C.int(8), C.int(0)) } w := i.lastWaypoint() txt := C.CString(fmt.Sprintf("%01d", i.SceneID)) C.cvPutText(unsafe.Pointer(nextFrame), txt, C.cvPoint(C.int(w.XPixels+10), C.int(w.YPixels+10)), &font, C.cvScalar(255.0, 255.0, 255.0, 255)) C.free(unsafe.Pointer(txt)) } for _, i := range scene.idleInteractions { w := i.lastWaypoint() pt1 := C.cvPoint(C.int(w.XPixels-w.HalfWidthPixels+5), C.int(w.YPixels-w.HalfHeightPixels+5)) pt2 := C.cvPoint(C.int(w.XPixels+w.HalfWidthPixels-5), C.int(w.YPixels+w.HalfHeightPixels-5)) C.cvRectangle(unsafe.Pointer(nextFrame), pt1, pt2, C.cvScalar(16.0, 186.0, 8.0, 255), C.int(5), C.int(8), C.int(0)) txt := C.CString("i:" + fmt.Sprintf("%01d", i.SceneID)) C.cvPutText(unsafe.Pointer(nextFrame), txt, C.cvPoint(C.int(w.XPixels+10), C.int(w.YPixels+10)), &font, C.cvScalar(255.0, 255.0, 255.0, 255)) C.free(unsafe.Pointer(txt)) } file := C.CString("f" + fmt.Sprintf("%03d", frame) + "-detected.png") C.cvSaveImage(file, unsafe.Pointer(nextFrame), nil) C.free(unsafe.Pointer(file)) frame++ } } log.Printf("INFO: Finished measure") scene.close(debug, config) }